LLMStart|持续课程 · 不追玄学
模块 5 · 5.2
进阶级65 分钟

5.2Function Calling / Tool Use

本课只解决一个主问题:本单元只解决一个主问题:

LLM 本身只会生成文本,为什么它能查数据库、发邮件、执行代码或操作外部系统?

学习目标

学完本单元后,学习者应该能够:

  • 解释 Function Calling / Tool Use 的基本机制。
  • 理解工具 schema、参数校验、工具返回和模型后续生成的关系。
  • 设计一个基础工具调用流程。
  • 识别工具调用中的权限、幂等性和错误处理问题。
  • 判断什么时候应该让模型调用工具,什么时候不应该。

先给直觉

模型本身不会真的“打开日历”或“查询数据库”。

它能做的是:

  1. 理解用户想做什么。
  2. 选择一个可用工具。
  3. 生成符合工具要求的参数。
  4. 由外部程序真正执行工具。
  5. 工具把结果返回给模型。
  6. 模型根据结果继续回答或决定下一步。

所以工具调用不是模型突然长出了手,而是系统给它配了受控的接口。

基本流程

一个简化工具调用流程:

用户请求
  ↓
模型判断需要调用工具
  ↓
模型生成工具名和参数
  ↓
系统校验参数和权限
  ↓
外部工具执行
  ↓
工具返回结果
  ↓
模型根据结果生成回答

关键点:真正执行动作的是系统,不是模型自己。

什么是工具

工具是模型可以请求调用的外部能力。

常见工具:

  • 搜索网页
  • 查询数据库
  • 读取文件
  • 写入文件
  • 执行代码
  • 发送邮件
  • 创建日历事件
  • 调用支付接口
  • 查询订单状态
  • 生成图片

工具可以很简单,也可以很危险。查询天气和转账付款显然不是一个风险等级。

工具 schema

工具 schema 是告诉模型:

  • 有哪些工具。
  • 每个工具做什么。
  • 需要哪些参数。
  • 参数类型是什么。
  • 哪些参数必填。
  • 参数有什么约束。

例子:

{
  "name": "search_course",
  "description": "在课程资料中搜索相关内容",
  "parameters": {
    "query": {
      "type": "string",
      "description": "用户要搜索的问题"
    },
    "module": {
      "type": "string",
      "description": "可选,限定课程模块"
    }
  },
  "required": ["query"]
}

好的 schema 能减少模型误用工具。

差 schema 的问题:

  • 工具描述太模糊。
  • 参数名不清楚。
  • 没有说明必填项。
  • 没有限制输入范围。
  • 把高风险能力暴露得太随意。

参数校验

模型生成的参数不能直接信任。

系统必须校验:

  • 类型是否正确。
  • 必填项是否存在。
  • 值是否在允许范围内。
  • 用户是否有权限。
  • 是否包含危险内容。
  • 是否会造成重复或破坏性操作。

例子:

模型想调用:

{
  "tool": "send_email",
  "to": "all@company.com",
  "subject": "紧急通知",
  "body": "..."
}

系统不应该直接发送。它至少要检查权限,并要求用户确认。

工具返回结果

工具返回给模型的内容也要设计。

好的返回结果应该:

  • 结构清晰。
  • 包含必要字段。
  • 明确成功或失败。
  • 错误信息可理解。
  • 避免泄露无关敏感数据。

例子:

{
  "status": "success",
  "results": [
    {
      "title": "4.1 为什么需要 RAG",
      "path": "04_rag_knowledge/01_why_rag/lesson.md",
      "snippet": "RAG 的思路是先查资料,再让模型带着资料回答。"
    }
  ]
}

模型看到这个结果后,才能继续生成有依据的回答。

幂等性

幂等性是工程里非常重要的概念。

简单说:同一个操作执行多次,结果不会造成额外副作用。

查询天气通常是幂等的。

发送邮件不是幂等的。调用两次就可能发两封。

付款、删除文件、发布文章,也通常不是幂等的。

对非幂等工具,必须特别小心:

  • 加确认节点。
  • 加去重 ID。
  • 加日志。
  • 加回滚或补救方案。
  • 限制重试。

Agent 系统最怕的是工具失败后模型“再试一次”,结果把邮件发了五遍。收件人也许会记住你,但方式不太理想。

权限边界

工具调用必须有权限设计。

