本文档总结当前项目里 agents/ 下 swarm 包的结构,以及 deepseek_demo 这一组 agent 的组织方式。
当前系统的 agent 相关结构可以分成四层:
core/:运行时与编排内核,负责 agent、tool、skill、graph 的注册、校验和执行。agents/:业务 swarm 包目录,每个子目录代表一个可加载的 swarm。tools/:默认工具实现,供 swarm 直接复用,也可以被单独引用。web/:HTTP 接入层,用 FastAPI 暴露运行时接口。
当前 agents/deepseek_demo/ 是一个完整的 swarm 包,包含:
agents/deepseek_demo/
swarm.toml
graph.py
agents/
planner.py
researcher.py
writer.py
reviewer.py
publisher.py
skills/
planner.prompt.md
planner.prompt.toml
researcher.prompt.md
researcher.prompt.toml
writer.prompt.md
writer.prompt.toml
reviewer.prompt.md
reviewer.prompt.toml
publisher.prompt.md
publisher.prompt.toml
swarm.toml 是这个 swarm 的索引文件,负责声明:
graph_fileagent_filesskill_filestool_files- 默认 LLM 后端配置
它的职责是“索引和约束”,不是执行逻辑。
每个 agent 文件只负责定义一个 AGENT 字典。
例如:
agent_idnameskill_namebackend_name
当前这些文件本质上是agent blueprint,即配置描述,不包含行为逻辑。
Envelope 模式已移除:agent 不再接收 JSON envelope 包装。state.payload 会直接作为 user_message 传入 agent,无论原始输入是字符串还是字典。这意味着 agent prompt 和工具文档里都不应再出现 _envelope 字段或 envelope 相关的解析逻辑。
当前 skill 被拆成两部分:
*.prompt.md:纯提示词文本*.prompt.toml:skill contract,定义输入/输出/依赖/前置条件/后置条件
这样 skill 不再只是 prompt asset,而是一个可描述、可校验的能力单元。
当前 agents/deepseek_demo/ 包含 7 个 agent:
- 负责分析用户研究请求
- 输出 JSON 格式的研究计划(topic/angles/depth/estimated_researchers)
- 作为 swarm 的入口和全局框架设定者
- 负责自适应架构控制
- 在 preflight 阶段判断分支树应该保持宽松还是被收窄
- 在 dispatch 阶段分发并行研究分支
- 在 checkpoint 阶段读取合并后的分支结果,决定是否需要重新规划
- 可选使用
graph_editor和agent_manager工具调整运行时图
- 负责将 orchestrator 的框架转化为紧凑的任务简报
- 定义研究角度(structure/evidence/risk)
- 输出 JSON 格式的控制计划(content/plan/organization_hint)
- 负责补充证据、假设和风险
- 使用
web_search工具收集信息 - 输出结构化研究笔记(Key Findings / Supporting Evidence / Sources / Gaps / Uncertainties)
- 为 writer 和 reviewer 提供支持信息
- 负责把 planner 和 researcher 的结果整理成可发布草稿
- 使用 Markdown 格式,结构为 Executive Summary → Background → Analysis → Conclusion → References
- 更偏“内容生成”
- 负责审查草稿和分支结果
- 输出 JSON 格式的 verdict(approve/revise/re_research)
- 通过
next_node_ids指示执行器下一步跳转到哪个节点 - 不直接输出图编辑指令
- 负责输出最终用户可读结果
- 不暴露内部 routing 或 graph edit 细节
当前 demo 的图是一个“编排 + 自适应分发 + 并行研究 + 汇聚 + 审查 + 发布”的流程。
orchestrator— 分析请求并生成研究框架organizer_preflight— 判断分支树宽度planner— 生成任务简报research_dispatcher(organizer)— 并行分发三条研究分支:architecture_researcher_runtime(结构/拓扑研究)evidence_researcher_runtime(实现证据研究)risk_researcher_runtime(风险/失效模式研究)- 每条分支通过
agent_manager创建临时 agent,通过graph_editor插入节点,执行后销毁
organizer_checkpoint— 汇聚分支结果,决定是否需要重新规划writer— 综合所有研究笔记撰写报告reviewer— 审查并输出 verdict(approve → publisher, revise → writer, re_research → organizer_preflight)publisher— 输出最终用户可读结果file_writer— 将最终输出保存到outputs/deepseek_demo_final.txt
orchestrator是入口节点(entry_node_id = 1)。organizer_preflight和research_dispatcher使用organizeragent,通过additional_prompt区分阶段(preflight / dispatch / checkpoint)。research_dispatcher使用route_policy = "all"和join_node_id = 17实现三条研究分支的并行执行和汇聚。- 每条研究分支包含 4 个 ToolNode:
agent_manager创建临时 researchergraph_editor插入临时节点agent_manager销毁临时 researchergraph_editor移除临时节点
- 临时节点默认标记为
runtime_transient = true - 若需要长期保留,则显式标记为
persistence = "persistent",并将其作为可长期存在的 swarm 结构 reviewer通过返回next_node_ids控制路由:approve → 20, revise → 18, re_research → 2。file_writer是出口节点(exit_node_id = 21)。
当前 demo 依赖的默认工具包括:
echofile_writergraph_editor_toolagent_manager_toolweb_search_tool
这是当前最重要的运行时工具之一。它可以:
- 添加节点
- 删除节点
- 添加边
- 删除边
- 替换某个节点的后继
- 设置入口节点
- 设置出口节点
这意味着文件中定义的图只是初始图,运行时可以继续演化。
新增节点现在有明确生命周期语义:
transient:用完即弃的运行态节点persistent:长期保留的节点,直到被显式编辑删除、禁用或替换
运行时会把生命周期写成结构化 node_lifecycle 元数据,建议包含:
runtime_transientpersistencelifetime_policy
默认情况下,新增节点应当是 transient,只有明确声明时才进入 persistent。
用于在运行时创建和销毁临时 agent。当前 demo 在研究分支中使用它来:
- 创建临时 researcher(
create_agent) - 销毁临时 researcher(
destroy_agent)
用于把结果写入文件。当前 demo 默认写到:
outputs/deepseek_demo_final.txt
用于为 researcher 提供网络搜索能力。
当前 skill contract 文件的目的,是把 skill 从“提示词文件”升级成“可验证能力描述”。
它目前包含:
capabilitydescriptioninput_schemaoutput_schemarequires_toolsrequires_skillspreconditionspostconditionsfailure_policyparallelizable
这样后续可以更容易做:
- 图校验
- 能力依赖分析
- 并行性判断
- 失败恢复策略
现在这套结构的定位是:
agent是执行角色skill是能力契约和提示词资产graph是编排结构tool是运行时能力扩展core是 runtime 解释器
这里有一个很重要的实现约束:agent 对象本身是长生命周期的,不会为每次请求自动重建。
因此,当前运行态可以分成两类:
- 请求级运行态
ExecutionState会在每次graph.run()时新建RunRecord只负责后台 run 的事件和快照,不会回灌到模型
- agent 级运行态
Agent._context现在是ManagedAgentContext,会保留历史消息、压缩块和归档Agent._context.metadata会保留last_round、turnsAgent.cognitive_graph会持续累积工具调用和推理痕迹
ManagedAgentContext 取代了旧的扁平 AgentContext,采用三层结构管理对话历史:
- Active window:最近 6 条完整消息,直接参与 LLM 调用
- Compressed blocks:当 active messages 超过 10 条时,最老的 4 条被压缩成
ContextBlock,保留摘要和关键词 - Archive:压缩后的原始消息仍完整保存,可通过
recall_context工具按需检索
压缩块包含:
block_idround_rangesummarykeywordsparticipantsmessages(原始完整消息,存入 archive)
build_messages() 的组装顺序:
- 所有 compressed blocks 的摘要以轻量
systemhint 形式注入 - Active window 的完整消息按原顺序追加
这意味着 LLM 始终看到最近的完整对话,以及更早对话的摘要,而不是无限制增长的消息列表。
每个 agent 自动绑定 recall_context 工具,允许 LLM 主动搜索 archive 中的历史块:
- 输入:自然语言查询字符串
- 行为:按关键词匹配 compressed blocks,返回最相关的完整归档消息
- 用途:当 LLM 需要引用较早的详细内容时,不必在每次调用中携带全部历史
这改变了传统的“被动截断”模型,改为“主动召回”模型:系统默认只给摘要,LLM 在需要时可以请求完整内容。
为了防止上一轮内容污染下一轮,当前路由层会在 swarm run 开始前调用 core.reset_runtime_state(),把 agent 可变状态清空后再执行图。
重置内容包括:
- 清空每个 agent 的
ManagedAgentContext(active messages、compressed blocks、archive) - 清空每个 agent 的私有 cognitive graph
- 重建 swarm 级共享 cognitive graph
这意味着:
run/start/runs适合做“单次任务执行”- 如果你在调试单个 agent,
/agents/<agent_id>/round仍然可能保留上下文,这是为了保留交互式调试体验 orchestrator和organizer作为架构控制 agent,同样会保留上下文,但 run 边界重置会清空所有 agent 的私有状态- 如果你希望完全无状态,需要在路由层或调用方显式重置,而不是假设 agent 默认短生命周期
如果后续继续扩展这个 swarm,建议优先考虑:
- 增加真正的 router 节点
- 增加并行汇总节点
- 给 skill contract 增加更严格的 schema 校验
- 给 tool 增加分类和权限标记
- 给 graph editor 增加更细粒度的审计日志