111.Agent-LangChain核心组件-Tools工具

**摘要:**本文围绕 LangChain 中工具(Tool)的定义与使用展开,重点讲解 @tool 注解的常用参数、Pydantic 的 Field 字段约束方式,以及如何通过 args_schema 将 Pydantic 模型接入工具,帮助大模型正确识别并调用函数。

内容参考于:图灵AI大模型全栈

工具就是大模型调用函数的能力

LangChain内置工具:https://docs.langchain.com/oss/python/integrations/tools

工具用到了@tool注解,如下图红框,注解里可以写的值

参数说明:

  • name_or_callable: str | Callable ..., Any | None = None:待包装函数或者工具名称;不传函数时作为装饰器,传函数则直接生成工具。
  • runnable: Runnable Any, Any | None = None:传入 LangChain Runnable 对象,使用该 Runnable 作为工具执行逻辑,替代被装饰函数。
  • *args: Any:内部兼容旧版本重载用的可变位置参数,业务代码不要手动传入。
  • description: str | None = None:工具功能描述,提供给大模型判断何时调用该工具;不填默认读取函数 docstring。
  • return_direct: bool = False:工具执行完毕后是否直接返回结果给用户,不再交由大模型继续思考。
  • args_schema: ArgsSchema | None = None:自定义 Pydantic 模型,定义工具入参 JSON 结构,优先级高于自动推断。
  • infer_schema: bool = True:是否自动从函数签名推断参数模型,关闭后必须手动提供 args_schema。
  • response_format: Literal "content", "content_and_artifact" = "content":工具返回结构;content 仅返回文本,content_and_artifact 返回摘要 content 与原始数据 artifact。
  • parse_docstring: bool = False:是否解析函数文档字符串,提取参数说明填充到工具 schema。
  • error_on_invalid_docstring: bool = True:开启 parse_docstring 时,文档字符串解析失败是否抛出异常;False 则静默忽略。
  • extras: dict str, Any | None = None:挂载到工具实例上的自定义元数据字典,大模型不可见,仅业务代码读取。

Python是一个是动态的语言,变量没有强制类型,它通过 Field 来对数据结构进行约束

参数说明:

  • default: Any = PydanticUndefined:字段默认值;不设置代表无默认值,必填。
  • default_factory: Callable \[, Any] | Callable \[dict \[str, Any], Any] | None = _Unset:工厂函数,用于动态生成字段默认值,不能和 default 同时使用。
  • alias: str | None = _Unset:序列化与反序列化通用别名,外部传入 key 和模型字段名不一致时使用。
  • alias_priority: int | None = _Unset:别名优先级,数值越大优先级越高,控制多个别名冲突时的选择。
  • validation_alias: str | AliasPath | AliasChoices | None = _Unset:仅反序列化校验阶段使用的别名,读取输入数据时生效,序列化输出不生效。
  • serialization_alias: str | None = _Unset:仅序列化输出阶段使用的别名,转 json 输出时替换字段名。
  • title: str | None = _Unset:生成 JSON Schema 时的标题文本。
  • field_title_generator: Callable \[str, FieldInfo, str] | None = _Unset:自定义回调函数,动态生成字段 title。
  • description: str | None = _Unset:JSON Schema 里字段描述,给 LLM / 文档查看。
  • examples: list Any | None = _Unset:JSON Schema 示例值列表,用于文档展示。
  • exclude: bool | None = _Unset:序列化时是否排除此字段,True 则输出 json 不包含该字段。
  • exclude_if: Callable \[Any, bool] | None = _Unset:回调函数,满足条件时序列化自动排除字段。
  • discriminator: str | types.Discriminator | None = _Unset:多态 Union 模型的鉴别器字段,用来自动匹配子模型。
  • deprecated: Deprecated | str | bool | None = _Unset:标记字段废弃,JSON Schema 增加 deprecated 标记。
  • json_schema_extra: JsonDict | Callable \[JsonDict, None] | None = _Unset:往 JSON Schema 追加自定义扩展字段。
  • frozen: bool | None = _Unset:标记字段只读,实例创建后不可修改。
  • validate_default: bool | None = _Unset:是否对 default/default_factory 生成的默认值执行校验。
  • repr: bool = _Unset:对象打印 repr 时是否展示该字段。
  • init: bool | None = _Unset:创建模型实例时,是否在init参数中包含此字段。
  • init_var: bool | None = _Unset:标记为初始化变量,仅实例构建时使用,不成为模型字段。
  • kw_only: bool | None = _Unset:是否强制该字段只能通过关键字参数传入。
  • pattern: str | re.Pattern str | None = _Unset:字符串正则校验规则。
  • strict: bool | None = _Unset:严格模式,开启时不自动做类型强制转换。
  • coerce_numbers_to_str: bool | None = _Unset:是否自动把数字强制转为字符串类型。
  • gt: annotated_types.SupportsGt | None = _Unset:数值校验,大于 (>)。
  • ge: annotated_types.SupportsGe | None = _Unset:数值校验,大于等于 (>=)。
  • lt: annotated_types.SupportsLt | None = _Unset:数值校验,小于 (<)。
  • le: annotated_types.SupportsLe | None = _Unset:数值校验,小于等于 (<=)。
  • multiple_of: float | None = _Unset:数值必须为此参数的倍数。
  • allow_inf_nan: bool | None = _Unset:是否允许 inf、nan 这类特殊浮点数。
  • max_digits: int | None = _Unset:Decimal 类型最大总位数。
  • decimal_places: int | None = _Unset:Decimal 类型小数点后保留位数。
  • min_length: int | None = _Unset:字符串 / 列表最小长度。
  • max_length: int | None = _Unset:字符串 / 列表最大长度。
  • union_mode: Literal 'smart', 'left_to_right' = _Unset:Union 联合类型的解析匹配策略。
  • fail_fast: bool | None = _Unset:校验时是否快速失败,遇到第一个错误就停止校验。
  • **extra: Unpack _EmptyKwargs:预留扩展关键字参数。 返回值:Any:返回 FieldInfo 实例,附加到模型字段上承载元信息。

