LangChain 资深开发者完全指南

这份文档详细介绍了 LangChain 库的多个高级功能和最佳实践。以下是几个关键点的总结和一些补充信息,以帮助更好地理解和使用这些功能:

模型绑定工具 (bind_tools)

绑定工具是将模型与其能够调用的工具关联起来的过程。这允许LLM根据特定任务选择合适的工具来执行操作(如查询数据库、搜索网络等)。以下是几个重要的注意事项和示例:

  1. 定义工具

    • 使用 @tool 装饰器或自定义 BaseTool 类来定义工具。
    • 示例代码展示了如何使用 Pydantic 模型作为工具的参数模式。
  2. 绑定工具到模型

    model_with_tools = model.bind_tools(
        tools=[add, weather],  # 工具列表,可以是 @tool 装饰器定义或 BaseTool 类实例
        tool_choice="auto",    # 参数表示LLM如何选择调用的工具,默认为 "auto"
        strict=True            # 对于某些模型(如 OpenAI),启用严格的模式检查。
    )
  3. 处理结果

    • 调用绑定后的模型会返回包含调用信息的消息,可以通过 AIMessage 类中的 tool_calls 属性访问。

结构化响应 (with_structured_output)

结构化响应允许将LLM的输出转换为特定格式(如JSON或Pydantic模型),便于后续处理。这在需要程序化使用LLM结果时非常有用:

  1. 定义模式

    • 使用 Pydantic 模型定义期望的输出格式。
  2. 配置结构化响应

    structured = model.with_structured_output(
        schema=Answer,         # 定义输出模式
        method="json_schema",  # 方法可以是 "function_calling" | "json_mode" | "json_schema"
        include_raw=False      # 默认为False,选择是否包含原始响应。
    )
  3. 处理结果

    • 结构化模型的 invoke 方法将返回符合指定模式的对象。

创建Agent (create_agent)

通过 create_agent 函数创建一个封装了LLM及其工具集的高级代理。这为构建复杂的交互式系统提供了强大的基础:

  1. 定义状态模式

    • 自定义的状态类必须继承自 AgentState 并使用 TypedDict。
  2. 构造代理

    agent = create_agent(
        model="openai:gpt-5.2",
        tools=[add],  # 可以是函数,也可以是BaseTool实例或字典
        prompt="You are a math assistant.",  # 启动时的提示信息
    )
  3. 使用代理

    • 调用代理的方法(如 invoke)来处理消息和执行任务。

模型配置与回调

模型配置和回调允许更灵活地控制LLM的行为,包括日志记录、统计收集等:

  1. 使用配置注入

    msg = model.invoke(
        messages,
        config={
            "callbacks": [UsageMetadataCallbackHandler()],  # 注入回调处理器
            "tags": ["extraction"],                         # 标签用于后续过滤和分析
            "metadata": {"task_id": "T-101"}               # 元数据,提供上下文信息
        },
    )
  2. 避免旧式绑定

    • 使用配置而不是通过模型构造函数注入回调。

常见陷阱

文档中提到的两个常见问题值得注意:

  1. with_structured_output 与 bind_tools 的不兼容:使用 with_structured_output 方法时,不再有 .bind_tools() 方法可用。
  2. 流式状态下工具参数的合并不稳定:部分提供商在流模式下不会以增量方式输出工具参数。

通过理解这些要点和陷阱,开发人员可以更有效地利用 LangChain 来构建强大的、可扩展的应用程序。

总结与关键概念

在LangChain v1.0中,以下几个核心的概念和实践非常重要:

1. Runnable 协议

  • Runnable 协议是所有事物的基础,包括语言模型、工具和消息处理。
  • | 操作符用于组合和扩展 Runnable 对象。

2. create_agent 函数

  • 使用 create_agent 可以快速构建代理(Agent),避免手工编写复杂的 AgentExecutor。
  • Middleware 是新的扩展点,可以轻松定制化行为。

3. langchain-core 包

  • 提供了底层的抽象和协议定义,确保代码可以在不同的提供商之间无缝切换。
  • BaseLanguageModel, BaseChatModel, 和 BaseLLM 等接口是核心的一部分。

4. LangGraph 框架

  • LangGraph 是复杂的异步任务执行框架,适用于需要高度定制化的场景。
  • 可以通过创建自定义的 StateGraph 来解决更为复杂的问题。

5. LangSmith 观测工具

  • 开启 LANGSMITH_TRACING=true 可以零成本地实现观测功能,有助于调试和性能优化。
  • 使用 with_config({"run_name": "xxx"}) 和 metadata={"user_id": ..., "session_id": ...} 提供更好的可读性。

生产最佳实践

1. 可观测性

  • 开启 LangSmith 进行实时观测,便于问题排查。
  • 在关键 Runnable 中添加运行名称和元数据信息以提升追踪能力。

2. 可靠性

  • 使用重试机制(如 .with_retry() 或 ModelRetryMiddleware)确保稳定性。
  • 实现回退策略应对主服务不可用的情况。
  • 设置合理的超时时间,避免长时间等待无响应的请求。

3. 成本控制

  • 利用工具选择器(如 LLMToolSelectorMiddleware)和缓存机制减少高成本模型的调用量。
  • 使用结构化输出优先处理原生 JSON 模式以降低成本。

4. 安全性

  • 实现 PII 掩码或阻断,保护隐私信息不被泄露。
  • 在 wrap_tool_call 中进行权限验证,确保工具的安全使用。
  • 不要直接暴露给终端用户配置项中的敏感参数。

5. 并发与吞吐量优化

  • 使用 .abatch(inputs, max_concurrency=N) 和异步方法提高系统的处理能力。

快速参考

22.1 Runnable 方法

方法返回类型描述
invokeOutput同步单次调用
ainvokeOutput异步单次调用
streamIterator[Output]同步流式处理
astreamAsyncIterator[Output]异步流式处理
batchlist[Output]批量同步处理
abatchlist[Output]批量异步处理
astream_eventsAsyncIterator[StreamEvent]高保真事件流

22.3 工具速查

  • 使用 @tool 装饰器定义工具。
  • 使用 BaseTool, StructuredTool, 和 InjectedToolArg 创建和管理工具。

关键源码路径

文件内容
libs/core/langchain_core/runnables/base.pyRunnable, RunnableSequence, RunnableParallel, RunnableBinding
libs/core/langchain_core/prompts/chat.pyChatPromptTemplate, MessagesPlaceholder
libs/partners/openai/, anthropic/, ...各合作伙伴的具体实现

结语

通过结合使用 create_agent 函数构建日常代理,利用 LangGraph 处理复杂任务,并始终保持在 langchain-core 的协议范围内编程,你可以在不断变化的技术环境中保持灵活性和效率。同时,集成 LangSmith 可以帮助你更好地理解系统行为并优化性能。


> 🔗 相关阅读LangChain.js 架构设计深度剖析