当前位置: 首页 > news >正文

开源Agent平台Dify源码剖析系列(五)核心模块core/agent之CotChatAgentRunner

每一篇文章都短小精悍,不啰嗦。

笔者寄语

本期介绍Dify框架的核心模块core/agent。接下来我们一起深入剖析core/agent目录下的所有代码,并以通俗易懂的方式解释。我们需要先了解这个目录的完整结构,然后逐个分析关键文件,最后总结整个Agent框架的设计和工作原理。

首先,让我查看core/agent目录的完整结构:

dify/api/core/agent.├── base_agent_runner.py    # Agent框架的基础实现├── cot_agent_runner.py    # Chain of Thought (CoT) Agent Runner的实现├── cot_chat_agent_runner.py    # CoT Chat Agent Runner的实现├── cot_completion_agent_runner.py    # CoT Completion Agent Runner的实现├── entities.py    # 定义了Agent框架中的核心实体和数据结构├── fc_agent_runner.py    # CoT Completion Agent Runner的实现├── __init__.py├── output_parser│   └── cot_output_parser.py  # Chain of Thought输出解析器的实现└── prompt    └── template.py  # Agent提示模板的实现

图片

CotChatAgentRunner 类继承自 CotAgentRunner,是专门为聊天场景优化的思维链代理运行器。其核心职责是构建符合思维链范式的提示模板,将系统指令、用户问题、历史对话和工具信息整合为大语言模型可理解的格式。下面我们从「功能定位→核心方法→构建流程→技术细节」四个层面进行剖析。

一、功能定位:聊天场景下的「提示工程师」

CotChatAgentRunner 的核心作用是将复杂的对话上下文转化为引导模型思考的提示信息。它解决了两个关键问题:

  1. 结构化提示构建

    将系统指令、工具列表、历史对话等信息组织成特定格式(如 ReACT 范式),引导模型按思维链方式思考。

  2. 多模态支持

    处理用户上传的文件(如图像),将其转化为模型可理解的格式(如文本描述)。

例如,当用户发送包含图片的问题(如「分析这张销售图表的趋势」)时,CotChatAgentRunner 会:

  • 将图片转换为文本描述(如「一张柱状图,展示了 2024 年 1-6 月各地区销售额」);

  • 结合系统指令(如「你是数据分析师,请使用工具分析图表数据」);

  • 历史对话(如用户之前的问题);

  • 可用工具(如「数据可视化工具」「趋势预测工具」);

  • 构建完整的提示模板,发送给模型。

二、核心方法:三大提示构建器

类中定义了三个核心方法,分别负责构建系统提示、用户查询和完整提示链:

1. _organize_system_prompt():构建系统指令
def _organize_system_prompt(self)-> SystemPromptMessage:
assert self.app_config.agent and self.app_config.agent.promptfirst_prompt = self.app_config.agent.prompt.first_prompt# 填充模板变量system_prompt =(first_prompt.replace("{{instruction}}", self._instruction)
.replace("{{tools}}", json.dumps(jsonable_encoder(self._prompt_messages_tools)))
.replace("{{tool_names}}",", ".join([tool.name for tool in self._prompt_messages_tools]))
)return SystemPromptMessage(content=system_prompt)

关键操作

  • 从配置中获取初始提示模板(如 first_prompt);

  • 动态填充三个关键变量:

    • {{instruction}}

      :用户指令(如「分析销量趋势」);

    • {{tools}}

      :可用工具列表的 JSON 字符串(包含工具名称、描述、参数);

    • {{tool_names}}

      :工具名称的逗号分隔列表(如 sales_dataset, chart_generator)。

示例输出(简化版):

你是一位专业的数据分析师。可用工具包括:
[
{"name": "sales_dataset", "description": "查询销售数据集", ...},
{"name": "chart_generator", "description": "生成图表", ...}
]
请根据用户需求,合理使用工具解决问题。

