前言
今天老顾给大家介绍另一个关键角色执行者Tools ,此角色主要的作用是对规划者Planner出来的内容进行执行,执行的方式包含搜索、代码执行,如果配置了MCP Server也会包含里面包含的工具。
执行者的触发
触发执行者有2个场景,第一个场景是规划者经过人工中断,前端选择Start Research按钮,或者配置了【自动接收规划者内容的配置】开关开启

代码都在人工中断节点中,如下

Agent流程图
我们再来看看整体的LangGraph的流程图

这个源码就是我们前一篇文章中介绍的交互流程。我们看一下执行者research_team在哪个位置
arduino
builder.add_node("research_team", research_team_node)
这个节点的原作者取的名字research,可以优化为executor,哈哈;但不重要
那么我们看看执行者具体的逻辑代码
执行者Agent
来看看源码
python
def research_team_node(state: State):
"""Research team node that collaborates on tasks."""
logger.info("Research team is collaborating on tasks is running........")
pass
这个函数啥事都没有做,执行完了后,后续怎么处理呢?
arduino
builder.add_conditional_edges(
"research_team",
continue_to_running_research_team,
["planner", "researcher", "coder"],
)
上面是条件边的定义,指明了后续会走到哪个节点,我们再来聚焦一下,看看continue_to_running_research_team这个方法。

我们来分析一下代码
kotlin
if not current_plan or not current_plan.steps:
return "planner"
这段代码表示 还没有规划内容,应该交给规划者Planner。
vbnet
if all(step.execution_res for step in current_plan.steps):
return "planner"
step.execution_res这个属性有值,代表已经执行处理过了。
那上面的代码for循环表示是不是所有的步骤都执行过了 ,如果执行过了就直接返回到planner规划者Agent。
arduino
for step in current_plan.steps:
if not step.execution_res:
break
遍历当前的规则的步骤,哪些步骤是没有执行的,就返回那个没有执行的步骤。
arduino
if step.step_type and step.step_type == StepType.RESEARCH:
return "researcher"
if step.step_type and step.step_type == StepType.PROCESSING:
return "coder"
return "planner"
上面的代码是根据步骤类型的step_type的值,执行不同的工具节点。我们具体看看步骤的结构体

上图的step_type类型的值,就是规划者Planner与大模型进行交互时,大模型给出的执行类型。具体可以看前面介绍规划者Agent的文章。
执行Research
我们看看research节点代码

上面的代码的核心逻辑是增加搜索tools工具
retriever_tool这个变量大家可以忽略,这个是为了检索本地知识库的,不妨碍我们分析源码
_setup_and_execute_agent_step 方法就是创建agent,此agent包含了工具tools,以及researcher这个参数值。
执行Coder

执行Coder比Research更简单,也是调用了 _setup_and_execute_agent_step 方法就是创建agent,此agent包含了python_repl_tool这个工具,以及coder这个参数值。
下面我们来具体看看创建Agent的方法_setup_and_execute_agent_step
创建Agent
我们先看看 _setup_and_execute_agent_step源码


里面有个核心的支持MCP的代码逻辑
yaml
if configurable.mcp_settings:
如果配置了mcp,就需要读取mcp server的配置信息,设置mcp_servers和enabled_tools这2个变量。
csharp
if mcp_servers:
async with MultiServerMCPClient(mcp_servers) as client:
如果有mcp servers,就通过client.get_tools()获得mcp的tools,加入到我们定义的工具,再加入到create_agent函数中。

create_agent方法里面定义了 大模型的,以及提示词的获取。大模型和提示词的获取 之前文章已经介绍过了。
我们下面来介绍Research提示词和Coder提示词
Research提示词
提示词是存放再researcher.md,里面内容还挺多,老顾这边只介绍比较核心的内容
1、身份定位

2、工具说明

3、执行步骤

里面有个if resources动态判断,就是要不要增加本地检索知识库的tool工具。
4、输出格式

里面有个locale变量,指明需要什么语言输出。
5、注意事项

Coder提示词
1、身份定位

2、执行步骤

3、注意事项

总结
至此就介绍了执行者这个角色的核心逻辑,到此5大角色就全部介绍完了 。结合之前的介绍DeerFlow的核心流程就全部介绍完了。此外项目还有生成播客的功能,代码比较简单,老顾就不介绍了。
研究了DeerFlow这个开源项目后,对老顾的关于AI Agent的相关技术的使用,有很大的帮助和启发。
DeerFlow再Python的工程结构上面也有很多学习的地方,下一篇我们来介绍一下DeerFlow工程方式的知识。