技术架构
RUC 百事通采用典型的「工具化智能体(Agentic Tool-use)」架构。前端负责轻量级交互, 核心逻辑由服务端的 Planner-Executor 模式驱动。
1. 总体架构分层
Layered Architecture
展现层 (Presentation)
Flask + Jinja Web UI。负责处理 HTTP/SSE 请求,提供同步表单与流式打字机效果。
智能体编排层 (Orchestration)
系统核心大脑。基于 DeepSeek 的 Planner 负责意图识别与多轮工具规划。
工具层 (Tools)
标准化能力封装。包含树洞检索、公告抓取、教务搜索等 Python 函数接口。
数据与存储层 (Data & Storage)
底层基础设施。包含 MySQL 业务库、向量索引库以及外部 API 网关。
系统数据流向图
2. 请求生命周期 (Lifecycle)
前端发起的每一次提问,都会在后端经历初始化、循环规划、工具执行、答案生成四个阶段。
执行流程
-
初始化 (Init)
后端接收问题
q,初始化空轨迹steps,设定最大步数max_steps=5。 -
规划循环 (Plan Loop)
调用 LLM 判断下一步意图。若返回工具调用指令,则执行;若返回
final,则跳出循环。 -
工具执行 (Execute)
根据指令分发给
search_*等函数,获取并精简结果,追加到steps。 -
回答生成 (Respond)
将所有
steps和证据打包,送入 LLM 生成最终的自然语言回答。
核心循环逻辑
PYTHON (Simplified)
# Main Loop for i in range(max_steps): # 1. 规划下一步 plan = _plan_next_action(user_q, steps, i) if plan.get("final"): break # 思考结束,准备回答 # 2. 执行工具 tool = plan["action"]["tool"] args = plan["action"]["args"] result = dispatch_tool(tool, args) # 3. 记录轨迹 (精简结果以节省 Token) steps.append({ "tool": tool, "args": args, "result": slim_result(result) }) # 4. 最终生成 return answer_with_deepseek(user_q, steps)
3. 智能体组件详情
规划器 (Planner)
_plan_next_action 利用 DeepSeek 的 JSON Mode 输出标准化的行动指令。
- 参数控制:对
limit,size等参数做强制约束,防止单次拉取过多数据。 - 白名单机制:只允许调用
allowed_tools中注册的函数。 - 历史压缩:传入 LLM 的历史步骤经过摘要处理,只保留核心信息。
回答器 (Responder)
answer_with_deepseek 是最后一道工序,负责将零散的证据整合成流畅的文本。
- 严格 RAG:Prompt 强调“只基于提供的 sources 回答”,禁止模型幻觉。
- 结构化引用:自动解析模型生成的
[[n]]标记,在前端渲染为可点击的角标。
4. 工具层说明
所有工具均遵循 func(args) -> dict 的签名规范。
工具集 Registry
系统启动时,会通过 register_tool 装饰器加载以下工具到全局注册表:
search_treehole
fetch_treehole_comments
search_academy_news
search_ruc_cms
metaso_kb_search
search_course_reviews
web_search
weather_forecast
remote_posts_search
remote_person_search
remote_activities_upcoming
5. 稳定性与扩展性
稳定性设计
- 熔断保护:关键工具(如树洞)失败时,会立即终止规划并抛出友好提示,而不是让 Agent 继续瞎猜。
- 超时控制:所有外部 API 调用均设有严格的 Timeout,防止单个工具卡死整个请求。
- 异步落库:数据采集端使用队列 + 批量写入,避免高并发下数据库死锁。
扩展性设计
- 插拔式工具:新增数据源只需编写一个 Python 函数并在
allowed_tools注册即可,无需修改 Agent 核心逻辑。 - 模型无关:Planner 与 Responder 模块已解耦,未来可轻松替换为 GPT-4 或 Qwen-Max。
- 重排器替换:Rerank 模块独立封装,可替换为 BGE 或 Cohere 等其他模型。