在人工智能的浪潮之巅,多智能体协作系统 (Multi-Agent Systems) 正以其解决复杂问题的卓越潜力,吸引着全球研究者的目光。它们如同一个高度协同的数字工匠团队,每个成员各司其职,共同完成宏伟的目标。然而,如何高效、灵活地定义和管理这些“数字工匠”的行为模式,一直是该领域的核心挑战。来自 LeapLabTHU 的 Cooragent 项目,为我们展示了一种精巧的解决方案——基于模板的智能体设计。今天,就让我们一同深入 Cooragent 的内核,揭开其 Agent 模板设计与运作的神秘面纱,探索这些“蓝图”如何赋予 AI 智能体生命与智慧。
📜 引言:AI智能体编排的艺术
想象一下,我们要构建一个能够自动化完成复杂软件项目或深度研究任务的 AI 系统。这需要不同类型的 AI 智能体——有的擅长编码,有的精于研究,有的则负责任务规划与协调。Cooragent 的设计者们巧妙地意识到,为每一种智能体从零开始定制行为逻辑既耗时又不灵活。他们引入了“模板”这一核心概念,如同为不同工种的工匠预先绘制好的行为蓝图。这些模板不仅定义了智能体的基本属性和能力,更重要的是,它们规范了智能体的思考方式和行动指南,使得整个多智能体系统能够像一部精密编排的交响乐般和谐运作。
🧩 基石:智能体模板的精巧构造 (.md
的魔力)
Cooragent 中智能体模板的物理载体,是一系列位于 src/prompts/
目录下的 Markdown (.md
) 文件 [coder.md:1-40, researcher.md:1-42]。这种选择本身就体现了设计的匠心:Markdown 格式易于人类阅读和编辑,同时也能被程序高效解析。每个 .md
文件都代表着一种特定类型智能体的“基因序列”。
打开其中一个模板,例如 coder.md
(一个为软件工程智能体设计的模板),我们会发现其结构清晰,通常包含以下几个核心部分 [coder.md:1-40]:
- 时间戳 (CURRENT_TIME: `<<CURRENT_TIME>>`): 这是一个动态变量,会在运行时被替换为当前时间,为智能体提供时间上下文,这对于需要时效性信息的任务至关重要。
- 角色定义 (Role Definition): 开宗明义地声明智能体的身份和专业领域。例如,
coder.md
中定义其为“一个专业的软件工程智能体,精通 Python 和 bash 脚本编写” [coder.md:4-5]。 - 任务描述 (Task Description): 这是一个非常有趣的设计。模板并不总是直接给出具体任务,有时它会指导智能体如何 自行寻找 任务描述。例如,在
coder.md
和researcher.md
中,智能体被告知需要在用户输入的["steps"]
列表中,根据自己的agent_name
(如 “coder” 或 “researcher”) 找到对应的["description"]
和["note"]
[coder.md:8-15, researcher.md:8-12]。这种“元指令”赋予了智能体一定程度的自主性和对复杂指令结构的理解能力。 - 执行步骤 (Steps): 这是模板的核心,详细列出了智能体完成任务时应遵循的思考和行动流程。例如,
coder.md
的步骤包括:寻找任务描述、需求分析、方案规划、方案实现(区分 Python 和 bash 的使用场景)、测试验证、方法文档化和结果呈现 [coder.md:17-32]。而researcher.md
则强调理解问题、规划方案、执行方案(使用tavily_tool
搜索和crawl_tool
爬取内容)、综合信息等步骤 [researcher.md:15-29]。 - 注意事项 (Notes): 这部分提供了智能体在执行任务时必须遵守的规则、约束和最佳实践。比如,
coder.md
强调代码效率、错误处理、代码注释、仅用 Python 进行数学计算和文件操作、以及如何安装缺失库(uv add <library name>
)等 [coder.md:34-40]。researcher.md
则提醒要验证信息相关性和可信度,不要进行数学计算或文件操作等 [researcher.md:38-42]。
这些 .md
模板通过 <<VAR>>
的形式定义变量占位符,这些占位符将在运行时被具体情境下的值所替换,从而实现模板的动态适应性 [template.py:12-25]。
⚙️ 引擎:模板的动态生命力 (template.py
的魔法)
静态的 .md
文件是如何转化为驱动 AI 智能体行动的动态指令的呢?这背后的“魔法引擎”便是 src/prompts/template.py
文件。该文件中的函数负责读取、解析和应用这些模板。
关键函数之一是 get_prompt_template(prompt_name: str)
[template.py:12-25]。它的工作流程大致如下:
- 根据
prompt_name
(例如 “coder” 或 “researcher”) 找到对应的.md
模板文件。 - 读取文件内容。
- 使用正则表达式
re.findall(r"<<([^>>]+)>>", template)
提取出所有<<VAR>>
格式的变量名。 - 为了与 Python 的字符串格式化兼容,它会先将模板中的
{
和}
转义为{{
和}}
,然后将<<VAR>>
替换为{VAR}
格式。 - 最终返回处理后的模板字符串和提取出的变量名列表。
另一个核心函数是 apply_prompt_template(prompt_name: str, state: AgentState, template:str=None)
[template.py:28-47]。此函数负责将具体的智能体状态 AgentState
(包含了当前对话历史、用户信息等) 应用到加载好的模板上:
- 它首先获取模板 (如果未直接提供
template
参数,则调用get_prompt_template
)。 - 然后,使用
PromptTemplate
(可能来自 LangChain 或类似库) 将模板中的变量 (如CURRENT_TIME
和state
中包含的其他信息) 替换为实际值,生成最终的系统提示system_prompt
。 - 这个
system_prompt
会与当前的消息历史messages
(同样经过格式化,区分为 “user” 和 “assistant” 角色) 结合,构成发送给大型语言模型 (LLM) 的完整输入。
通过这种机制,每个智能体在执行任务前,都会获得一个根据其角色模板和当前情境量身定制的、充满动态信息的“行动纲领”。
# template.py 中的核心逻辑示意
def get_prompt_template(prompt_name: str) -> tuple[str, list[str]]:
# ... 读取 prompts_dir / f"{prompt_name}.md" ...
template_content = read_file_content()
variables = re.findall(r"<<([^>>]+)>>", template_content)
# 将 <<VAR>> 替换为 {VAR} 以便格式化
formatted_template = re.sub(r"<<([^>>]+)>>", r"{\1}", template_content)
return formatted_template, variables
def apply_prompt_template(prompt_name: str, state: AgentState, template_str:str=None) -> list:
# ... 获取并格式化消息 ...
_template, _ = get_prompt_template(prompt_name) if not template_str else (template_str, [])
# 使用 state 中的值填充模板
system_prompt_content = _template.format(CURRENT_TIME=datetime.now().strftime(...), **state)
return [{"role": "system", "content": system_prompt_content}] + formatted_messages
👤 化身:Agent
类的定义与 AgentManager
的统筹
模板定义了“角色类型”,而具体的“角色实例”则由 src/interface/agent_types.py
文件中定义的 Agent
类来承载 [agent_types.py:30-46]。一个 Agent
对象封装了一个智能体实例的所有关键信息:
user_id
: 用户标识。agent_name
: 智能体的唯一名称。nick_name
: 智能体的昵称。description
: 对智能体能力的描述。llm_type
: 该智能体背后驱动的语言模型类型 (例如,特定的 GPT 版本或其他模型)。selected_tools
: 一个列表,定义了该智能体可以使用的工具集 (如搜索工具、代码执行器等)。prompt
: 该智能体所使用的提示模板内容 (通常是get_prompt_template
返回的模板字符串)。
这些 Agent
实例并非孤立存在,而是由 src/manager/agents.py
中的 AgentManager
类进行统一管理 [agents.py]。AgentManager
负责智能体的创建、保存、加载、编辑和删除等生命周期操作。
值得注意的是,AgentManager
在初始化时,会预定义一系列基础的、共享的智能体 (user_id="share"
),例如:
- researcher: 使用
tavily_tool
(搜索) 和crawl_tool
(网页内容爬取) 的研究型智能体,其prompt
来自get_prompt_template("researcher")
[agents.py:49-55]。 - coder: 使用
python_repl_tool
(Python代码执行) 和bash_tool
(Bash命令执行) 的编码型智能体,其prompt
来自get_prompt_template("coder")
[agents.py:56-62]。 - browser: 使用
browser_tool
进行网页交互的智能体 [agents.py:65-71]。 - reporter: 专注于基于提供信息生成报告的智能体,不使用额外工具 [agents.py:73-79]。
_create_mcp_agent
方法展示了如何将工具定义和模板字符串组装成一个完整的 Agent
对象并保存 [agents.py:99-119]。这套机制确保了智能体定义的一致性和可管理性。
🌐 协作之舞:Agent Factory 与 Agent Workflow 的双重奏
Cooragent 的强大之处不仅在于单个智能体的模板化定义,更在于它支持两种灵活的智能体运作模式,使得这些“数字工匠”能够协同工作,共同应对复杂挑战。
Agent Factory 模式:即时创造的力量
在某些场景下,用户可能需要一个当前系统中不存在的、特定用途的智能体。此时,Agent Factory
模式便派上了用场。src/workflow/agent_factory.py
中的 agent_factory_node
扮演了“智能体创造工厂”的角色 [agent_factory.py:20-53]。
其工作流程大致为:
- 应用名为 “agent_factory” 的特定模板,该模板可能指导 LLM 如何根据用户对新智能体的描述来定义其属性。
- LLM (通过
get_llm_by_type(AGENT_LLM_MAP["agent_factory"]).with_structured_output(Router)
) 的响应会被结构化解析,提取出新智能体的名称、LLM 类型、所需工具、提示内容和描述。 - 调用
agent_manager._create_agent_by_prebuilt
(或类似方法) 来创建并注册这个全新的智能体。 - 新创建的智能体随后便可以加入到团队中,参与后续的任务。
这种模式赋予了 Cooragent 动态扩展其智能体团队的能力,极大地增强了系统的适应性和灵活性。
Agent Workflow 模式:多智能体协作的编排艺术
当任务需要多个不同类型的智能体接力协作时,Agent Workflow
模式便登上了舞台。这一模式的核心逻辑主要体现在 src/workflow/coor_task.py
和 src/workflow/graph.py
中。
coor_task.py
定义了一系列关键的“节点函数 (Node Functions)”,它们共同构成了一个决策和执行流程图:
coordinator_node
(协调员节点) [coor_task.py:143-159]:- 作为与用户交互的第一个接触点。
- 应用 “coordinator” 模板,LLM 会分析用户输入,决定是否需要将任务移交给规划师进行更详细的计划。如果响应中包含 “handover_to_planner”,流程将转向规划师节点。
planner_node
(规划师节点) [coor_task.py:105-140]:- 负责生成详细的任务执行计划。
- 应用 “planner” 模板,LLM 会分析当前状态和用户需求,输出一个包含具体步骤和所需智能体类型的计划 (通常是 JSON 格式)。
- 支持“深度思考模式” (使用不同的 LLM) 和“规划前搜索” (先用
tavily_tool
搜索相关信息辅助规划)。
publisher_node
(发布者/调度器节点) [coor_task.py:56-79]:- 在规划师制定计划后,或一个智能体完成其子任务后,此节点决定下一步应该由哪个智能体接手。
- 应用 “publisher” 模板,LLM (同样使用
with_structured_output(Router)
) 会分析当前状态和计划,决定下一个行动者 (next
)。 - 如果
next
是 “FINISH”,则工作流结束。如果next
是 “agent_factory”,则会调用智能体工厂。否则,通常会导向agent_proxy_node
。
agent_proxy_node
(智能体代理节点) [coor_task.py:82-102]:- 作为执行具体智能体任务的代理。
- 根据
publisher_node
决定的state["next"]
(即要执行的智能体名称),从agent_manager
获取对应的智能体定义。 - 创建一个可执行的 React Agent (一种能够进行思考-行动-观察循环的智能体),配置好其 LLM、工具和从模板生成的提示。
- 调用智能体的
invoke
方法执行任务,并将结果更新到状态中,然后流程通常返回到publisher_node
以决定下一步。
整个工作流程的执行由 src/workflow/graph.py
中的 CompiledWorkflow
类控制 [graph.py:27-50]。它维护了一个节点 (nodes) 和边 (edges) 的图结构,从起始节点 (start_node
) 开始,根据每个节点函数的返回值 (command.goto
),在不同的节点之间传递和更新状态 (state
),直至到达 __end__
节点。
这种基于图的流程控制,结合模板化的智能体定义,使得 Cooragent 能够以高度结构化和可扩展的方式编排复杂的多智能体协作。
🚀 实战演练:从“股票分析专家”看模板的威力
README_zh.md
中提供了一个生动的例子:“创建一个股票分析专家 agent. 今天是 2025年 4 月 22 日,查看过去一个月的小米股票走势,分析当前小米的热点新闻,预测下个交易日的股价走势,并给出买入或卖出的建议。” [README_zh.md:157-159]。
让我们想象一下 Cooragent 如何通过其模板驱动的机制来响应这个请求:
- 协调员 (
coordinator_node
) 接收到用户请求。其模板驱动的 LLM 识别出这是一个复杂任务,决定移交给规划师。 - 规划师 (
planner_node
) 接手。其模板引导 LLM 将任务分解:- 可能需要一个 researcher 智能体来搜索小米过去一个月的股票数据和热点新闻。
- 可能需要一个 coder (或特定分析型) 智能体来处理数据、进行趋势分析,并结合新闻进行预测。
- 最后可能需要一个 reporter 智能体来整合所有信息,给出买卖建议并生成报告。
- 如果系统中没有现成的“股票分析专家”模板,规划师甚至可能指示先调用 agent_factory 创建一个。
- 发布者 (
publisher_node
) 根据计划,首先调度 researcher。 - 代理 (
agent_proxy_node
) 执行 researcher。researcher.md
模板被应用,CURRENT_TIME
被设为 “2025年 4 月 22 日”。它使用搜索工具查找股票数据和新闻。 - 结果返回给 发布者,它再根据计划调度 coder (或分析师)。
- 代理 执行 coder。
coder.md
模板被应用。它接收研究员的结果,利用 Python (可能配合数据分析库) 进行分析和预测。 - 如此往复,直到所有子任务完成,最终由 reporter 智能体(应用
reporter.md
模板)汇总并呈现结果。
在这个过程中,每个智能体的行为都严格遵循其模板的指引,而模板中的变量 (<<CURRENT_TIME>>
, <<任务描述>>
等) 则确保了它们能够适应具体的任务情境。
🔬 超越指令:模板作为高级提示工程的实践
Cooragent 中的 Agent 模板,远不止是简单的指令列表。它们是高级提示工程 (Prompt Engineering) 的精妙体现。模板的结构,特别是“任务描述的自我寻找机制”和详尽的“注意事项”,实际上是在引导 LLM 进行更深层次的思考和更规范的行动。
例如,coder.md
中“你需要自己寻找你的任务描述”这一指令 [coder.md:8-15],迫使 LLM 理解并解析一个结构化的输入,而不是被动等待一个扁平化的任务字符串。这提升了 LLM 处理复杂上下文的能力。同样,“注意事项”部分 [coder.md:34-40, researcher.md:38-42] 如同为 LLM 内置了一套行为准则和质量控制标准,有助于减少错误,提高输出的可靠性和实用性。
这些精心设计的模板,实质上是在与 LLM 进行一种“元对话”,教会它们如何成为一个合格的“研究员”、“编码员”或“规划师”,而不仅仅是完成一次性的文本生成。
🔮 结语:模板驱动的未来——构建复杂AI生态的基石
LeapLabTHU/cooragent 项目通过其创新的 Agent 模板机制,为我们描绘了一幅构建复杂、可扩展、可维护的多智能体系统的清晰蓝图。这些 .md
文件不仅仅是静态的文本,它们是智能体行为的DNA,通过 template.py
的解析和 AgentWorkflow
的编排,被赋予了鲜活的生命力。
从 coder.md
的严谨逻辑到 researcher.md
的探索精神,每一种模板都精心雕琢了对应智能体的“性格”与“技能”。这种将智能体设计模块化、规范化的思想,极大地降低了构建和管理多智能体应用的复杂度。
未来,随着我们对 AI 认知能力的深入探索,这类模板驱动的架构无疑将扮演越来越重要的角色。它们是连接人类意图与机器执行之间的桥梁,是培育繁荣 AI 生态的肥沃土壤。Cooragent 的实践,无疑为我们点亮了前行的一盏明灯,昭示着一个由精心设计的“数字工匠蓝图”所驱动的、更加智能化的未来。
参考文献
- LeapLabTHU/cooragent.
src/prompts/coder.md
. - LeapLabTHU/cooragent.
src/prompts/researcher.md
. - LeapLabTHU/cooragent.
src/prompts/template.py
. - LeapLabTHU/cooragent.
src/interface/agent_types.py
. - LeapLabTHU/cooragent.
src/manager/agents.py
. - LeapLabTHU/cooragent.
src/workflow/agent_factory.py
. - LeapLabTHU/cooragent.
src/workflow/coor_task.py
. - LeapLabTHU/cooragent.
src/workflow/graph.py
. - LeapLabTHU/cooragent.
README_zh.md
.