createToolCallingAgent#
createReactAgent
核心机制:ReAct 框架(Reasoning + Acting)
- 工作方式:基于经典的 ReAct(Reason, Act)范式。代理在每一步中交替进行“思考(Thought)”、“行动(Action)”和“观察(Observation)”。
- Thought:模型解释它为什么采取某个行动。
- Action:决定是调用某个工具还是结束任务。
- Observation:执行工具后获得的结果。
- 该过程循环进行,直到模型决定
Final Answer。
- 推理过程:使用思维链(Chain-of-Thought)进行多步推理。模型明确输出其推理过程,然后决定下一步行动。
- 特点:
- 可解释性强:由于输出中间推理步骤,更容易调试和理解代理的决策过程。
- 兼容性好:即使模型不支持原生工具调用,也可以通过文本解析实现。
- 开销较大:可能需要多次模型调用才能完成任务。
- 适用场景:适用于需要透明推理过程、调试复杂任务或使用不支持原生工具调用的模型。
对于现代 LLM(如 GPT-4),当前 LangChain.js 更推荐使用 createToolCallingAgent。
核心机制:直接提示(Direct Prompting)与结构化输出(Structured Output)
- 工作方式:该代理使用现代大语言模型(LLM)原生支持的函数调用(Function Calling)或工具调用(Tool Calling)能力。代理提示模型直接输出一个结构化的调用指令,指定要使用的工具(tool)及其输入参数。
- 推理过程:模型在单步内决定是否调用工具,并直接生成调用请求。如果需要调用,它会输出一个工具调用动作;否则,直接生成最终回复。
- 特点:
- 高效:通常只需要一次或少数几次模型调用即可完成任务。
- 依赖模型能力:要求底层LLM支持结构化输出或工具调用功能(如OpenAI的
gpt-3.5-turbo或gpt-4系列)。 - 简洁:不涉及复杂的思维链(Chain-of-Thought)推理。
- 适用场景:适用于现代支持工具调用的LLM,追求效率和低延迟的场景。
总结对比表
| 特性 | createToolCallingAgent | createReactAgent |
|---|---|---|
| 底层机制 | 原生工具调用(Tool Calling) | ReAct 框架(Reason + Act) |
| 推理方式 | 直接决策,无显式思考过程 | 多步思维链(Thought → Action → Observation) |
| 模型要求 | 需支持结构化输出/工具调用的LLM | 任何文本生成模型均可(兼容性更强) |
| 调用效率 | 高(通常1-2次调用) | 较低(可能多次循环) |
| 可解释性 | 低(直接输出调用或回复) | 高(显示完整推理链) |
| 适用LLM | OpenAI, Anthropic, 支持tool calling的模型 | 所有模型,尤其适合不支持tool calling的模型 |
| 典型应用 | 快速响应、生产环境高效执行 | 教学、调试、复杂任务分析 |
最佳实践
两者代表了 Agent 设计中“效率”与“透明度”的权衡:
- 如果你使用的是支持工具调用的现代LLM(如GPT-4),并且追求高性能和低延迟,应优先使用
createToolCallingAgent。 - 如果你需要可解释的推理过程,或者使用的是不支持原生工具调用的模型,则
createReactAgent更合适。
streamEvents#
这是 AgentExecutor 提供的一个异步可迭代方法,用于在执行过程中实时产生事件流,而不是等待整个执行完成才返回结果。
与 .invoke() 或 .stream() 不同,.streamEvents() 提供的是最细粒度的执行过程信息,适合用于调试、监控、前端实时展示等场景。
const events = await executor.streamEvents( { input, chat_history }, { version: 'v2' })参数:
{input, chat_history}
- input:用户当前的输入问题或指令。例如:
"今天北京天气怎么样?" - chat_history:对话历史,用于支持多轮对话。
- 通常是
BaseMessage对象数组,如[new HumanMessage("你好"), new AIMessage("你好!")] - 这让 Agent 能够理解上下文,避免“失忆”。
- 通常是
{version: "v2"}
表示使用事件系统 v2 版本。该版本关键能力:
-
支持 token 级别的流式输出,特别是
on_chat_model_stream事件,可以捕获大模型生成的每一个 token。这意味着可以实现逐字输出效果。 -
提供更丰富、更结构化的事件类型,例如:
on_llm_start:LLM 开始生成on_llm_end:LLM 生成结束on_tool_start:某个工具开始执行on_tool_end:工具执行完成on_chain_start/on_chain_end:子链(如 Agent 步骤)的开始与结束on_chat_model_stream:每个 token 生成时触发
-
用法:
const events = await executor.streamEvents({ input, chat_history },{ version: 'v2' })for await (const event of events) {if (event.event === 'on_chat_model_stream') {const token = event.data.chunk.content // 获取当前生成的 tokenprocess.stdout.write(token) // 实时打印(像打字机一样)}if (event.event === 'on_tool_start') {console.log(`正在调用工具: ${event.name}`)}if (event.event === 'on_tool_end') {console.log(`工具结果:`, event.data.output)}}
LangGraph#
LangChain 官方目前更加推荐使用 LangGraph 来创建 Agent,而不是传统的基于 AgentExecutor 的纯 LangChain 方法。
这并非意味着 LangChain 本身被弃用,而是 LangGraph 被定位为构建复杂、有状态、多步骤 Agent 的更强大、更灵活的底层框架。LangChain 的核心组件(如 LLM、工具、记忆等)仍然是基础,而 LangGraph 则是在其之上进行高级编排的“大脑”。
传统 AgentExecutor 的局限性
- 线性/简单循环:
AgentExecutor通常遵循“思考 → 行动 → 观察”的固定循环,难以实现复杂的控制流。 - 缺乏状态持久化:执行过程中的状态难以保存,无法轻松实现暂停、恢复、人工介入。
- 调试困难:执行过程像“黑箱”,难以监控中间步骤和决策路径。
- 不支持多 Agent 协作:难以构建多个 Agent 分工协作的系统。
LangGraph 的核心优势
LangGraph 基于“有向图”(Directed Graph)的概念,将 Agent 的执行流程建模为节点(Nodes)和边(Edges)的图结构。
- 循环与分支控制:支持复杂的条件分支、循环、并行执行,适合真实世界的复杂任务。
- 状态持久化:每一步执行后自动保存状态,支持:
- 错误恢复(崩溃后从断点继续)
- 人工介入(暂停执行,人工确认或修改)
- 长时间运行任务(如多日流程)
- 多 Agent 协作:轻松构建“规划 Agent”、“执行 Agent”、“验证 Agent”等角色协同工作。
- 与 LangChain 无缝集成:可直接使用 LangChain 的 LLM、Tools、Retrievers 等组件作为图中的节点。
LangGraph 目前已从 LangChain 中独立出来,拥有自己的文档、GitHub 仓库和持续更新。官方称其为“用于构建有状态、多参与者 LLM 应用的框架”。