2. _organize_user_query():处理用户输入(含多模态)
def _organize_user_query(self, query, prompt_messages):
if self.files:# 如果用户上传了文件(如图像)contents =[TextPromptMessageContent(data=query)]# 文本部分# 获取图像细节配置(如高/中/低描述)image_detail_config = self.application_generate_entity.file_upload_config.image_config.detailimage_detail_config = image_detail_config or ImagePromptMessageContent.DETAIL.LOW# 将每个文件转换为模型可理解的格式
forfilein self.files:contents.append(file_manager.to_prompt_message_content(
file, image_detail_config=image_detail_config
)
)prompt_messages.append(UserPromptMessage(content=contents))
else:# 纯文本输入prompt_messages.append(UserPromptMessage(content=query))return prompt_messages

关键操作

  • 处理多模态输入:将用户上传的文件(如图片)转换为 ImagePromptMessageContent 对象,包含图像描述;

  • 图像细节配置:通过 image_detail_config 控制描述的详细程度(如「低」仅包含基本信息,「高」包含像素级细节)。

示例场景
用户发送问题「分析这张图表」并上传图片 → 方法将图片转换为「一张包含 2024 年各季度销量数据的折线图」,与文本问题合并为多模态输入。

3. _organize_prompt_messages():整合所有提示组件
def _organize_prompt_messages(self)->list[PromptMessage]:
# 1. 构建系统提示system_message = self._organize_system_prompt()# 2. 构建当前助手回复(基于历史思考步骤)
if self._agent_scratchpad:assistant_message = AssistantPromptMessage(content="")
for unit in self._agent_scratchpad:
if unit.is_final():assistant_message.content +=f"Final Answer: {unit.agent_response}"
else:assistant_message.content +=f"Thought: {unit.thought}\n\n"
if unit.action_str:assistant_message.content +=f"Action: {unit.action_str}\n\n"
if unit.observation:assistant_message.content +=f"Observation: {unit.observation}\n\n"assistant_messages =[assistant_message]
else:assistant_messages =[]# 3. 构建用户查询query_messages = self._organize_user_query(self._query,[])# 4. 整合历史消息和当前消息
if assistant_messages:historic_messages = self._organize_historic_prompt_messages(
[system_message,*query_messages,*assistant_messages, UserPromptMessage(content="continue")]
)messages =[system_message,*historic_messages,*query_messages,*assistant_messages, UserPromptMessage(content="continue")]
else:historic_messages = self._organize_historic_prompt_messages([system_message,*query_messages])messages =[system_message,*historic_messages,*query_messages]return messages

关键操作

  • 思维链格式化

    :将历史思考步骤(_agent_scratchpad)转换为 ReACT 格式的文本(如 Thought: ... Action: ... Observation: ...);

  • 历史对话整合

    :通过 _organize_historic_prompt_messages 方法,将历史消息转换为模型可理解的格式,并添加 continue 标记,引导模型继续思考;

  • 多轮对话支持

    :在多轮迭代中,动态更新 assistant_messages,保留完整的思考链条。

三、构建流程:从用户输入到模型提示

以用户提问「分析近 3 个月销量趋势」为例,看 CotChatAgentRunner 如何构建提示:

  1. 系统提示(简化版):

    你是一位专业的数据分析师。可用工具包括:["sales_dataset", "chart_generator"]。

    请按以下格式回答:
    Thought: 我需要...
    Action: {"name": "工具名", "parameters": {"param1": "value"}}
    Observation: 工具返回的结果
    ...(重复思考-行动-观察)
    Final Answer: 最终答案
    

  2. 用户查询

    User: 分析近3个月销量趋势

  3. 第一轮思考(假设模型输出):

    Assistant: 

    Thought: 我需要先获取近3个月的销量数据,使用sales_dataset工具。
    Action: {"name": "sales_dataset", "parameters": {"time_range": "近3个月"}}
    

  4. 工具调用与观察

    • 系统调用 sales_dataset 工具,获取数据;

    • 将结果作为 Observation 添加到思考链:

      Observation: 近3个月销量数据:1月1000,2月1200,3月1300,呈上升趋势。

  5. 第二轮思考(模型基于观察继续思考):

    Thought: 已获取数据,销量呈上升趋势。需要生成图表可视化,使用chart_generator工具。

    Action: {"name": "chart_generator", "parameters": {"data": [...]}}
    

  6. 最终答案

    Final Answer: 近3个月销量呈上升趋势(1月1000→2月1200→3月1300)。已为您生成趋势图(见附件)。