至少考虑:

  • 哪些用户能调用工具。
  • 工具能访问哪些数据。
  • 工具能执行哪些动作。
  • 是否需要二次确认。
  • 是否有日志审计。
  • 是否能撤销。

权限不能靠 Prompt 约束。

不要只写:

请不要访问敏感数据。

系统层必须真的不让它访问。

错误处理

工具调用一定会失败。

常见失败:

  • 参数错误。
  • 权限不足。
  • 网络超时。
  • 外部 API 失败。
  • 返回数据为空。
  • 结果格式变化。
  • 工具执行了一半失败。

系统要告诉模型失败原因,并让模型采取合理下一步。

例子:

{
  "status": "error",
  "code": "PERMISSION_DENIED",
  "message": "当前用户无权访问该文档"
}

模型应该回复:

我无法访问该文档。你可以提供有权限的资料,或联系管理员调整权限。

而不是编一个答案。

工具选择

不是所有问题都需要工具。

适合调用工具:

  • 需要实时信息。
  • 需要私有数据。
  • 需要执行动作。
  • 需要精确计算。
  • 需要验证事实。

不一定需要工具:

  • 通用概念解释。
  • 轻量改写。
  • 头脑风暴。
  • 风格润色。

工具调用会增加成本、延迟和失败点。能不用工具稳定解决,就不要为了显得高级硬加工具。

人类确认

高风险工具调用前必须确认。

建议确认的动作:

  • 发邮件。
  • 发消息。
  • 删除文件。
  • 覆盖文档。
  • 付款。
  • 下单。
  • 发布内容。
  • 修改生产数据。
  • 调用外部客户系统。

确认界面应该显示:

  • 工具名称。
  • 即将执行的动作。
  • 参数。
  • 影响范围。
  • 是否可撤销。

不要只给一个“确定吗?”按钮。用户需要知道自己在确认什么。

案例:课程资料搜索工具

目标:让模型搜索 LLMCourse 内容。

工具:

{
  "name": "search_course",
  "description": "搜索课程讲义和模块说明",
  "parameters": {
    "query": {
      "type": "string",
      "description": "搜索问题或关键词"
    },
    "module": {
      "type": "string",
      "description": "可选,限定模块,如 RAG、Agent、Prompt"
    },
    "top_k": {
      "type": "integer",
      "description": "返回结果数量,范围 1 到 10"
    }
  },
  "required": ["query"]
}

系统校验:

  • query 不能为空。
  • top_k 默认 5,最大 10。
  • module 必须来自允许列表。
  • 只搜索已发布课程内容。

工具返回:

  • 文件路径。
  • 小标题。
  • 片段。
  • 相似度或排序分数。

模型生成回答:

  • 根据返回片段回答。
  • 引用课程路径。
  • 如果没有结果,说明未找到资料。

常见误区

误区 1:模型调用工具就是模型自己执行动作

不是。模型生成调用请求,系统执行工具。

误区 2:Prompt 可以替代权限控制

不能。权限必须在系统层实现。

误区 3:工具越多,Agent 越强

工具越多,选择和安全问题越复杂。工具要按任务需要设计。

误区 4:工具失败时让模型自己圆回来就行

不行。工具失败要明确暴露,不能让模型编造结果。

误区 5:所有工具都可以自动重试

非幂等工具不能随意重试,否则可能造成重复副作用。

动手练习

设计一个工具,让 AI 帮你管理课程任务。

填写:

项目 你的设计
工具名称
工具用途
输入参数
必填参数
参数校验规则
返回结果格式
权限限制
是否需要确认
失败时怎么办
检查题(自测)
  1. 工具调用的基本流程是什么?
  2. 为什么模型生成的工具参数必须校验?
  3. 什么是幂等性?为什么它对工具调用重要?
参考答案
  1. 基本流程:模型输出结构化的工具调用请求 → 系统解析并校验参数 → 执行工具 → 把结果返回给模型 → 模型基于结果继续生成。
  2. 模型生成的参数可能格式错误、取值非法或越权,不校验可能导致错误执行、数据损坏或权限滥用;校验是工具调用的安全底线。
  3. 幂等性指同一操作执行多次结果一致。它对工具调用重要,因为重试不可避免:如果每次重试都重复扣款、重复发送,后果会很严重。

Takeaway

Tool Use 让 LLM 能连接外部世界,但真正可靠的工具调用依赖 schema、参数校验、权限、错误处理、幂等性和人类确认。模型负责提出动作,系统负责安全执行。