Files
smartmate/backend/agent/通用能力接入文档.md
Losita 468367d617 Version: 0.8.3.dev.260328
后端:
1.彻底删除原agent文件夹,并将现agent2文件夹全量重命名为agent(包括全部涉及到的文件以及文档、注释),迁移工作完美结束
2.修复了重试消息的相关逻辑问题

前端:
1.改善了一些交互体验,修复了一些bug,现在只剩少的功能了,现存的bug基本都修复完毕

全仓库:
1.更新了决策记录和README文档
2026-03-28 18:00:31 +08:00

5.8 KiB

agent 通用能力接入文档

1. 文档目的

本文用于说明 backend/agent 目录下“通用能力”的职责边界、放置位置和接入约束,避免后续继续出现“同一类能力复制三份、四份”的情况。

这里的“通用能力”特指:

  1. 会被两个及以上能力域复用,或者已经明确会继续扩散的基础能力。
  2. 与具体业务语义弱耦合,抽出来后不会把某个 skill 的 prompt、状态字段、业务规则污染到其它模块。
  3. 抽出后能显著减少样板代码、降低迁移成本,或者统一链路行为。

本文不负责描述某个具体 skill 的业务流程。业务流程、状态机、prompt 细节,仍应放在对应能力域自己的文件中。

2. 当前目录分层

backend/agent/
  entrance.go
  chat/
  graph/
  llm/
  model/
  node/
  prompt/
  router/
  shared/
  stream/

2.1 entrance.go

职责:

  1. 作为 agent 模块对上层 service 的统一入口。
  2. 负责装配路由器与各能力 handler。
  3. 不负责具体 graph 逻辑、不负责直接调模型、不负责工具执行。

2.2 router/

职责:

  1. 负责一级分流,把请求映射到具体能力链路。
  2. 维护统一的请求/响应结构和 action 定义。
  3. 不承载具体 skill 的业务判断细节。

适合放入这里的能力:

  1. 路由请求结构。
  2. action 解析与分发。
  3. 对上层稳定暴露的最小门面。

2.3 graph/

职责:

  1. 只负责组图、连线和节点编排。
  2. 文件里应尽量只出现节点挂载、分支和边定义。
  3. 不直接写复杂业务逻辑、不直接调 DAO、不直接拼 prompt。

2.4 node/

职责:

  1. 承接能力域的核心业务节点实现。
  2. 按“节点逻辑文件 + 工具文件”的双文件格局组织复杂能力域。
  3. 在确实存在多节点复用时,可下沉少量带业务语义的 node 内部公共 helper。

当前约定:

  1. schedule_plan.go / schedule_plan_tool.go 为一组。
  2. schedule_refine.go / schedule_refine_tool.go 为一组。
  3. quicknote.go / quicknote_tool.gotaskquery.go / taskquery_tool.go 同理。

补充说明:

  1. node/tool_common.go 是 node 层内部通用工具聚合点。
  2. 这里只放“被两个及以上节点复用、但仍带一点节点上下文语义”的 helper。
  3. 如果某个能力已经弱化到与业务无关,应继续下沉到 shared/,而不是长期堆在 tool_common.go

2.5 llm/

职责:

  1. 统一封装模型调用、JSON 解析、推理参数和模型侧协议。
  2. 让上层节点尽量只关心“要什么结果”,不重复实现 SDK 样板代码。
  3. 不承载具体业务状态流转。

2.6 model/

职责:

  1. 统一放置 agent 内部状态结构、输入输出 DTO、默认预算等模型无关定义。
  2. 不在这里写业务执行逻辑。

2.7 prompt/

职责:

  1. 维护系统提示词、结构化输出模板、路由提示词等文本资产。
  2. 不在 prompt 文件中写节点控制流和工具编排。

2.8 stream/

职责:

  1. 统一承接 SSE chunk 包装、阶段推送、OpenAI/Ark 流式适配。
  2. 保证上层 service 不需要重复拼装流协议。

2.9 shared/

职责:

  1. 放置跨能力域复用的纯工具能力,例如时间、重试、深拷贝等。
  2. 要求业务语义尽量弱、依赖尽量少。
  3. 一旦某类逻辑已经被第二处复用,必须优先评估是否放到这里。

3. 什么该抽成通用能力

满足以下任一条件时,必须优先评估抽公共层:

  1. 同类逻辑已经出现第二份实现。
  2. 不同 skill 的实现只有参数不同,控制流基本一致。
  3. 上层 service 已经开始出现重复胶水代码。
  4. 继续复制会增加迁移、测试或回归排查成本。

常见应优先考虑抽取的方向:

  1. 模型调用门面。
  2. JSON 容错解析。
  3. SSE 阶段推送与 chunk 包装。
  4. 深拷贝与快照转换。
  5. 缓存快照读写辅助逻辑。

4. 什么不该抽成通用能力

以下内容默认不应抽到公共层:

  1. 某个 skill 独有的 prompt 片段。
  2. 只服务单一业务的状态字段映射。
  3. 带强业务语义的 ReAct 决策规则。
  4. 只在一个节点里短期使用、且没有第二处复用证据的 helper。

判断原则:

  1. 若抽出来后名字仍然需要带明显业务词,通常说明它还不够通用。
  2. 若抽出来会让其它模块被迫理解某个 skill 的内部规则,说明抽取层级过早。

5. 新增能力时的落点规则

  1. 纯工具、弱业务语义、跨域复用:优先放 shared/
  2. 只在路由阶段复用:放 router/
  3. 只与模型协议相关:放 llm/
  4. 只与流式输出相关:放 stream/
  5. 只在 node 层内被多个节点复用,且带少量业务上下文:放 node/tool_common.go 或同层 helper。
  6. 仍然明显属于某个能力域:留在对应 node/prompt/model/ 文件中,不要硬抽。

6. 变更要求

后续若在 backend/agent 中新增、下沉、替换任何通用能力,必须同步完成以下动作:

  1. 更新本文档,说明新能力放在哪一层、为什么放这里。
  2. 说明是否替代了旧实现,旧实现是否已经删除。
  3. 检查是否还残留第三份及以上重复实现。
  4. 若本轮只是暂时无法抽公共层,必须在代码注释或文档里写明原因。

7. 当前结构结论

截至当前版本,backend/agent 已是唯一正式实现目录,backend/service/agentsvc 也已与历史旧路径完全解耦。

后续重构优先级建议:

  1. 继续收口 node 层内部重复的查询/校验/移动辅助逻辑。
  2. 持续把 service 层里可复用的旁路读写逻辑下沉到更稳定的公共层。
  3. 保持 graph 只做编排、node 只做业务、shared 只做弱语义公共能力,避免重新堆回大杂烩结构。