首页
/ Langchain-Chatchat Agent 对话接口 agent_chat 深度解析:从参数约定到流式工具调用全流程

Langchain-Chatchat Agent 对话接口 agent_chat 深度解析:从参数约定到流式工具调用全流程

2026-09-08 16:01:44作者:魏侃纯Zoe

本篇技术指南围绕 Langchain-Chatchat 项目中的 Agent(代理)对话功能展开,以 markdown_docs/server/chat/agent_chat.md 描述的 agent_chat 及其内部 agent_chat_iterator 为骨架,讲解 Agent 对话接口的核心参数、流式/非流式两种输出模式、LLM 与工具初始化链路,并结合当前仓库源码说明该能力在新版 OpenAI 兼容统一接口中的落地形态。读完你将掌握 Langchain-Chatchat 中「让模型自主规划并调用工具」的对话是如何被编排与返回的,以及如何正确调用与解析这一接口。

Agent 对话(Agent Chat)是 Langchain-Chatchat 中区别于普通 LLM 问答、知识库问答(kb_chat)的一类核心交互:模型不仅生成文本,还会自主决定调用哪些外部工具(天气、搜索、计算、SQL 查询、本地知识库检索等),并根据工具返回结果继续推理,最终给出带工具的最终回答。agent_chat 正是这一能力的对话层封装函数。

一、agent_chat 函数定位与整体职责

文档将 agent_chat 描述为一个异步函数,用于处理用户与 Agent 的聊天对话。它的核心职责可以拆解为四个阶段:

  1. 历史规范化:把传入的历史对话列表 history 统一转换为 History 对象列表,保证后续构造模型消息时格式一致;
  2. 迭代器定义:在函数内部定义异步迭代器 agent_chat_iterator,真正承载"初始化模型与工具 → 处理历史 → 驱动 Agent 推理 → 产出回复"的完整链路;
  3. 流式/非流式分发:当 stream=True 时以异步 yield 逐块吐出 JSON 数据(适用于聊天框实时刷新场景);否则收集全部输出后一次性组装为一个 JSON 响应体返回;
  4. 状态感知输出:在流式模式下,会根据 Agent 运行的不同阶段(工具调用开始、完成、出错、得到最终答案等)产出不同结构的 JSON 数据块。

从当前仓库的服务端目录看,Agent 对话不再以独立模块存在:server/chat/ 目录下仅保留 chat.pycompletion.pyfeedback.pyfile_chat.pyhuman_message_event.pykb_chat.pyutils.py,Agent 对话能力已被整合进 chat_routes.py 的 OpenAI 兼容统一对话接口(详见下文第六节),因此本文档描述的 agent_chat 更应被理解为一份接口行为规范,其参数语义与输出格式约定至今仍然有效。

二、核心参数说明

agent_chat 对外暴露的参数决定了 Agent 对话的每一次行为,是接入方最需要关心的部分:

参数 类型与必填 含义与默认值
query 字符串,必填 用户输入的查询语句,是驱动 Agent 推理的起点
history 列表 历史对话记录,每个元素为一个 History 对象;传入前需保证元素要么本身就是 History,要么可被转换为 History
stream 布尔,默认 False 是否以流式方式返回数据;True 适合需要实时更新聊天气泡的场景
model_name 字符串 使用的 LLM 模型名称,默认取 LLM_MODELS 配置列表中的第一个模型
temperature 浮点 LLM 采样温度,控制生成随机性,取值范围 0.0~1.0,默认值由运行时 TEMPERATURE 配置决定
max_tokens 整数/None,默认 None 限制生成 Token 数上限;None 表示不设限制、使用模型自身最大值
prompt_name 字符串,默认 "default" 选用的 Prompt 模板名称,agent_chat 依据它加载对应提示模板

值得注意的两点参数语义:

  • temperaturemax_tokens 是"一次请求级"的覆盖开关。它们默认值来自运行时配置(TEMPERATURE、LLM 模型最大上下文),但调用方每次都可以显式传入覆盖值。Agent 在调用工具时需要模型输出结构化的 Action JSON,过高的 temperature 会降低输出格式稳定性,实际调优时通常建议对 Agent 推理保持较低温度。
  • model_name 的默认取首个模型而非 Agent 专属模型。文档同时说明:如果运行时配置了 Agent_MODEL,内部会额外用该模型初始化一个"Agent 大脑",并将其单独挂入模型容器——这为"Agent 规划模型"与"普通问答模型"分离提供了设计空间。

