跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像AI 生图工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
PythonAI算法

LangChain 实战:工具调用与结构化输出应用指南

深入探讨了 LangChain 中的工具调用与结构化输出技术。通过实战代码演示了三种工具创建方式及本地/第三方工具集成流程,详细对比了 Pydantic、TypedDict 和 JSON Schema 三种结构化输出方案的优劣。文章结合简历解析、意图识别及智能助手等场景,展示了如何将非结构化文本转化为规范数据,以及如何实现 AI 的智能决策与精准执行。核心在于利用结构化能力提升 AI 在自动化任务中的可靠性与可维护性。

人间过客发布于 2026/4/8更新于 2026/7/2135 浏览
LangChain 实战:工具调用与结构化输出应用指南

LangChain 实战:工具调用与结构化输出

工具调用(Tool Calling)和结构化输出是 LangChain 让 AI 从'聊天'走向'干活'的关键能力。前者允许模型调用外部函数或 API,后者则确保返回数据符合特定格式,便于程序处理。

工具调用(Tool Calling)

当 LLM 无法直接获取实时信息(如天气、数据库内容)时,我们可以借助工具完成查询。

创建工具的三种方式

  1. 直接用 @tool 装饰函数 最简单,适合轻量级小工具。
    from langchain_core.tools import tool
    
    @tool
    

def add(a: int, b: int) -> int: """计算两个数的和""" return a + b