代码:

python 复制代码
from langchain.tools import tool
import numexpr

# 函数名表示工具名称,这函数名要写的有意义不可以随便写,函数的参数表示工具的参数,函数返回值表示工具输出结果
# 函数的文档字符串会当做工具的描述,写到六个引号之间的内容就是文档字符串,注意老版本 LangChain 不是这样写的
# 所以文档字符串要写明白函数的作用、入参的作用、返回值的作用,从而保证Agent能够正确识别并且调用工具
# @tool ,这叫注解,这个注解的作用表示当前函数是LangChain的工具函数,老版本的LangChian函数的描述需要写到 @tool里
@tool
def get_天气(city:str)->str:

    # 下方Args是用来描述函数入参的,入参的数据类型和入参的作用
    # 下方Returns是用来描述函数返回值的,返回值类型和返回值的作用
    """
        获取指定城市的天气信息
        Args:
            city(str): 城市名称
        Returns:
            str: 天气信息
    """
    return f"{city}挺好"

# 下方是使用 @tool 注解来描述函数的作用,calculator是工具名,description它的值表示当前函数的作用描述
# 如果在注解中写了函数的描述和名字,然后在函数中用文档字符串又写了描述,那么它会以注解为主
@tool("calculator", description="执行算术计算。用这个来解数学题。输入应该是一个数学表达式,例如 '2 + 2' 或 'sqrt(16)'。")
def calc(expression: str) -> str:
    """计算数学表达式

    Args:
        expression (str): 数学表达式

    Returns:
        str: 计算结果
    """
    return str(numexpr.evaluate(expression).item())

# pydantic模型
from pydantic import BaseModel, Field

# Python是一个动态语言,变量没有强制类型,一个变量传递什么数据类型都可以,通过pydantic模型可以对数据类型进行校验
# 通过继承 pydantic模型中BaseModel类,来实现对数据类型的校验
class CalculateInput(BaseModel):
    # : str就表示当前变量要接收一个字符串
    # : float就表示当前变量要接收一个boolean类型的值
    # 使用 Field 可以对变量的值进行条件约束,它可以传递很多判断值的方式和逻辑
    operation: str = Field(description="要执行的运算类型,如 'add' 或 'multiply'")
    a: float = Field(description="第一个操作数")
    b: float = Field(description="第二个操作数")

# pydantic模型在工具中使用 args_schema 来的传递约束
@tool("calculator", args_schema=CalculateInput)
def calculate(operation: str, a: float, b: float) -> str:
    """当你需要进行数学计算时使用此工具"""
    if operation == "add":
        return str(a + b)
    elif operation == "multiply":
        return str(a * b)
    return "Unknown operation"

相关推荐
云雀衔光1 小时前
MCP + 应用生成:让 AI 直接产出可交互的应用
java·人工智能·测试工具·microsoft·交互·ai编程
武子康1 小时前
让 SGLang 按 JSON 回答,怎样少写一些补救代码
人工智能·llm·agent
小唔w1 小时前
文字一键生成播客音频,2026年几款AI工具功能梳理
人工智能·音视频
醍醐实验室1 小时前
分布式梯度累加(Gradient Accumulation):通信与计算的交错隐藏
人工智能
vivo互联网技术1 小时前
SmartPhotoCrafter: 先思考后修图,统一理解-生成的图像优化新范式
人工智能·算法·计算机视觉
沈管家AI数字员工1 小时前
对话式数据分析实操:从自然语言到可视化图表的全流程
数据库·人工智能·ai·oracle·数据分析
日常筹谋记1 小时前
深度评论:光模块固晶机精度跃迁中的三菱电机伺服与控制
人工智能
legendary_1631 小时前
PD‑SINK芯片在无协议后端负载中的工程应用
c语言·开发语言·人工智能·智能手机·计算机外设
代码柏拉图1 小时前
article
人工智能