三、内部执行链路 agent_chat_iterator 逐段拆解

文档指出 agent_chat_iterator异步生成器,其内部编排逻辑分为多个关键步骤,下面结合文档与当前仓库源码逐段说明。

1. max_tokens 防御性归一化

进入循环前首先检查:若 max_tokens 是整数且 <= 0,则将其重置为 None。这样可避免传入 0 或负数导致模型侧 Token 限制异常,属于健壮性兜底。

2. 模型与工具上下文初始化

  • 通过 get_ChatOpenAI 初始化主聊天模型实例;
  • 调用 get_kb_details 获取知识库列表详情,注入模型容器(model_container)的数据库字段,使 Agent 在需要时可感知"有哪些知识库可用"(对应"检索本地知识库"类工具);
  • 若配置了 Agent_MODEL,则用该模型再初始化一个独立聊天模型实例并同样放入容器;否则复用前面初始化的主模型。

3. Prompt 模板与输出解析器装配

  • get_prompt_template 依据 prompt_name 取出模板内容;
  • CustomPromptTemplate 实例化自定义 Prompt 模板,用于把"可用工具描述 + 历史对话 + 当前问题"渲染为发给 LLM 的完整指令;
  • CustomOutputParser 创建输出解析器,负责把模型吐出的文本解析成结构化 Agent 动作。

这套"模板渲染 + 输出解析"的经典 Agent 架构,在当前仓库中被重构并下沉到 langchain_chatchat/agents 下,面向不同模型家族提供了多种解析器与模板工厂:

  • 模型家族输出解析器:structured_chat_output_parsers.pyglm3_output_parsers.pyqwen_output_parsers.py 等,分别对应通用、GLM3、Qwen 等模型的 Action 解析规则;
  • 平台工具类解析:platform_tools.pyplatform_knowledge_output_parsers.py 负责把模型消息中的 tool call 与函数调用解析为 Agent 动作;
  • Prompt 模板工厂:react/create_prompt_template.py 提供 create_prompt_glm3_templatecreate_prompt_structured_react_templatecreate_prompt_gpt_tool_templatecreate_prompt_platform_knowledge_mode_template 等,分别面向不同 Agent 执行范式(ReAct、GPT Function Calling、知识库增强模式等)。

4. Agent 执行器创建与异步驱动

旧文档描述:根据模型名称,若为 GLM3 则调用 initialize_glm3_agent 初始化专用 Agent 执行器,否则基于 LLMSingleActionAgent + AgentExecutor 组装通用执行器。这正是 Langchain-Chatchat 早期对 ChatGLM 函数调用格式做专项适配的体现。

从当前仓库结构看,该逻辑已升级为"按 Agent 类型注册 + 统一创建"的机制:

5. wrap_done 回调与异步产出

在异步循环中,Agent 执行器的运行会被包装成一个 asyncio 任务,用 wrap_done 绑定完成事件——任务结束即通过回调通知唤醒等待方,避免异步死锁。这一惯用封装在当前版本中仍保留于 Agent 工具包的公共基类中(位于 agent_toolkits/all_tools 下,定义 wrap_done(fn, event))。

之后分两条路径输出:

  • stream=True:异步迭代回调处理器(文档中的 CustomAsyncIteratorCallbackHandler)的缓存输出,依据当前 Agent 状态把日志/中间步聚/最终回答编码为 JSON 块并 yield
  • stream=False:在循环内累积全部输出,结束后一次性 yield 一个同时含 answerfinal_answer 的完整 JSON 对象。

四、返回格式约定:非流式与流式

1. 非流式输出

当请求未开启流式且用户查询最终生成了一系列回复时,函数返回如下结构的 JSON:

{
  "answer": "这是聊天过程中生成的回复文本。",
  "final_answer": "这是最终的回复文本。"
}

其中 answer 记录聊天过程中累计生成的回复文本,final_answer 则是经过完整推理(含工具调用后的收敛)产出的最终答案。接入方在非流式模式下只需等待接口整体返回并读取 final_answer 即可。

2. 流式输出

流式模式下函数逐块返回数据,前端可按"状态字段"增量渲染。典型的数据块分为两类。

第一类:工具调用过程块,携带本次工具名称、状态、输入与输出,供前端渲染"正在调用工具"的过程日志:

{
  "tools": [
    "工具名称: 天气查询",
    "工具状态: 调用成功",
    "工具输入: 北京今天天气",
    "工具输出: 北京今天多云,10-14摄氏度"
  ]
}