2. **用 `@tool` + 自定义参数结构(Pydantic)**
参数更清晰,能写详细说明。
```python
from pydantic import BaseModel, Field

class AddInput(BaseModel):
    a: int = Field(description="第一个数")
    b: int = Field(description="第二个数")

@tool(args_schema=AddInput)
def add(a: int, b: int) -> int:
    return a + b
  1. 继承 BaseTool 写类 最灵活,适合复杂逻辑或异步操作。
    from langchain_core.tools import BaseTool
    
    class AddTool(BaseTool):
        name = "add_tool"
        description = "用于加法运算的工具"
    
        def _run(self, a: int, b: int) -> int:
            return a + b
    

本地自定义工具实战

定义好工具后,需要将其绑定到模型。这里以 DeepSeek 模型为例。

from langchain.chat_models import init_chat_model
from langchain_core.messages import HumanMessage, SystemMessage, ToolMessage

llm = init_chat_model(
    model="deepseek-chat",
    model_provider="deepseek",
    api_key="your-api-key",
    temperature=0.7,
    max_tokens=8192,
)

# 绑定工具
bound_llm = llm.bind_tools([add])

调用流程解析:

  1. 构建用户消息,包含系统提示和具体请求。
  2. 模型决定是否调用工具。如果决定调用,响应中会包含 tool_calls。
  3. 执行工具,并将结果包装为 ToolMessage 返回给模型。
  4. 模型根据工具结果生成最终回答。
message = [
    SystemMessage(content="你是一个数学助手。当用户给你一个数字 n 时,使用 add 工具计算结果。"),
    HumanMessage(content="请计算 5 加 3 的结果。"),
]

ai_message = bound_llm.invoke(message)
message.append(ai_message)

# 如果有工具调用,执行它
if ai_message.tool_calls:
    for tool_call in ai_message.tool_calls:
        if tool_call["name"] == "add":
            result = add.invoke(tool_call["args"])
            message.append(ToolMessage(content=str(result), tool_call_id=tool_call["id"]))

final_msg = bound_llm.invoke(message).content
print(final_msg)

注意: ai_message 是经过框架整合的响应,必须使用 ToolMessage 包装执行结果并提供 tool_call_id,否则模型无法关联上下文。

第三方工具集成

集成第三方服务(如 Tavily 搜索)通常需要提供 API Key。

from langchain_tavily import TavilySearch

tavily_tool = TavilySearch(
    max_results=4,
    tavily_api_key="your-tavily-api-key"
)
bound_llm = llm.bind_tools([tavily_tool])

支持多轮调用,模型可以根据搜索结果自动判断是否需要进一步搜索。

结构化输出(Structured Output)

结构化输出允许模型返回符合特定格式的数据,而不是纯文本。这对于数据存储、API 响应生成等场景非常有用。

Pydantic BaseModel(推荐)

这是最常用且类型安全的方式。

from pydantic import BaseModel, Field

class WeatherInfo(BaseModel):
    city: str = Field(description="城市名称")
    weather: str = Field(description="天气状况")
    temperature: str = Field(description="温度范围")

model = llm.with_structured_output(WeatherInfo)
result = model.invoke("上海现在的天气如何?")
print(f"城市:{result.city}")

优点: 类型安全,IDE 有完整提示,支持字段验证。

TypedDict

轻量级方案,返回纯字典。

from typing import TypedDict, Annotated

class WeatherDict(TypedDict):
    city: Annotated[str, "城市名称"]
    weather: Annotated[str, "天气状况"]

model = llm.with_structured_output(WeatherDict)
result = model.invoke("北京天气")
print(result["city"])

缺点: 类型检查较弱,不支持 Field() 的高级功能。

JSON Schema

标准化格式,跨语言通用,适合复杂嵌套结构。

import json

json_schema = {
    "type": "object",
    "properties": {
        "city": {"type": "string", "description": "城市名称"},
        "weather": {"type": "string", "description": "天气状况"}
    },
    "required": ["city", "weather"]
}

model = llm.with_structured_output(json_schema)
result = model.invoke("广州天气")
print(json.dumps(result, ensure_ascii=False, indent=2))

可选结构化输出(动态类型选择)

当需要根据输入自动选择返回不同类型的数据时,可以使用 Literal 类型配合嵌套模型。

from typing import Literal

class PersonInfo(BaseModel):
    name: str
    age: int

class CityInfo(BaseModel):
    city: str
    population: int

class Response(BaseModel):
    type: Literal["person", "city"] = Field(description="响应类型")
    person: PersonInfo | None = None
    city: CityInfo | None = None

model = llm.with_structured_output(Response)
result = model.invoke("介绍一下张三")
if result.type == "person":
    print(f"姓名:{result.person.name}")

三大实际应用场景

1. 信息提取器

将非结构化文本转化为结构化数据。例如从简历中提取姓名、教育经历和工作经历。

from pydantic import BaseModel, Field

class Education(BaseModel):
    school: str
    degree: str

class ResumeInfo(BaseModel):
    name: str
    education: list[Education]

model = llm.with_structured_output(ResumeInfo)
resume_text = "...简历内容..."
result = model.invoke(f"提取信息:\n{resume_text}")

2. 提示词增强

帮助 AI 更好理解用户意图。将模糊需求转换为明确的结构化指令。

class SearchIntent(BaseModel):
    intent_type: Literal["informational", "transactional"]
    keywords: list[str]

intent = model.invoke("我想买个性价比高的笔记本")
# 根据 intent.intent_type 执行不同策略

3. 与 Tool 联合使用

结构化输出 + 工具调用的完美组合。AI 先分析需求并输出结构化决策,然后调用相应工具执行。

# 步骤 1:绑定工具
bound_llm = llm.bind_tools([tavily_tool])
# 步骤 2:绑定结构化输出
structured_llm = bound_llm.with_structured_output(WeatherResult)
# 步骤 3:直接调用
result = structured_llm.invoke("北京天气")

总结

方式优点适用场景
Pydantic类型安全、验证强复杂数据结构
TypedDict轻量、纯字典简单键值对
JSON Schema标准化、跨语言跨系统对接
可选输出灵活性高多类型动态响应

选择合适的输出方式取决于你的业务需求。如果是内部 Python 项目,Pydantic 通常是首选;如果需要与其他语言交互,JSON Schema 更稳妥。

目录

  1. LangChain 实战:工具调用与结构化输出
  2. 工具调用(Tool Calling)
  3. 创建工具的三种方式
  4. 本地自定义工具实战
  5. 绑定工具
  6. 如果有工具调用,执行它
  7. 第三方工具集成
  8. 结构化输出(Structured Output)
  9. Pydantic BaseModel(推荐)
  10. TypedDict
  11. JSON Schema
  12. 可选结构化输出(动态类型选择)
  13. 三大实际应用场景
  14. 1. 信息提取器
  15. 2. 提示词增强
  16. 根据 intent.intent_type 执行不同策略
  17. 3. 与 Tool 联合使用
  18. 步骤 1:绑定工具
  19. 步骤 2:绑定结构化输出
  20. 步骤 3:直接调用
  21. 总结
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • 前端大数据导出优化:解决 Chrome 内存崩溃的实战方案
  • 2023 年网络安全岗位前景分析与求职指南
  • AbortController 入门教程:Web API 请求取消核心概念
  • Java 异常处理机制:try-catch 用法与体系结构
  • C++ 异常处理机制详解
  • MySQL 表约束核心指南:从基础到外键实战
  • Python 数据可视化的 3 个核心步骤
  • KES 数据库运维:资源回收与膨胀防治全攻略
  • 前后端分离与不分离架构对比分析
  • AI Agent 自动化工作流系统架构与实现
  • 前端函数防抖详解
  • Kali Linux 虚拟机安装与基础配置图文教程
  • Python 核心技术点汇总:装饰器、拷贝与数据结构
  • npm 安装 OpenClaw 时 Git 报错的解决方法
  • Java 核心面试题汇总:基础、并发、集合与框架实战
  • Google 发布 Gemini Embedding 2 及 MuleRun 自进化 AI 助手
  • Nacos 构建 Spring Cloud Alibaba 服务发现体系
  • 前端可访问性:别让网站成为障碍
  • 2025 年 AI 办公工具评测:PPT 生成与远程控制
  • 开源软件管理实战指南:从问题诊断到高效运维

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • RSA密钥对生成器

    生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online

  • Mermaid 预览与可视化编辑

    基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online

  • 随机西班牙地址生成器

    随机生成西班牙地址(支持马德里、加泰罗尼亚、安达卢西亚、瓦伦西亚筛选),支持数量快捷选择、显示全部与下载。 在线工具,随机西班牙地址生成器在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • curl 转代码

    解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online