四、技术细节与设计亮点

  1. 多模态兼容性

    • 通过 file_manager.to_prompt_message_content 方法,将不同类型的文件(如图像、文档)转换为模型可理解的格式,支持跨模态推理。

  2. 类型安全

    • 使用 assert isinstance(assistant_message.content, str) 确保类型安全,避免在字符串拼接时出现类型错误;

    • 通过 jsonable_encoder 处理复杂对象的 JSON 序列化,确保工具列表正确转换为字符串。

  3. 迭代优化

    • 在多轮迭代中,通过 UserPromptMessage(content="continue") 引导模型继续思考,而不是重新开始;

    • 动态更新工具列表(如最后一轮迭代时移除所有工具,强制模型输出最终答案)。

  4. 模板灵活性

    • 使用字符串替换(replace)而非硬编码,允许通过配置文件自定义提示模板,适应不同场景需求。

五、总结:思维链代理的「提示设计哲学」

CotChatAgentRunner 的核心价值在于通过精心设计的提示模板,将大语言模型转化为遵循特定思维范式的智能代理。它的设计哲学包括:

  1. 结构化引导

    通过 ReACT 等范式,将自由文本生成转化为结构化的「思考→行动→观察」循环;

  2. 透明化推理

    将模型的内部推理过程显式化(如 ThoughtAction),增强可解释性;

  3. 工具增强

    通过外部工具扩展模型能力,解决其「知识边界」和「计算限制」问题;

  4. 多模态整合

    打破纯文本交互的限制,支持图像、文件等多种输入形式。

这种设计让 AI 代理不仅能回答问题,还能展示思考过程、调用外部资源、处理复杂任务,真正实现从「问答系统」到「决策助手」的跨越。

http://www.lryc.cn/news/591584.html

相关文章:

  • 文字转图片的字符画生成工具
  • 今日行情明日机会——20250717
  • Web3.0 实战项目、简历打造、精准投递+面试准备
  • springboot 整合spring-kafka客户端:SASL_SSL+PLAINTEXT方式
  • 流式数据处理实战:用状态机 + scan 优雅过滤 AI 响应中的 `<think>` 标签
  • 面试高频题 力扣 200.岛屿数量 洪水灌溉 深度优先遍历 暴力搜索 C++解题思路 每日一题
  • 【Lua】题目小练1
  • 50天50个小项目 (Vue3 + Tailwindcss V4) ✨ | GoodCheapFast(Good - Cheap - Fast三选二开关)
  • yolo8+ASR+NLP+TTS(视觉语音助手)
  • RK3566开发板调试记录:从编译配置到功能优化
  • 杰理AC70NN项目用脚本自定义添加.mk文件,直接链接进主Makefile脚本编译
  • 微服务的编程测评系统3-加密-日志-apifox-nacos-全局异常
  • 用Python实现神经网络(一)
  • RuoYi-Cloud 定制微服务
  • 微服务网站开发学习路线与RuoYi-Cloud实战指南
  • 迅速高效从web2到web3转型 ,开启远程工作
  • 验证损失判断过拟合情况
  • VTK体绘制中的抗锯齿技巧总结
  • LAMP迁移LNMP Nginx多站点配置全流程
  • AUTOSAR进阶图解==>AUTOSAR_SWS_BusMirroring
  • 线性回归策略
  • 水安考试:水利水电安全员 B 证考取指南及报考要求
  • OpenFeign的简单实践
  • C++11新特性(上)——右值引用,移动语义,引用折叠,完美转发,初始化列表,可变参数模版,lambda,包装器
  • 为何“白名单媒体”是性价比之选?
  • 从虚拟大脑到世界行者:具身智能与机器人控制基础
  • 抽奖错觉:游戏设计中的心理学武器
  • Clip微调系列:《MaPLe: Multi-modal Prompt Learning》
  • 基于在线地图的路径规划测评对比-综合对比城区、农村及城乡结合处的导航
  • ESP8266服务器建立TCP连接失败AT+CIPSTART=“TCP“,“192.168.124.1“,8080 ERROR CLOSED