Skip to content

Agent实践

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-turbogpt-4系列)。
    • 简洁:不涉及复杂的思维链(Chain-of-Thought)推理。
  • 适用场景:适用于现代支持工具调用的LLM,追求效率和低延迟的场景。

总结对比表

特性createToolCallingAgentcreateReactAgent
底层机制原生工具调用(Tool Calling)ReAct 框架(Reason + Act)
推理方式直接决策,无显式思考过程多步思维链(Thought → Action → Observation)
模型要求需支持结构化输出/工具调用的LLM任何文本生成模型均可(兼容性更强)
调用效率高(通常1-2次调用)较低(可能多次循环)
可解释性低(直接输出调用或回复)高(显示完整推理链)
适用LLMOpenAI, 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' }
)

参数:

  1. {input, chat_history}
  • input:用户当前的输入问题或指令。例如:"今天北京天气怎么样?"
  • chat_history:对话历史,用于支持多轮对话。
    • 通常是 BaseMessage 对象数组,如 [new HumanMessage("你好"), new AIMessage("你好!")]
    • 这让 Agent 能够理解上下文,避免“失忆”。
  1. {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 // 获取当前生成的 token
    process.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 应用的框架”。