第二类:最终回答块,当 Agent 完成全部推理后下发:

{
  "final_answer": "这是最终的回复文本。"
}

从当前仓库的工具类型定义可以印证这类过程信息的结构设计:在 langchain_chatchat/agents/output_parsers/tools_output 目录下,分别针对普通函数工具(function.py)、代码解释器(code_interpreter.py)、画图工具(drawing_tool.py)、网页浏览工具(web_browser.py)定义了各自的 AgentAction 流式解析逻辑,说明"工具名称、输入、中间输出"作为 Agent 对话的流式中间事件被系统化建模。调用方在解析流时,应区分"过程事件块"与"终止回答块",前者做过程展示、后者做最终内容渲染并结束会话。

五、从接口文档到当前仓库的落地形态

如前所述,当前仓库已将 Agent 对话收敛到 chat_routes.py 定义的 /chat/completions 统一接口中。其请求解析规则与 agent_chat 的定位一脉相承:

  • 请求的 extra_body 中含 tool_input:视为对某个工具的直接调用(tool_choice);
  • 请求的 extra_body 中含 tool_choice 但不含 tool_input:通过 Agent 推理决定如何调用该工具;
  • 请求中带 tools 列表:进入 Agent 对话模式,由模型自主规划工具;
  • 其他情况:普通 LLM 对话。

也就是说,新版中"是否携带工具声明"即等价于旧文档 agent_chat 与普通 chat 的分界。该路由在把消息落库时明确记录了 chat_type="agent_chat"(见 chat_routes.py),与知识库对话(kb_chat)、文件对话(file_chat)在历史消息维度上被区分为不同类型的会话,便于后续按类型回放与统计。

支撑 Agent 对话的工具生态则沉淀在 server/agent/tools_factory/tools_registry.py 与同目录的工具实现中,包括天气查询(amap_weather.py)、高德 POI 搜索(amap_poi_search.py)、通用互联网搜索(search_internet.py)、本地知识库检索(search_local_knowledgebase.py)、计算器(calculate.py)、SQL 查询(text2sql.py)、PROMQL 查询(text2promql.py)、文生图(text2image.py)、URL 读取(url_reader.py)等,它们共同构成 Agent 可自主调用的工具集。

六、使用注意事项与最佳实践

文档明确提示了以下使用边界,结合实践可进一步展开:

  1. history 必须格式合法:每个元素应为 History 对象,或至少是能够被转换为 History 的数据结构,否则消息构造会失败。接入方建议在会话层统一维护 History 序列,不混用字符串与对象。
  2. stream 决定返回方式,需与前端配套:流式模式返回的是多段 JSON 事件流,前端要按事件类型分别渲染过程与结果;非流式模式则一次性返回完整对象。二者不能混用解析逻辑。
  3. 依赖项须预先配置agent_chat 强依赖已配置的 LLM 模型、工具注册与 Prompt 模板,调用前应确保模型服务(对应 LLM_MODELS 首模型或 Agent_MODEL)可用,否则 Agent 无法进入规划环节。
  4. prompt_name 与模型能力匹配:不同模型家族(GLM3 / Qwen / 通用 OpenAI 兼容)对工具调用的指令遵循格式不同,应选用与其输出解析器匹配的模板与执行器类型。
  5. 生产建议:对 Agent 会话适当调低 temperature 以保证 Action 输出格式稳定;max_tokens 设置过小会导致推理在工具调用中途被截断,一般交给模型默认最大值,仅在确有上下文预算约束时收紧。

七、小结

agent_chat 是理解 Langchain-Chatchat Agent 对话语义的钥匙:它以 query 为输入、以"模型 + 工具 + 模板 + 解析器"为推理内核,通过 stream 开关对外提供事件流与整体响应两种消费方式,并用 answer/final_answertools 等结构化字段把"过程"与"结果"清晰暴露给调用方。即便其底层实现在当前仓库中已重构并入 OpenAI 兼容的 /chat/completions(以 tools 是否存在判定 Agent 模式),本文所解析的参数语义、内部执行链路与输出格式约定,依然是理解并接入这一能力最直接的参考——建议配合 agent_chat.mdchat_routes.py 以及 agents 目录 下的解析器与模板工厂源码对照阅读。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
898
5.82 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
921
1.84 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.8 K
1.02 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
531
596
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.02 K
519
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.36 K
1.46 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
391