Agent Capabilities 1: Tool Use
- 日期
- Thu, Aug 27, 2026
- 课程资料
- 32 项
- 内容产物
- 4 项
课程简介
CMU 11-768 Fall 2026 · Lecture 2 · Agent Capabilities 1: Tool Use 学习笔记
来源:平台字幕与官方 Slides。内容已由用户审核确认。
依据:Lecture 2 slides(官方 PDF 文本提取,待核)与中文逐字稿整理稿(机器翻译,待审核)。图示、公式与任何仅凭文本提取无法确认的细节均标注“待核”。本笔记不代表官方结论,也内容已由用户审核确认。
一、学习目标
学完本节课,应该能够:
- 说清“工具”在语言模型智能体中的定义与边界:工具是语言模型调用外部计算机程序的接口,模型提出调用,外部软件决定是否以及如何执行(Slides 第 3 页)。
- 区分工具的两类收益——“扩展”(Extend)与“促进”(Facilitate),并能对给定例子判断属于哪一类(Slides 第 4 页、第 5 页;逐字稿 01:17 起)。
- 识别典型工具类别:文本回复(finish 控制动作)、信息检索、代码执行、图像生成、自定义函数(Slides 第 8–12 页)。
- 理解“代码作为元工具”的含义与代价:表达力强、能组合控制流与库;但更难约束、影响更大,需要沙盒与资源限制(Slides 第 14–17 页)。
- 描述工具调用的机制链路:schema 进入提示词 → 模型按自身协议发出调用 → 解析 → 校验 → 分发执行 → 用 call ID 匹配结果(Slides 第 19–25 页)。
- 区分语法/形状/类型/取值四类约束,理解为什么约束解码“保证形式而不保证语义正确”(Slides 第 28–35 页)。
- 比较直接 REST 调用与 MCP 的契约差别,尤其是凭证中介(credential brokering)这一点(Slides 第 37–46 页)。
- 说明并行工具调用的适用条件、时间收益与实现要点(Slides 第 48–51 页)。
- 用“选择—参数—轨迹—任务”四层以及效率、可靠性、安全性三个运营维度来评估工具使用(Slides 第 53–57 页)。
二、概念主线
本节课的主线可以概括为一句幻灯片原话:工具使用是一个分层系统(Slides 第 59 页)。
- 能力层:工具为智能体增加检索、执行、生成与应用类动作;这正是智能体区别于纯语言模型的地方。
- 机制层:schema 进入提示词;不同模型有各自的工具调用序列化协议;harness 负责校验、分发、按 ID 匹配结果。
- 约束层:JSON Schema 与语法掩码保证“形式正确”,但不保证语义正确、权限正确或工具选择正确。
- 接口层:直接 REST 调用与 MCP 是暴露能力的两种替代方式,后者额外处理凭证隔离。
- 系统层:编排依赖关系与并发,并从选择、参数、结果、成本、运营故障等角度做评估。
一个贯穿性的判断标准在 Slides 第 5 页给出:只有在工具的收益超过延迟、成本、失败与风险时,才应该调用工具。这句话是后面所有“为什么不全用代码”“为什么要沙盒”“为什么评估要看运营指标”的共同理由。
三、关键机制
3.1 工具的分类与两类收益
Slides 第 3 页给出定义与例子清单:搜索、计算器、浏览器、Python、API。Slides 第 4 页区分两类收益:
- 扩展(Extend):访问模型参数中不可得的信息或动作。
- 促进(Facilitate):把外部程序做得更可靠或更高效的操作委托出去。
逐字稿中的例子很适合用来检验理解:模型无从知道四个月前的日期,因为参数被冻结,这属于“扩展”;两个七位数相乘模型其实能做,但调用计算器更快更可靠,这属于“促进”(逐字稿 02:02–02:45)。Slides 第 5 页把场景与收益对应起来:当前信息→搜索→新鲜证据;精确计算→计算器或 Python→可靠执行;私有状态→账户 API→被授权的应用数据;外部动作→浏览器或 API→改变环境。
课堂互动部分补充了一批 ChatGPT 用例(逐字稿 04:00–05:52):写代码、渲染 Blender、生成图像、商品推荐(需要网络搜索或直连电商 API)、渲染 LaTeX 并生成 PDF、与 Slack 之类的系统交互。注意 LaTeX 一处课堂上有讨论:讲师表示不确定那究竟是工具还是前端渲染,后来确认它会创建 PDF,才归为工具。这个细节提醒我们:判断某能力是“工具”还是“界面效果”,要看是否有外部程序被调用。
3.2 典型工具与 finish 的两种实现
Slides 第 8–12 页给出五个具体例子,均保留:
- 文本回复:
finish("Accra is the capital of Ghana.")。幻灯片明确标注这是 harness 控制动作(CONTROL),不是外部程序。 - 信息检索:
search_web("site:cmu.edu announced today")→ 三条匹配新闻。 - 代码执行:
execute_code("sum([18,23,41,54])/4")→ 34.0。 - 图像生成:
generate_image("watercolor robot studying in a library")→ generated_image.png。 - 自定义函数:
create_grocery_cart(["bananas","milk","coffee"])→ Cart C17 · 3 items · $31.42。
逐字稿补充了两点:其一,文本回复在智能体循环里可以用两种方式实现——单独的 finish 工具,或者“模型决定不调用工具就直接结束循环”(逐字稿 06:41–07:02)。其二,图像生成的特殊之处在于模型会在调用前大幅改写查询,历史上甚至能从下载图片时隐约看到生成器实际收到的描述(逐字稿 09:16–09:38)。这提示“决定查询内容”本身就是工具有效性的一部分。
3.3 代码作为元工具
Slides 第 14 页:代码在一次动作中组合控制流、库与多个操作。Slides 第 15 页引用 CodeAct,第 16 页给出结果:在展示的子集中,代码在 8/8 个模型上取得最佳成功率;在 7/8 个模型上使用最少轮数;在全部 17 个模型上这两个计数都是 12/17。逐字稿用一个具体例子解释“元工具”的意思:把“面包师烤了 200 条面包,还剩多少条”拆成赋值工具、减法工具等函数调用树,再引入循环等控制流(逐字稿 10:55–11:49)。逐字稿还给出一个经典对比任务——确定购买 Kodak 1 手机最具成本效益的国家(考虑美国、日本、德国、印度),串行方式要反复调用汇率、价格、税费工具,而写一段程序即可一次完成(逐字稿 12:44–13:30)。逐字稿转述 CodeAct 的核心结果是成功率上升、平均交互轮数下降,且这一优势甚至出现在传统上不需要代码的工具使用任务上(逐字稿 13:55)。
代价在 Slides 第 17 页列得很清楚:表达力强(循环、变量、库,适合多步数据操作与组合);更难约束(动作空间宽,校验精度低于窄类型函数);影响更大(文件、网络、进程),因此需要沙盒、资源限制、权限与审计日志。逐字稿的课堂问答补充了具体风险:可能写出无限循环需要额外处理;可能引入被攻破的库从而危及整个系统;更容易占用内存、磁盘、CPU(逐字稿 14:41–15:43)。
3.4 从 token 到分发:工具调用的机制链路
Slides 第 19 页把文本续写与工具续写并列:文本续写是“The weather is sunny.”,工具续写是 <tool_call> get_weather(...),并注明“模型请求动作,harness 执行”。逐字稿补充了一个重要观察:ReAct 循环如今不再表示为独立代码,而更像是单次补全——同一份输出里既可能有给用户的文本,也有工具调用;若使用推理模型,还可能先有思维 token,再有消息,再有工具调用(逐字稿 16:35–18:05)。
Slides 第 20 页说明消息如何变成模型输入:API 层的 system/user/assistant 角色由 chat template 序列化为单一输入序列(以 Qwen 格式为例)。Slides 第 21 页给出工具定义 JSON(get_weather,参数 city 为 string 且 required)并说明 harness 同时发送 messages 与 tool schemas。Slides 第 22 页给出“定义进、调用出”:提示词含 <tools> 块,模型发出 <tool_call> 块,API 响应附带唯一 call ID。
Slides 第 23 页是重要的一页:同一份 schema,不同模型有不同序列化协议。Qwen 3.8 用 function/parameter 标签;Mistral Small 4 用 [TOOL_CALLS] 控制 token 加 call ID;DeepSeek V3.2 用 DSML invocation 块(<|DSML||function_calls> 等)。幻灯片结论是:一份 schema,模型特定的序列化与解析。逐字稿补充两处实践含义:不能假设为 DeepSeek 写的解析代码能直接用于 Qwen;微调时应当匹配模型已被训练过的工具调用格式;好消息是这类格式在 Hugging Face 的 apply chat template 一类函数中已实现(逐字稿 21:02–23:20)。逐字稿中还出现了一个关于“这些特殊 token 是否必须存在于预训练词表”的问答,讲师的回答倾向于:通常并非必须在全网预训练阶段就存在,更典型的是在中间训练阶段引入,之后再做强化学习(逐字稿 18:05–19:10)。这一细节涉及训练流程,具体表述以原视频为准。
Slides 第 24 页给出 OpenHands 的分发流程:初始化时注册(resolve_tool(spec, state) → 名称到 ToolDefinition(schema · Action · executor)的 tools_map);每次模型调用时分发(解析 {name, args} → 查表 → 用 action_from_arguments(args) 校验 → executor(action) → 返回 ObservationEvent(call_id))。逐字稿补充了两类失败:校验失败(模型给出错误的工具调用)和执行失败(例如 Python 工具接受任意字符串,但真正运行时才报错)(逐字稿 24:15–25:05)。
Slides 第 25 页说明结果按 call ID 返回:assistant 的 tool call 带 "id": "call_123",tool 结果消息带 "tool_call_id": "call_123",并注明这同样适用于并行调用。逐字稿给出一条容易踩坑的实践细节:部分提供方(讲师以 Anthropic 为例)在出现“工具调用没有匹配的工具结果”时会直接拒绝该历史并停止生成,这在程序崩溃后恢复的场景中会造成麻烦(逐字稿 25:33–26:47)。此说法属于讲师经验陈述,未在幻灯片中给出,使用时宜标注为课堂经验。
3.5 约束解码:保证形式,不保证正确
Slides 第 27 页给出畸形工具调用的例子:JSON 缺少最后的右括号,harness 无法解析。Slides 第 28 页列出四类约束:语法(valid JSON)、形状(expected fields)、类型(city 是 string)、取值(units 是 C 或 F),并明确边界:约束保证形式,不保证真值、权限、工具选择或任务成功。
Slides 第 29 页给出 JSON Schema 示例,含 type、properties、enum、required 与 additionalProperties: false,并列出其特点:用于描述 JSON 数据的词汇表、类型/必填字段/允许取值、机器可读的验证规则。Slides 第 30 页用两棵派生树对比:{"city":"Pgh","units":"F"} 可由 unit → "C" | "F" 派生;{"city":"Pgh","units":"K"} 不行,因为 K 不能从 unit 派生(注意幻灯片设定不接受 Kelvin 作为温度单位)。
Slides 第 31 页解释下推自动机(PDA):有限控制记录文法规则中的局部位置,栈记忆任意深度的嵌套。逐字稿给出更通俗的对照:正则文法可用有限状态自动机解析,而 JSON Schema 不能只用正则文法表达,需要上下文无关文法,进而需要带栈的 PDA;做法是在从左到右生成输出时逐步验证(逐字稿 29:22–32:38)。
Slides 第 32 页给出关键工程细节:语法检查发生在分词之下。先编译一次(unit → "C" | "F" 编译到字节级 PDA),再对每个候选 token 检查:token t₁: "F"} 解码为字节 22 46 22 7D,对全部字节跑 advance(bytes),保留或掩蔽。幻灯片特别提醒:一个 token 可能跨越多个语法终结符,也可能停在某个终结符中间,因此不能把 token 边界当作语法边界。
Slides 第 33 页给出缓存 token 掩码的四步流程:1)解析前缀,对已输出字节推进持久 PDA 栈;2)取缓存决策,栈顶节点索引预计算的、与上下文无关的 token 有效性;3)检查少数派,把上下文相关的候选 token 对完整栈运行,并在匹配的栈之间求并集;4)掩蔽并继续,合并决策、掩蔽 logits、采样 token、更新 PDA 栈。Slides 第 35 页总结加速来源:缓存处理大多数 token、持久栈支持分支、CPU 工作与 GPU 推理重叠。逐字稿补充了 token 掩蔽的直观理解:对每个候选 token 看文法是否允许,允许得 1,不允许设为负无穷,再重新归一化(逐字稿 33:05–33:31),并提到这套方法被广泛用于推理库、由本校机器学习系的人开发(逐字稿 32:38)。
一个重要的边界情形(逐字稿 34:27–35:17):即使有约束解码,仍可能拿不到格式良好的工具调用——当 token 预算用完时,输出可能仍在一条有效路径上但没有到达终态。讲师称这是很罕见的难题,并把“在推理栈里实现按剩余 token 数截断”当作可选的加分方向提及;这类具体做法未在幻灯片中给出,属于课堂提议,不宜当作官方要求。
3.6 REST 与 MCP
Slides 第 37 页:库暴露的是进程内 API,调用方与被调函数共享同一进程,Python 提供名称、参数、类型与返回类型,但还不能远程调用——网络客户端仍需要地址、协议、序列化与认证。示例 weather_lib.py 定义了 get_weather(city, units: Literal["C","F"]="F") -> Weather。
Slides 第 38 页:REST API 通过 HTTP 暴露函数,示例以 FastAPI 绑定端点并记录 API key 头(X-API-Key)。Slides 第 39 页说明 REST 服务器发布 OpenAPI 描述:OpenAPI 描述 HTTP 操作,内嵌 JSON Schema 描述其取值。
Slides 第 40 页:编码智能体常用 curl 直接调用 REST API,并给出示例命令;同时指出风险——有 shell 权限的智能体也可能读取或滥用该密钥。幻灯片原话是:直接 REST 访问很简单,但智能体的 shell 会拿到 API 凭证。
Slides 第 42 页说明 MCP 连接 host 与 servers 的拓扑:本地 stdio(文件系统服务器)、远程 HTTP(Sentry 服务器),并明确 MCP 是面向智能体的替代接口,而不是调用 REST API 的必要条件。Slides 第 43 页说明 FastMCP 默认把每个 OpenAPI 路由转换成可发现的 MCP 工具。Slides 第 44 页强调用分离的凭证启动 MCP:UPSTREAM_API_KEY 授权 API 调用,MCP_API_KEY 保护 MCP 端点;并注明静态 token 仅用于教学/开发,生产应校验 JWT 或使用 OAuth。Slides 第 45 页给出关键机制——凭证中介:服务器接受一个凭证并在上游使用另一个凭证,模型看不到任何一个秘密。
逐字稿对这部分补足了动机:讲师起初认为有了 API 就不需要 MCP,后来认可的核心区别是安全层——上游 GitHub token 给 MCP 服务器,而不是给智能体;给智能体的是 MCP API key,这样即使泄露也相对无害,否则智能体可能把 GitHub token 推到公开仓库(逐字稿 39:00–42:51)。逐字稿还提到 MCP 注册表与第三方目录站点的存在(逐字稿 44:11–44:39),这类具体站点与数量属于口头提及,宜按待核处理。
Slides 第 46 页给出对照表:两者共享名称、描述与结构化输入的 JSON Schema;发现方式不同(取 OpenAPI 文档 vs 运行时 tools/list);调用方式不同(HTTP 动词+路径+参数 vs 经 MCP 传输的 tools/call);认证不同(客户端认证到 API vs 客户端认证到 MCP、上游认证分离);范围不同(描述 HTTP 操作 vs 还支持 resources、prompts 与 extensions)。
3.7 编排并发
Slides 第 48 页给出串行成本:生成 0.8s + 天气 1.2s + 生成 0.8s + 日历 0.9s + 生成 0.8s + 航班 1.1s + 生成 0.8s ≈ 6.4 秒。Slides 第 49 页给出并行成本:两个生成阶段加最慢的工具,即 2 × 0.8 + max(1.2, 0.9, 1.1) ≈ 2.8 秒。这些是幻灯片给出的示意数值,用于说明结构差异,不是实测基准。
Slides 第 50 页给出并行前提:可安全并行的是“匹兹堡天气 / 读今天的日历 / 查航班状态”;必须串行的是“找客户 ID / 用 ID 取订单 / 退款选中的订单”。结论是只并行独立且可安全并发的调用。Slides 第 51 页给出实现要点:用 asyncio.gather(..., return_exceptions=True) 并发执行,并在结果乱序返回时保留 call ID。
逐字稿补充了两点:其一,并行调用通常通过一次智能体响应里放多个工具调用块实现,执行上一般真并发(逐字稿 45:25–47:01)。其二,讲师提出一个有趣的观察——更新、更强的模型在并行工具调用上表现好得多,原因之一是强化学习对任务时长施加重惩罚,迫使模型并行化;这一点是课堂推论(逐字稿 47:01–48:37),不应当作已被幻灯片确认的结论。
3.8 评估
Slides 第 53 页列出 Berkeley Function Calling Leaderboard V4 的维度:单轮(simple、multiple、parallel、multiple-parallel)、多轮(base、missing function、missing parameter、long context)、智能体(web search、memory)、鲁棒性(幻觉测量、格式敏感性)。
Slides 第 54 页给出四层“评估整栈”的框架(保留示例指标):选择(工具对否,precision/recall,不需要执行,典型失败是缺失或多余调用);参数(值对否,AST/schema 匹配,不执行,典型失败是字段或值错误);轨迹(顺序对否,序列成功率,通常要执行,典型失败是依赖错误);任务(目标达成否,端到端成功,要执行,典型失败是看似合理的错误答案)。
Slides 第 55 页给出三个运营维度:效率(延迟、调用数、token、成本)、可靠性(超时、重试、部分失败)、安全性(策略、权限、副作用)。幻灯片特别指出:一个正确的智能体仍可能慢到或贵到不可用;可靠性评估应在真实提供方行为下报告任务成功率;安全性需要测试对抗性输出和高后果动作。
Slides 第 56 页给出运营故障的归因表:模型(错工具、坏参数、忽略结果)、harness(解析、认证、校验、ID 不匹配)、提供方或工具(超时、限流、执行错误)。结论是生产评估既需要基准准确率,也需要运营失败率。
Slides 第 57 页是 OpenRouter 提供方工具调用错误率图(来源标注为 2026 年 8 月 27 日)。逐字稿提到该图针对同一个模型的多个提供方,错误率差异很大(逐字稿 51:43–52:14),并讨论了原因:量化级别(FP8 与 FP4 的差别)、投机解码是否有损、各提供方是否实现约束解码、以及提供方本身的可靠性(逐字稿 52:40–55:49)。需要强调:图上的具体数值在本笔记的文本提取中无法确认,属“待核”;上述原因分析是课堂讨论,且讲师对部分点使用了“可能”“我不确定”等措辞,不应写成确定结论。
四、公式与符号的假设
本讲没有需要推导的数学公式,出现的都是成本估算式与形式语言记号,因此这里列出的是“读法与其背后的假设”。
时间估算(Slides 第 48、49 页)
- 串行总时长 ≈ Σ(每次生成) + Σ(每个工具)。
- 并行总时长 ≈ 2 × 0.8 + max(1.2, 0.9, 1.1) ≈ 2.8 秒。
- 符号:0.8s 为一次生成的示意时长;1.2/0.9/1.1s 分别为天气/日历/航班工具的示意时长。
- 假设:这些是教学用示意数值而非实测;并行要求调用之间不存在依赖;每次“生成”时长相同;工具之间可真正并发且不会互相限流。若实际提供方限流或工具共享资源,该估算不成立。
约束解码的掩蔽规则(Slides 第 34 页图;逐字稿口头描述)
- 讲师口头描述为:合法下一 token 得 1,非法得 0,把非法项设为负无穷,再重新归一化,使概率只落在合法 token 上。
- 待核:Slide 34 是图示,其具体公式与坐标含义仅凭文本提取无法确认,本笔记不给出公式形式。
形式语言记号(Slides 第 30、32 页)
unit → "C" | "F":产生式写法,表示 unit 可派生为 C 或 F。幻灯片明确把 K 排除在温度单位之外。advance(bytes):PDA 对字节序列推进状态的函数,输入是 token 解码后的字节(如22 46 22 7D对应"F"})。- 假设:文法先编译一次到字节级 PDA;检查发生在分词之下;因此 token 边界不能当作语法边界。
“选择—参数—轨迹—任务”四层(Slides 第 54 页)
- 这不是公式,而是一个评估分解。其隐含假设是:某些指标(选择、参数)无需真正执行即可测量,而轨迹与任务指标通常需要执行。
五、常见误区
- 以为约束解码能保证正确。Slides 第 28 页明确:约束只保证形式,不保证真值、权限、工具选择或任务成功。逐字稿的 Python 例子更直白:字符串可以被解析为 Python,但程序本身仍可能是错的。
- 以为工具调用格式是通用的。Slides 第 23 页的三家格式并列说明不能跨模型复用解析逻辑;逐字稿补充微调时必须匹配已有格式。
- 以为代码越多越好。代码表达力强,但动作空间宽、校验不精确、影响面大,需要沙盒、资源限制、权限与审计(Slides 第 17 页)。
- 以为 MCP 只是“换个方式调 API”。Slides 第 46 页的对照表与第 45 页的凭证中介说明:MCP 的核心差异之一是认证与凭证分离,而不是调用语法。
- 以为工具结果可以随便丢弃或错配。Slides 第 25 页强调 call ID 匹配,尤其在并行场景;逐字稿补充缺少匹配结果时某些提供方会拒绝该历史。
- 以为并行就是“把所有调用一起发出去”。Slides 第 50 页给出明确反例链:找 ID → 取订单 → 退款。
- 以为准确率就是全部。Slides 第 55 页:正确但慢或贵的智能体可能不可用;还需要可靠性(超时、重试、部分失败)和安全性(策略、权限、副作用)。
- 以为同一模型在不同提供方表现一致。Slides 第 57 页与逐字稿讨论表明背后有量化、解码算法、约束解码实现与可靠性等差异(具体数值待核)。
- 把 finish 当成外部工具。Slides 第 8 页把它标注为 harness 控制动作。
- 把攻击面只放在模型上。Slides 第 56 页的归因表把故障分给模型、harness、提供方或工具三方。
六、复习问题
- 用“扩展”和“促进”两个类别,给下面四个能力归类并说明理由:查今天的航班状态;把两个七位数相乘;查询你自己的订单记录;在网页上完成一次购买。
- Slides 第 8 页把
finish标为 CONTROL 而不是 TOOL。为什么这个区分对 harness 实现有意义?请给出两种实现文本回复终止的方式。 - 为什么说代码是“元工具”?请用逐字稿中的面包师例子说明函数调用树的构成,并说明引入循环后表达力为什么进一步增强。
- 除了表达力,代码作为工具带来哪三类代价?各自对应什么样的防护措施(Slides 第 17 页)?
- 请按顺序复述从“messages + tool schemas”到“ObservationEvent(call_id)”的完整链路(Slides 第 21–25 页),并指出至少两个可能失败的环节。
- 同一份
get_weatherschema,在 Qwen 3.8、Mistral Small 4、DeepSeek V3.2 中的序列化有何不同?这对工程实现意味着什么(Slides 第 23 页)? - 为什么说“token 边界不能当作语法边界”?请用 Slide 32 中
t₁: "F"}的例子说明。 - 请复述缓存 token 掩码的四步流程,并解释加速来自哪里(Slides 第 33、35 页)。
- 约束解码“保证形式不保证正确”,请分别举一例说明“形式对但取值不可接受”和“形式对但语义错误”的情形。
- 直接 REST 调用与 MCP 在发现、调用、认证、范围四个方面分别有何不同?为什么凭证中介能降低风险(Slides 第 45、46 页)?
- Slides 第 48、49 页的 6.4 秒与 2.8 秒分别是怎么算出来的?这个估算依赖哪些假设?
- 判断下列三组调用能否并行:查天气 / 读日历 / 查航班;找客户 ID / 取订单 / 退款;查天气 / 根据天气决定是否带伞 / 发送提醒。
- 用“选择—参数—轨迹—任务”四层评估一个只会调用错误但格式正确工具的模型,指出每层的典型失败(Slides 第 54 页)。
- 除准确率外,还要报告哪些运营维度?请分别给出一个指标例子(Slides 第 55 页)。
- 如果某个提供方的工具调用错误率明显高于其他提供方,可能的原因有哪些?其中哪些是讲师明确标为“可能/不确定”的(Slides 第 57 页;逐字稿 52:40–55:49)?
- 课堂提到一个连约束解码也可能失效的情形。请描述该情形,并说明为什么它属于 token 预算问题而非文法问题。
- 在什么情况下你应当选择“窄类型函数”而不是“代码执行”作为工具接口?请结合 Slides 第 5 页的“收益需超过延迟、成本、失败与风险”来判断。
七、术语对照(便于回看幻灯片)
- 工具(tool):语言模型调用外部计算机程序的接口(Slide 3)。
- 扩展 / 促进(Extend / Facilitate):两类工具收益(Slide 4)。
- 元工具(meta-tool):指代码,因其能组合控制流、库与多操作(Slide 14)。
- 工具调用(tool call):模型输出的动作请求,由 harness 执行(Slide 19)。
- chat template:把角色化消息序列化为单一模型输入序列(Slide 20)。
- call ID:把工具结果匹配回调用的标识,含并行场景(Slide 25)。
- 约束解码(constrained decoding):在解码时掩蔽不合文法的 token(Slides 第 27–35 页)。
- JSON Schema:描述 JSON 数据的机器可读验证规则(Slide 29)。
- 下推自动机(PDA):有限控制加栈,可解析上下文无关文法(Slide 31)。
- OpenAPI:描述 HTTP 操作并内嵌 JSON Schema(Slide 39)。
- MCP:面向智能体的替代接口,含独立凭证与工具发现(Slides 第 42–46 页)。
- 凭证中介(credential brokering):服务器接受一个凭证、在上游使用另一个凭证(Slide 45)。
- 并行工具调用:独立调用共享一次生成与一次等待(Slides 第 48–51 页)。
八、待核事项
- Slides 第 34 页(token masking 图)与第 2 页(Basic idea)在文本提取中几乎为空/极简,需对照官方 PDF 视觉核验。
- Slides 第 6 页(Examples of tools)为纯图清单,文本提取未保留条目,需对照 PDF。
- Slides 第 16 页的 CodeAct 结果描述中“展示的子集”具体范围需对照原论文与 PDF 图示。
- Slides 第 57 页错误率图的具体数值与模型名称(逐字稿提到 GLM 5.3)需对照 PDF 与来源标注。
- 逐字稿中若干口头提及(MCP 注册表、第三方目录站点数量级、Anthropic 拒绝无匹配结果的历史、按剩余 token 截断的加分设想、强化学习迫使并行化)均非幻灯片内容,属课堂陈述,引用时应标注出处为逐字稿。
- 逐字稿为机器翻译、状态“待审核”,个别术语(如“编解码器”“next grammar”“Xgrammer”)存在明显转写误差,正文已按 Slides 的 XGrammar 等写法处理,具体措辞以原视频为准。
九、给定资料中的官方来源链接
- 课程主页:https://www.cmu-agents.com/
- 课程日程与阅读:https://www.cmu-agents.com/#schedule
- 作业与项目要求:https://www.cmu-agents.com/#assignments
- Assignment 1 · Harness:https://github.com/cmu-agents/assignment-1
- Assignment 2 · Eval:https://github.com/cmu-agents/assignment-2
- 课程视频(Lecture 2):https://www.youtube.com/watch?v=jXChFB4JSyw&list=PLSN0qpDfUvTM&index=2
- 官方课程日程:https://www.cmu-agents.com/#schedule
- Lecture 2 slides:https://www.cmu-agents.com/slides/lecture-02-tool-use.pdf
从 Token 预测到行动:CMU 11-768 第二讲中的工具使用机制
来源:平台字幕与官方 Slides。内容已由用户审核确认。
一个问题:语言模型为什么会“需要”工具
语言模型本质上是一个 token 预测机器。它可以在参数中存储大量知识,也可以做相当复杂的推理,但它有一个根本限制:它只能生成文本,不能直接与外部世界交互。CMU 11-768 Fall 2026 第二讲的核心问题正是从这里出发的:如果我们希望语言模型不只是回答问题,而是真正去做事情——查天气、运行代码、生成图像、调用购物 API——我们需要什么样的机制?
Slides 第 3 页给出了工具的定义:工具是语言模型调用外部计算机程序的接口。这个定义的关键在于“接口”二字。模型负责提出调用请求(propose),而外部软件负责决定是否执行以及如何执行(decide whether and how to execute)。模型本身不执行任何东西,它只是生成一段结构化的文本,告诉 harness“我想调用这个工具,参数是这些”。
学习者解释:可以把工具调用理解为一种“委托”。模型像一个只会写便条的助理,便条上写着“请帮我查一下匹兹堡的天气”。真正去查天气的是另一个程序。模型的价值在于它能根据上下文决定写什么便条、什么时候写、参数填什么。
工具的两个好处:扩展与促进
Slides 第 4 页引用了 Wang et al. 的 COLM 2024 论文,把工具的好处分为两类:
扩展(Extend) :让模型做到它从根本上做不到的事情。比如获取四个月前的日期——模型的参数是冻结的,它不可能知道训练截止之后发生的事情。又比如访问用户的私有账户信息,这些数据从未出现在训练语料中。
促进(Facilitate) :让模型更可靠或更高效地完成它本来就能做的事情。讲者在课堂上举了一个例子:语言模型如今其实可以很好地做数学,但如果你让它们把两个七位数相乘,它们需要做大量推理,花很长时间。计算器可以瞬间完成。这就是“促进”——不是模型做不到,而是外部程序做得更好。
Slides 第 5 页进一步把工具使用场景分为四类:
| 需求 | 示例工具 | 好处 |
|---|---|---|
| 当前信息 | Search | 新鲜证据 |
| 精确计算 | Calculator 或 Python | 可靠执行 |
| 私有状态 | Account API | 授权的应用数据 |
| 外部行动 | Browser 或 API | 改变环境 |
Slide 第 5 页底部有一句重要的话:只在工具的好处超过延迟、成本、失败和风险时才调用工具。这意味着工具调用不是免费的——每次调用都有开销,也可能失败。
从 ChatGPT 看工具的典型形态
Slides 第 6 到 12 页展示了 ChatGPT 中常见的工具类型。讲者在课堂上让同学们列举 ChatGPT 能做什么,得到的答案包括:写代码、渲染 LaTeX、生成图像、推荐产品(需要网络搜索)、与 Slack 交互等。
Slide 第 8 页介绍了一个特殊的东西:finish(text)。这不是一个外部程序,而是 harness 的控制动作。它的作用是返回最终文本并停止智能体循环。讲者指出,文本回复可以用两种方式实现:一种是显式地有一个 finish 工具;另一种是如果智能体决定不调用任何工具,循环就自然结束。
Slide 第 9 页展示了 search_web(query)——信息检索工具。讲者在课堂上特别提到了 RAG(检索增强生成)。他说,很多人觉得“RAG 已死”,但实际上 RAG 已经变得如此普遍,以至于人们甚至没有意识到自己还在用它。搜索网页、检索信息、基于检索结果生成答案,这已经成为聊天应用的标准配置。
Slide 第 10 页展示了 execute_code(code)——代码执行工具。Slide 第 11 页展示了 generate_image(query)——图像生成工具。讲者在这里指出了一个有趣的细节:调用图像生成 API 之前,语言模型会大幅扩展用户的查询。用户说“画一个在图书馆学习的水彩机器人”,模型实际发送给图像生成器的查询可能完全不同。Slide 第 11 页的图示中,用户查询和实际发送的查询确实不一样。
Slide 第 12 页展示了 create_grocery_cart(items)——自定义函数。这是应用特定的能力,通过一个类型化的调用来暴露。讲者举的例子是“给我买香蕉、牛奶和咖啡”,智能体创建一个购物车并调用类似 Instacart 的 API。
代码作为一种“元工具”
Slides 第 13 到 17 页讨论了程序化工具调用(Programmatic Tool Calling)。这是本讲中一个重要的递进。
传统方式是:你给模型一个 API 函数列表,模型每一步调用一个 API。但代码是一种特殊的 API,因为代码极具表现力。Slide 第 14 页引用 Wang et al. 的论文指出:代码在一个动作中组合了控制流、库和多个操作。
讲者在课堂上用了一个例子来说明这一点。假设任务是“确定购买智能手机型号 Kodak 1 最具成本效益的国家,考虑美国、日本、德国和印度”。如果用传统的逐步 API 调用方式,你需要:查德国汇率 → 查手机价格 → 转换和计算税费 → 再查汇率 → 再查价格……一步一步走。但如果你写代码,你可以直接写一个单一程序来执行这个任务。
Slide 第 15 页引用 CodeAct(Wang et al., ICML 2024)展示了程序化组合的概念。Slide 第 16 页给出了 CodeAct 的结果:在展示的子集中,代码在 8/8 个模型上取得了最佳成功率;在 7/8 个模型上使用了最少的轮数;在全部 17 个模型上,这两个计数都是 12/17。
但代码不是没有代价的。Slide 第 17 页列出了代码作为高功率工具的三个特征:
- 表达力强:循环、变量、库。适合多步数据操作和组合。
- 难以约束:动作空间广泛,验证不如窄类型函数精确。
- 影响更大:文件、网络、进程。需要使用沙盒、资源限制、权限和审计日志。
讲者在课堂上问学生:代码调用可能有什么缺点?学生回答了“可能卡住”(无限循环)和“安全问题”(引入被攻破的库)。讲者确认了这些担忧,并指出这是智能体安全讲座中会进一步讨论的内容。
学习者解释:代码作为工具的核心矛盾在于“能力越大,责任越大”。一个窄类型函数(如
get_weather(city: str))的动作空间非常有限,验证起来很简单。但一段 Python 代码可以读写文件、发网络请求、启动进程——你很难在执行之前完全验证它要做什么。
工具调用的底层机制
Slides 第 18 到 25 页讲述了提供工具的机制。这部分是理解工具调用“到底发生了什么”的关键。
工具调用就是 token
Slide 第 19 页给出了一个简洁的对比:文本续写是“The weather is sunny.”,工具续写是 <tool_call>get_weather(...)。模型请求一个动作,harness 执行它。
Slide 第 20 页展示了消息如何变成模型输入。API 层面有 system、user、assistant 三种角色,它们被 chat template 序列化为一个模型输入序列。比如 Qwen 的格式是 <|im_start|>system ... <|im_end|>。
Slide 第 21 页展示了工具如何为请求添加结构。工具定义是一个 JSON schema,告诉模型函数名是 get_weather,参数是 city,类型是字符串,并且是必需的。这个 schema 通过 tools 参数传递给 API。
Slide 第 22 页展示了“定义进去,工具调用出来”的过程。提示词包含 <tools> 部分,模型输出 <tool_call> 部分。API 响应会附加一个唯一的 call ID。
不同模型的工具调用格式
Slide 第 23 页展示了三个模型的不同工具调用格式:
- Qwen 3.8:使用
<function=get_weather>和<parameter=city>标签 - Mistral Small 4:使用
[TOOL_CALLS]控制 token 加 JSON - DeepSeek V3.2:使用 DSML(DeepSeek Markup Language)调用块
讲者在课堂上强调:一个 schema,模型特定的序列化和解析。你不能假设为 DeepSeek 写的解析代码能直接用于 Qwen。好消息是,这些已经在 Hugging Face 的 apply_chat_template 函数中实现了。
Harness 如何分发工具调用
Slide 第 24 页以 OpenHands 为例展示了工具调用的分发过程:
- 初始化时注册:工具规格(如 BashTool)被解析为 ToolDefinition,包含 schema、Action 和 executor。名称到定义的映射存储在
tools_map中。 - 每次模型调用时分发:解析
{name, args}→ 查找tools_map[name]→ 验证action_from_arguments(args)→ 执行executor(action)→ 返回ObservationEvent(call_id)。
Slide 第 25 页强调了 call ID 的作用:助手工具调用中的 id 字段与工具结果消息中的 tool_call_id 字段匹配。这在并行工具调用中尤其重要——你需要知道哪个结果对应哪个调用。
讲者在课堂上提到了一个实际细节:Anthropic 的 API 如果一个工具调用没有匹配的工具结果,会直接失败。这意味着如果你的程序在工具执行过程中挂了,没有写出结果,恢复时会遇到问题。
约束解码:保证格式正确
Slides 第 26 到 35 页讨论了约束解码。这是本讲中技术含量最高的部分。
问题:格式错误的工具调用
Slide 第 27 页展示了一个格式错误的工具调用:JSON 缺少最后的右括号。harness 无法解析它。讲者说,他见过无数人试图手动修复缺失的括号,但你不应该那样做。
约束的层次
Slide 第 28 页列出了工具调用的四个约束层次:
- 语法(Syntax) :必须是有效的 JSON
- 形状(Shape) :必须有预期的字段
- 类型(Types) :
city必须是字符串 - 值(Values) :
units必须是 C 或 F
Slide 第 28 页底部有一句关键的话:约束确保形式——不是真理、权限、工具选择或任务成功。
JSON Schema 和上下文无关文法
Slide 第 29 页展示了 JSON Schema 的词汇:类型、必需字段、允许值、机器可读的验证规则。
Slide 第 30 页用树形结构展示了 schema-valid 和 schema-invalid 的区别。两者都是 JSON,但只有 "F" 能从 unit → "C" | "F" 推导出来,"K" 不能。
Slide 第 31 页引入了下推自动机(Pushdown Automaton)。有限状态自动机(用于正则文法)无法解析上下文无关文法,但下推自动机可以——它给正则文法加了一个栈。状态记录当前在文法规则中的局部位置,栈记住任意深度的嵌套。
XGrammar 和 token 掩码
Slide 第 32 页展示了文法检查发生在 tokenization 之下。一个 token 可能跨越多个文法终结符,或者在某个终结符中间结束——所以 token 边界不能被当作文法边界。XGrammar(Dong et al., MLSys 2025)把文法编译为字节级的 PDA,然后检查每个候选 token。
Slide 第 33 页展示了缓存 token 掩码生成的四个步骤:
- 解析前缀:在已发出的字节上推进持久 PDA 栈
- 获取缓存决策:栈顶节点索引预计算的上下文无关 token 有效性
- 检查少数:对上下文相关的候选 token 运行完整栈
- 掩码并继续:合并决策,掩码 logits,采样 token,更新 PDA 栈
Slide 第 34 页展示了 token 掩码的效果。Slide 第 35 页解释了速度来源:缓存处理大多数 token,持久栈支持分支,CPU 工作与 GPU 推理重叠。
讲者在课堂上说,XGrammar 是由 CMU 机器学习系的人开发的,现在在所有 LM 推理库中被广泛使用。如果你不喜欢算法,那就庆幸有人在替你解决这个问题。
什么时候约束解码也不够
讲者在课堂上提了一个“快速小测验”:什么时候即使有约束解码也无法得到格式良好的工具调用?答案是:当你用完 token 时。模型只能生成这么多 token,你可能仍然在通过自动机的有效路径上,但不在最终状态。
REST API 和 MCP
Slides 第 36 到 46 页讨论了两种暴露工具的方式。
REST API
Slide 第 37 页展示了库 API:调用者和函数共享一个进程,Python 提供名称、参数、类型和返回类型。但库 API 还不能远程调用——网络客户端还需要地址、协议、序列化和认证。
Slide 第 38 页展示了 FastAPI 如何把库函数绑定到 REST 端点。@app.get("/weather", operation_id="get_weather") 装饰器让 weather 函数变成一个 HTTP 端点,APIKeyHeader 提供认证。
Slide 第 39 页展示了 REST API 服务器发布 OpenAPI 描述。OpenAPI 描述 HTTP 操作,嵌入的 JSON Schema 描述其值。
Slide 第 40 页展示了编码智能体常用 curl 调用 REST API。但这里有一个问题:智能体的 shell 会收到 API 凭证。
MCP:模型上下文协议
Slide 第 42 页展示了 MCP 的基本架构:MCP 主机(AI 应用)连接到多个 MCP 服务器。本地服务器通过 STDIO 连接,远程服务器通过 HTTP 连接。
Slide 第 43 页展示了 FastMCP 如何把 OpenAPI 操作投影为 MCP 工具。FastMCP.from_openapi() 默认把每个 OpenAPI 路由转换为可发现的 MCP 工具。
Slide 第 44 页展示了 MCP 的凭证分离:UPSTREAM_API_KEY 授权 API 调用,MCP_API_KEY 保护 MCP 端点。讲者在课堂上问:为什么要用 MCP 而不是直接调用 API?答案是安全性。如果你把 GitHub token 给了智能体,智能体可能把它推送到公开仓库。但如果你只给智能体 MCP API key,真正的凭证保留在 MCP 服务器上。
Slide 第 45 页展示了凭证代理:MCP 服务器接受一个凭证(MCP key),使用不同的凭证(upstream key)调用上游 API。模型看不到任何秘密。
Slide 第 46 页总结了 REST API 和 MCP 的区别:
| OpenAPI / HTTP API | MCP | |
|---|---|---|
| 共享 | 名称、描述、JSON Schema | 同左 |
| 发现 | 获取 OpenAPI 文档 | 运行时调用 tools/list |
| 调用 | HTTP 动词 + 路径 + 参数 | 通过 MCP 传输的 tools/call |
| 认证 | 客户端认证到 API | 客户端认证到 MCP;上游认证分离 |
| 范围 | 描述 HTTP 操作 | 还支持资源、提示和扩展 |
编排多个调用
Slides 第 47 到 51 页讨论了并行工具调用。
Slide 第 48 页展示了串行工具调用的成本:生成(0.8s)+ 天气(1.2s)+ 生成(0.8s)+ 日历(0.9s)+ 生成(0.8s)+ 航班(1.1s)+ 生成(0.8s)≈ 6.4 秒。
Slide 第 49 页展示了并行工具调用:一轮往返,三个结果。两个生成阶段加上最慢的工具:2 × 0.8 + max(1.2, 0.9, 1.1) ≈ 2.8 秒。
Slide 第 50 页给出了并行化的条件:只能并行化没有依赖关系的调用。匹兹堡天气、读取今天日历、查询航班状态可以并行;但查找客户 ID → 获取订单 → 退款选中的订单必须顺序执行。
Slide 第 51 页展示了并发执行的代码:使用 asyncio.gather 执行多个工具调用,return_exceptions=True 确保即使某个调用失败也不会影响其他调用。关键是在结果乱序完成时保留 call ID。
讲者在课堂上指出,更新、更贵的模型在并行工具调用方面做得好得多。这是因为强化学习在某种程度上迫使它们这么做——如果你对任务执行时长施加简洁性惩罚,模型就会学会并行调用。
评估工具使用
Slides 第 52 到 57 页讨论了评估。
Slide 第 53 页介绍了 Berkeley Function Calling Leaderboard V4 的维度:单轮(简单、多个、并行、多并行)、多轮(基础、缺失函数、缺失参数、长上下文)、智能体(网络搜索、记忆)、鲁棒性(幻觉测量、格式敏感性)。
Slide 第 54 页展示了评估整个技术栈的四个层次:
| 层次 | 问题 | 示例指标 | 需要执行? | 典型失败 |
|---|---|---|---|---|
| 选择 | 对的工具? | 精确率/召回率 | 否 | 缺失或多余调用 |
| 参数 | 对的值? | AST/schema 匹配 | 否 | 错误字段或值 |
| 轨迹 | 对的顺序? | 序列成功 | 通常 | 坏依赖 |
| 任务 | 目标达成? | 端到端成功 | 是 | 看似合理的错误答案 |
Slide 第 55 页列出了质量的操作维度:效率(延迟、调用次数、token、成本)、可靠性(超时、重试、部分失败)、安全性(策略、权限、副作用)。
Slide 第 56 页展示了操作层面的工具失败:模型(错误工具、坏参数、忽略结果)、Harness(解析、认证、验证、ID 不匹配)、提供商或工具(超时、速率限制、执行错误)。
Slide 第 57 页展示了 OpenRouter 提供商工具调用错误率。讲者在课堂上提到,同一个模型的不同提供商,错误率可能从 15% 到 0.01%–0.05% 不等。原因包括:解码算法不同、量化级别不同(FP8 vs FP4)、是否使用约束解码、提供商可靠性不同。
总结:工具使用是一个分层系统
Slides 第 59 页给出了本讲的总结:
- 能力:工具增加检索、执行、生成和应用动作。
- 机制:schema 进入提示词;模型协议发出调用;harness 验证、分发、按 ID 匹配结果。
- 约束:JSON Schema 和文法掩码保证形式——不是语义正确性。
- 接口:直接 REST 调用和 MCP 是暴露能力和管理凭证的替代方式。
- 系统:编排依赖关系和并发;评估选择、参数、结果、成本和操作失败。
讲者在课堂最后提到,这将会是第一个作业(Assignment 1 · Harness)中涉及的内容。学生需要构建自己的智能体并处理这些问题。
学习者解释:本讲的核心洞见可以概括为一句话——工具调用不是一个魔法,而是一个工程系统。从模型生成 token,到 harness 解析和验证,到外部程序执行,到结果返回和匹配,每一步都有失败的可能,每一步都需要设计。约束解码可以在形式层面保证正确性,但不能保证语义正确性。MCP 可以在安全层面提供凭证分离,但不能替代合理的工具设计。评估需要覆盖选择、参数、轨迹、任务以及效率、可靠性、安全性等多个维度。
官方来源链接
待核事项
- Slide 第 11 页的图示中,用户查询和实际发送的查询的具体差异需要对照官方 PDF 视觉核验。
- Slide 第 16 页的 CodeAct 结果数据需要对照论文原文核验。
- Slide 第 23 页中 Qwen 3.8、Mistral Small 4、DeepSeek V3.2 的版本号和格式细节需要对照官方 PDF 视觉核验。
- Slide 第 34 页的 token 掩码图示需要对照官方 PDF 视觉核验。
- Slide 第 57 页的 OpenRouter 提供商工具调用错误率数据需要对照官方 PDF 视觉核验。
- 讲者在课堂上提到的“MCP 注册表有约一百五十万个 MCP 服务器”这一数值需要核验,因为逐字稿中表述不够清晰。
- 讲者在课堂上提到的 XGrammar 由 CMU 机器学习系开发的表述需要核验。
CMU 11-768 Fall 2026 · Lecture 2 · Agent Capabilities 1: Tool Use|完整中文逐字稿
- 视频:官方视频
- 来源:平台英文自动字幕清洗稿的机器翻译;保留原段落时间戳。
- 状态:用户审核通过;中英文按完整语义段合并,每段保留首条原字幕时间戳。
- 说明:这是逐字稿,不是摘要;保留讲述顺序、例子与课堂互动。
正文
[00:00.640] 好。那么,大家好。呃,欢迎来到第二节课。今天,呃,今天我要讲的是语言模型智能体的工具使用。而且,呃,这是,你知道,关于智能体最基础的东西,呃,你知道,它让智能体与语言模型区别开来。 嗯,所以这里的基本想法是,呃,我们将要,嗯,一个工具基本上是一个接口,通过它,语言模型可以调用一个外部计算机程序。而且,呃,这是一个语言模型无法独自完成的事情,因为它本质上是一个预测 token 的机器。但这让你能够做,你知道,许多许多不同的事情。所以,你知道,你可以搜索,你可以调用一个 计算器,你可以调用一个浏览器,嗯,你可以调用 Python,你可以调用任意的 API,所以,呃,语言模型,就像你会看到的那样,工具调用的方法是标准化的,但你在工具调用下游所做的事情可以非常不同。所以基本上工具有两个,呃,好处,而所有这些都是来自我在网站上发布的一篇阅读材料, 如果你想回去读更多相关内容的话。呃,这是一篇综述,呃,是我和 Daniel 以及 Zoro Wong,我们的一个学生,一起写的。嗯,第一件事是扩展语言模型的能力。所以这是赋予语言模型去做某些它们从根本上无法做到的事情的能力。所以这可能是像访问
[01:40.079] 语言模型,嗯,你知道,动作空间之外的信息或动作。第二件事是,呃,促进语言模型。所以我说这个的意思是,这是语言模型从根本上可以做到的事情,但如果你不要求语言模型去做,那就容易得多。 所以,嗯,有没有人能想出一个例子,或者我想我们这里已经有一个例子了。所以,比如语言模型从根本上无法做到的一件事,就是获取四个月前的日期之类的。所以它看到的最新的信息是,呃,来自四个月前的,然后它的参数被冻结了。所以如果不调用,你知道,一个外部函数,它就不可能知道那个。 另一方面,呃,属于促进范畴的某件事是,语言模型如今其实可以很好地做数学,但它们做数学比调用计算器要花长得多的时间,因为它们必须做推理,比如你让它们把两个七位数相乘,呃,它们会花很长时间才能做到, 而计算器可以非常快地做到这一点。所以这就是这两类基本类别。所以,嗯,更深入一点讲这些,呃,你可以做像查找当前信息这样的事情,嗯,这样做的好处是这给了你,你知道,新鲜的证据来,呃,为你的答案提供依据,呃,使用像计算器或 python 这样的东西做精确计算,这给了 你比使用语言模型本身更可靠或,以及更快速执行的能力。嗯,其他事情是,呃,访问私有状态。所以让模型访问比如关于用户的信息,这样它们可以,呃,基于用户状态来回应,嗯,或者,呃,对你的外部环境做出改变。所以这可能是像浏览或者调用一个 API。
[03:33.280] 所以,举一些这些的例子,嗯,如果我们想一想 ChatGPT,呃,ChatGPT 刚出来的时候,过去简直就只是文本输入、文本输出。它,你知道,它唯一能做的就是,呃,对你的查询给出文本回复。现在,它有点像是一个万能应用。它允许你做许多不同的事情。嗯,所以,比如,呃,有哪些 例子,呃,你知道,是你们现在使用 ChatGPT 的,呃,最主要的使用场景? >> 是的。 >> 写代码。好。所以,呃,像这样的事情你需要什么工具?呃,比如 cursor 或 codeex,我想它们可以调用,比如 >> 好,但那不是 ChatGPT,对吧,那是 cursor 或 codeex,是的,我意思是 ChatGPT,比如在 ChatGPT 界面里
[04:30.080] >> 它们可以用 blender,所以它们可以渲染 blender,好,东西,所以那是一个例子,嗯,某件需要执行代码,但也要以合适的格式显示它的事情。嗯,还有没有其他人做的其他例子?是的,只是网页,生成图像。 >> 生成图像。是的。所以那,那是在调用一个图像生成工具。还有别的吗? >> 是的。所以推荐产品,比如 blender 之类的。那对于这个,呃,你觉得它需要什么样的工具? >> 某种像 Google 或 Amazon 这样的网络搜索来找到。 >> 对。所以你可能需要比如任意网络搜索,或者你可能需要一个直接连到 Google 或 Amazon 之类的 API。是的。还有别的,比如更奇怪、更奇怪的例子吗?你惊讶于 ChatGPT 能够做的事情? >> 是的。 >> 你可以相当漂亮地渲染 latex。 >> 好。我把文件搞乱了,当我给你修 PDF >> 然后编译所有东西,这有时非常方便。 >> 对。Ren,它可以渲染 latex。嗯,其实我不知道这是一个工具,还是这只是一个前端界面的事情,但可能只是它在你的网页浏览器里被渲染了。
[05:52.160] >> 哦,它创建一个 PDF。所以,好。是一个工具。好。非常酷。是的。 >> 交互 >> 呃,与像 Slack 之类的东西交互。所以,那是另一个专门的 API。所以各种各样不同的事情。嗯,我,我有点把这些归类成一个清单,是我认为,嗯,最,呃,像典型工具的东西,而大多数其他工具都可以,有点,被归类到 其中的每一个里。所以第一个是,呃,文本回复。所以这是有点无聊的那个,它只是给你一个答案。嗯,在智能体,呃,像循环里,你可以用两种方式实现这个。顺便说一下,ChatGPT 现在是一个智能体了。呃,如果你,比如,如果对这一点有任何疑问的话,ChatGPT 不只是一个聊天应用。它是一个智能体,因为它进行,呃,迭代式的工具调用来 回答你的查询。所以那有点像是智能体的定义。嗯,但,呃,文本回复,你可以用两种方式实现这些。你可以实现这些的一种方式是,你可以有一个 finish 工具,它说:“好,我与用户交互完了,所以我就要结束了,然后输出一些文本。”另一种方式是,如果智能体决定不调用工具, 你就可以直接结束智能体循环。所以那有点是,呃,你知道,简单的,呃,你知道,最明显的一个。另一个极其常见的。嗯,所以所有,所有这些都是工具,所以,比如理论上它们全都可以被看作是一个 API,但,呃,只是为了再稍微分解一下它们。嗯,另一个是搜索网络,这是,你知道,从所有
[07:28.479] 这些不同的设置。嗯,有多少人听说过检索增强生成?大概每个人都听说过,每个在这里上过 NLP 课程的人,你知道,都听说过,但很多人。有多少人听说过类似“RAG 已死”这种说法?[嗤笑和笑声] 相当多的人。所以,在语言模型 圈子里一直有一种论调,认为检索增强生成是两年前的东西了,好像没人再关心它了。我在这里的观点是,一种检索上下文然后基于它生成答案的检索增强生成,已经变得如此平常,以至于人们甚至都没有意识到他们还在用它。所以,嗯,它其实活得很好,以至于人们以为它已经死了。嗯,但呃 基本上,你知道,搜索网页、检索信息,然后基于它生成答案,现在本质上已经成为这些应用程序中的常态。现在,嗯,所以这是另一个被非常非常广泛提供的工具,就像任何聊天界面一样。 另一个是代码执行,这是,呃,投入,你知道,一组代码来做计算或者类似这样的事情。对于计算以及我们谈到的所有其他东西非常有用。另一个常见的是,呃,拥有某种图像生成,呃,这,你知道,显然是 ChatGPT 中另一个非常流行的用例。嗯,这个有点
[08:56.320] 不同,因为就像我谈到的这里所有其他的,基本上,你知道,大多是与文本交互。嗯,这里这是与图像交互。一件有趣的事情是,呃,你会注意到这跟这里不是同一回事。 所以这就像是水彩机器人正在图书馆里学习,而查询实际上是不一样的。所以调用这些图像的一个重要部分实际上是决定要在里面放什么查询。所以语言模型在调用图像生成 API 之前,会真的真的扩展这个查询。我不知道你们现在还能不能在 ChatGPT 里看到这个,但以前你可以在聊天 GPT 里看到,当你下载图像时,嗯,它会有一个跟你给出的说明非常不同的说明文字,你可以隐隐约约地看到图像生成器发送给生成图像工具的查询是什么。然后还有各种各样的,你知道,自定义函数。所以,嗯,比如给我买,给我买香蕉、牛奶和咖啡。 嗯,所以,你知道,这可以为你创建一个购物车,呃,并调用类似 Instacart API 来做这件事。嗯,你基本上可以用所有这些工具想怎么玩就怎么玩,添加任何你想要的工具。好,所以有几种不同的方式来思考工具调用。
[10:27.040] 嗯,思考工具调用的第一种方式是,你提供一份,呃,50 或 70 个 API 函数的列表,智能体能够与这些函数交互,它可以调用这些 API,如果你这样做,基本上你所做的就是每一步调用一个 API,或者如果你在做并行工具调用,你调用多个 API 或者类似的事情,但代码是一种 特殊的 API,呃,因为代码极具表现力,你可以把代码看作一种元工具,对吧,所以在这个里面,我们有比如面包师烤了 200 条面包,他们还剩下多少条面包,这里是在调用一个赋值工具,一个赋值工具,这里是在调用一个减法工具,嗯,这里是在调用一个赋值工具,你 知道等等等等,所以基本上,嗯,我想很多人上过类似编程语言的课程,或者对编程语言有一些了解,但基本上你可以把每一段代码表达为这些函数调用的树,嗯,这些树也可以有循环和其他控制流在里面。所以它本质上 你知道,是一种非常丰富的调用工具的方式。嗯,所以你也可以引入外部库。所以这些现在就是你引入到你的系统中的自定义 API。所以,嗯,你知道,现在如果你调用 pandas,你就打开了 pandas 中所有类似工具,对吧,嗯,你知道,你可以构建自己的实用函数。所以你可以调用,呃, 你想要的特殊用途函数。所以代码有点特殊。它就像其中一个,你知道,特殊的东西,它与其他工具的不同之处在于它打开了以新方式调用工具的能力。所以实际上有,呃,研究工作表明这非常有效。呃,现在我们基本上
[12:44.079] 把它当作理所当然,但这不是我们三四年前调用工具的方式,呃,当我们最初开始,你知道,用 LLM 构建智能体的时候。所以当时的标准是,如果你收到一个查询,抱歉这个太小了,但嗯,它基本上说的是确定购买智能手机型号 Kodak 1 最具成本效益的国家。 呃,要考虑的国家是美国,呃,日本、德国和印度。基本上,这要求你做的是,呃,你会调用你的查询汇率工具查德国。嗯,你会调用你的查询手机价格,呃,工具。你会调用,呃,转换和计算税费。然后你会再次调用查询汇率。然后你会调用,呃,查询手机价格,你会 一步一步又一步地走,呃,为了,呃,最终,呃,最终得到结果。但如果你写代码,你可以直接写一个单一程序来执行这个。所以,呃,这使得它成为一种更丰富,呃,一种更高效的调用工具的方式,除了更丰富之外。所以这种叫做,呃,叫做 Kodak 的方法有一篇,呃,关于它的论文, 呃,论文中的一些核心结果基本上是成功率上升,平均交互轮数下降。而且这甚至适用于传统上不需要代码的任务。这些是那些被视为常规工具使用任务的任务。嗯,但就像代码只是一种很好的媒介,呃,来做这件事。
[14:18.560] 嗯,但人们不把代码,呃,程序化工具调用用于所有事情是有原因的。嗯,这很大程度上与,嗯,与你想给智能体多大的权力有关。所以代码权力很大。它富有表现力。它给你循环变量和库。这是好事。但这可能有什么缺点呢? 有什么想法吗?就,就关于循环,呃,循环和变量,一开始也许。是的。>> 卡住。>> 是的,它可能会卡住。所以它可能写出一个无限循环,然后你需要在你的系统里有某种东西来处理无限循环,对吧?那,呃,那有点烦人。嗯,那库呢? 这有什么问题吗?>> 是的,安全问题会是其中之一。还有,可能只是版本控制之类的,但嗯,我不确定大家是否熟悉这个,但目前在网络安全领域,智能体面临的一个主要问题是,智能体会引入一个已被攻破的库。嗯,智能体被攻破,然后你的整个系统 就被攻破了。所以,呃,这是你需要非常小心的事情。嗯,它们也更难约束,因为它们有很广泛的动作空间。所以呃,你知道,更难验证,呃,也更难获得可预测的行为。嗯,它们也有更高的影响。所以它们可以,你知道,使用更多的磁盘,呃,抱歉,使用更多的内存,使用更多的 磁盘,使用更多的 CPU 之类的。所以正因为如此,嗯,我们会在安全讲座中更多地讨论这个,但就像一旦你转向程序化工具调用,你需要呃,你需要考虑沙盒以及你将如何限制智能体之类的问题。
[15:59.600] 嗯,关于这个有什么问题吗?好的。好。那么接下来我想谈谈提供工具的机制,呃,现在呃每个语言模型基本上都很擅长呃,比如调用工具,但这并不是你知道理所当然的。我想我周二也提到过这个。嗯,但基本上工具调用是以像这样的 token 来表示的。所以嗯,你知道,一个文本 续写是天气晴朗。一个工具续写是呃,像一个工具调用,然后在工具调用里面有 get weather 之类的。而且很多时候呃,你在同一个输出里两者都有。所以如果你记得 react,呃,之前讨论过的,嗯,我其实可以在黑板上画出来,但 react 基本上是你上面有你的文本 然后你有你的呃工具调用,然后你下面有你的工具调用。是的,这就像是工具调用的结尾。所以现在你有模型在呃向人类给出回复,呃,同时它在进行工具调用。然后呃,在这里你有它正在进行的实际的工具调用。所以 react 循环不再被表示为 像单独的代码。它更多地被表示为像只是一个单一的补全。嗯,如果你使用的是某种推理模型,嗯,它可以推理,呃,比如有很长的推理轨迹之类的。此外,你可能在这里有思维 token,然后是一条消息,然后是工具调用。所以思维就像是你不展示给
[18:05.120] 用户的非常冗长的思维。文本是你展示给用户的较不冗长的呃消息,然后工具调用就像是你那里有的实际输出。是的,>> 工具调用 token 在预训练期间也必须存在于模型的词汇表中,对吧?>> 是的。>> 所以所有这些服务 token 都会成为词汇表。 >> 呃,是的。所以实际上这是个好观点。我说了是的,但答案可能是否定的。我先重复一下问题。所以问题是,嗯,这些 token 在你做预训练时必须存在于词汇表中吗?嗯,通常如果你在整个互联网上预训练,你不一定必须让它们已经在词汇表中。嗯,我们有 一些情况下你可能会那样做,但实际上更典型的是在一个中间训练的过程中引入它们,这就像是呃,在呃,当你在以你喜欢的格式对中等规模的数据进行训练时,然后呃,你可能在那之后做强化学习,但你在整个互联网上预训练时不一定会有它们。
[19:10.400] 好。嗯,所以我认为这应该对嗯,你知道,呃,在之前的自然语言处理或或其他课程中实现过东西的人来说是熟悉的。但嗯,如果你有聊天格式,比如 OpenAI 聊天格式,你有系统消息、用户消息、助手消息之类的东西,然后呃,这些在 呃,比如在 Python 中当你调用模型时被表示为类似 JSON 的东西,但这些会被转换成某种东西,呃,这里有一个特殊 token,系统,呃,就像一个系统提示,然后要简洁之类的。所以就像每条聊天消息都有自己的格式,这是 Qwen 格式的一个例子,但呃,正如我稍后会展示的,其他呃,其他函数的格式不同。所以 工具基本上嗯,为请求添加了结构,所以你有一个像这样的工具定义,呃,这告诉你它是一个函数。函数名可能是 get weather。嗯,参数是 city,类型是字符串,并且这是必需的。这个 schema 会被传递给例如 chat completions 函数,就是你在调用 OpenAI 或 类似东西时会使用的那个。所以嗯,当提示词呃包含类似这样的东西时,你可能会呃,把这个包含在提示词的工具部分中,然后输出呃最终会是类似 name get weather 这样的东西,呃,带有适当的参数,比如 Pittsburgh 这个城市。
[21:02.799] 所以嗯,我们有一个关于你如何预训练模型的问题,嗯,你可能不是在预训练,但至少在中间训练及之后,你会训练模型来适配某个特定的工具调用格式。有趣的是,呃,每个模型都有不同的工具调用格式。也许不是每一个,但很多不同的模型都是这样。所以呃,Qwen 有类似 im start tool call 呃 IM end。 呃,Mistral 有 tool calls,然后呃所有的工具调用。DeepSeek 有他们类似 DSML,DeepS 标记语言函数调用。他们不叫它工具调用,他们叫它函数调用,然后呃 evoke、invoke,基本上你知道这些任何一个都可以用。嗯,如果用相同的数据训练相同的模型,呃,哪一个性能更好可能会有呃微小的差别。 呃,但你需要知道的是,你需要知道这些是不同的。所以你不能只是假设某些能和 DeepSeek 配合的解析代码会突然也能和 Qwen 配合,反之亦然。是的。>> 你说你添加了功能。所以需要提供。
[22:17.280] >> 嗯,所以你说的松散泛化性是什么意思?>> 是的。微调集 >> 是的。所以当你,当你在微调时,你会想要匹配,就像如果你是从一个已经训练过的模型进行微调,你百分之百想要匹配工具调用格式。你不想试图让它做它没有被训练过的事情。嗯,好消息是这一切都 在类似 Hugging Face 中用 apply chat template 呃函数实现了。所以你需要为你使用的模型应用聊天模板,但这一切都已经实现了。如果没有被正确实现,你可以进去,嗯,比如你问他们,他们会进去实现它,或者你自己做之类的。但是的,现在这一切都标准化了。但我想要 人们要知到底层正在发生什么,因为如果你不知道这一点,你就可能犯错,呃,而且结果不会令人愉快。好。那么呃,一旦你完成了这件事呃,下一步就是呃,你要做工具调用解析,实际上我将在下一节讨论工具调用内核解析。所以呃不是马上在这里讲,但让我们假设
[23:47.919] 如果呃语言模型输出了这个,你有办法把它解析成呃解析成函数参数。然后你呃比如有,你在初始化时注册工具,呃你呃有办法解析它,这样你就得到一个从名称到你想执行的工具的映射。所以大多数智能体框架基本上都会有一种方式让你 可以添加新工具。每个工具都有自己的名称,然后你有一个 Python 函数或类似的东西。Python、TypeScript,随便什么语言。然后它呃它会被分派到那个工具,并带上适当的参数。然后每次你你解析呃你查找工具,你根据参数验证呃动作,然后你执行呃然后你返回。但是呃在 验证时,如果模型给了你错误的呃错误的工具调用,这可能会失败。在执行时,这同样可能失败,如果存在某种并非被明确说明为糟糕的呃、并非被明确说明为无效、但隐含地无效的东西。比如举个例子,如果你有一个执行 Python 的工具,它可能接受任何字符串作为 Python,但当你实际尝试运行这个 Python 时,它它 可能会失败。所以那那就会是一种执行错误。然后如果它确实如果它呃无论它呃无论它失败与否,然后呃你会从中得到一个观察结果。所以这是另一个细节呃,它相当有帮助,但当你实现智能体时也真的很烦人,如果你呃如果你把它搞错了。但基本上每个工具调用都会被分配一个 ID,呃当
[25:33.279] 你呃当你运行它时,基本上是由呃呃要么是语言模型推理代码,要么是智能体代码来分配,然后你得到一个结果,而该结果有一个匹配的调用 ID,这特别有用,在并行工具调用的情况下,因为我稍后会谈到并行工具调用,让 ID 匹配能让你知道哪个工具调用 与与哪个结果相关联。但呃问题是呃例如呃 Anthropic,如果你有一个工具调用没有匹配的工具结果,它会直接失败不让你继续,呃所以它会告诉你这是一个无效的历史,我不会接受这个历史,也不会为你生成任何更多输出。所以根据我的实际经验,有时候比如助手 发起了一个工具调用,然后突然呃你的呃你的程序挂了或类似的事情,它没能写出工具结果,然后你恢复它,它没有那个结果、没有关联的结果,呃 Anthropic 就不肯为你工作了。所以这是一个你需要了解的小细节。
[26:47.120] 好。那么,呃,这里有什么问题吗?是的。>> 呃,好问题。工具调用是异步的吗?呃,我将在下一呃下一节谈到这个。是的。好。好。那么,现在现在这里有一个技术上、算法上都很困难的问题。呃,它可能对你非常有意思,也可能对你不那么有意思。但如果它对你没 有意思,庆幸有别人在替你解决它吧。呃,那么,呃,语言模型绝对不保证会生成格式良好的工具调用。呃,这是一个例子。呃,你可以看到这是 JSON,但它缺少了呃最后一个右括号。
[27:36.320] 所以,这是格式很差的 JSON。你把它放进你的 JSON 解析程序,它会抛出一个异常,你就无法从中取出呃那个数据。所以我见过无数人跑进去试图比如弄清楚是不是少了括号,然后事后补上一个,但你不应该那样做。那可不不好玩。呃所以有一堆约束呃 你呃可以给每个工具调用指定这些约束。所以第一个是语法。所以它必须是有效的 JSON。所以这有点像最基本的门槛,对吧?所以它它必须能解析。呃第二件事是呃形状。所以要确保如果你有预期字段或必填字段,你有那些必填字段。呃第三件事是类型。所以呃你知道如果你 有 city,那 city 必须是一个字符串。哦抱歉。是的。呃是的。所以如果你有一个 city,city 是字符串。呃如果你有呃值,呃你知道单位要用适当的单位。所以这一切都可以通过呃一种叫做 JSON schema 的东西来表达,或者基本上通过任何 schema 库来表达。呃所以就像这是一个 city,呃类型是 string,单位可以 是呃 Celsius 或 Fahrenheit,而 city 是必填的。所以呃这样做的好处是它有机器可读的验证规则。所以你可以检查某个调用呃是否遵循该 schema。但呃一种你可以表达 schema 有效或无效的方式,是在呃在该 schema 上定义一个文法。有多少人呃学过比如上下文无关文法或者类似
[29:22.159] 那些东西?正则文法。有多少人知道正则表达式?好。很多很多人。好。那么呃正则表达式就是一种正则文法。呃有人知道你怎么解析正则表达式吗?>> 有限状态自动机。是的,完全正确。呃所以一个有限状态自动机呃,对于那些对此不太熟悉的人来说,是 看起来有点像这样的东西。呃,所以你有一个状态,每次你接收一个 token 作为输入,呃,你就移动到一个不同的状态。所以如果你得到 A,你会移动到这个状态。如果你得到 B 或 C,你会移动到这个状态。而它这适用于呃一种叫做呃呃正则文法东西。所以像你可能会用来搜索搜索文本的那些斜杠加点 星号之类的东西,就是呃正、是正则表达式,它们可以通过正则文法来表达。呃JSON schema 不能通过正则文法来表达。呃它可以通过一种叫做上下文无关文法的东西来表达,而你可以呃上下文无关文法基本上可以造出一棵看起来有点像 这样的树。所以呃每个 JSON 表达式都可以在两侧有括号。它的成员之间可以有逗号。呃这可以是一个字符串呃而这可以是一个单位。而如果呃JSON schema 格式正确,你应该能够创建一棵呃看起来像这样的树。 如果 JSON schema 格式错误,你可能能创建、能够创建一棵树的大部分。但当你到达一个单位时,一个单位不能是 K。所以基本上这呃这会失败,即使一个单位可以是 K,但呃我们我们把这里定义为不接受 Kelvin 作为我们的温度单位。
[31:42.320] 所以嗯基本上,如果你能用从你的 JSON schema 定义出的上下文无关文法来解析嗯工具调用,嗯你就能嗯做到这个,我不会深入讲很多细节,但有限状态自动机无法解析嗯一个上下文无关文法,不过有一种叫做下推自动机的东西可以让你做到这个。所以基本上它给嗯 正则文法加了一个栈,嗯你把东西压入栈嗯把东西从栈里弹出,最终能够嗯最终能够判定它是否嗯可解析。所以你要做的就是,你从最开始嗯在这个下推自动机中的一个状态出发,然后你一步步走,嗯在你嗯从左到右生成输出时对其进行验证 我这里举一些来自 X grammar 的例子嗯,X grammar 是一个实际上在嗯所有 LM 推理库中都被相当广泛使用的东西。它实际上是由这里机器学习系的人开发的。嗯所以嗯这意味着什么呢,就是每次你让 LLM 预测下一个 token 的 logits 时,你看一下你的文法,如果文法说 这是一个有效的下一个 token,嗯你就得到分数一,如果你有一个无效的下一个 token,你就得到分数零。然后你把所有无效的下一个 token 设为负无穷。嗯对于输出 logits,然后你重新归一化,这样你只会在有效 token 上得到概率。所以这嗯让你能做到的是,这确保你生成有效的输出。 嗯,所以这是来自 Xgrammer 论文的另一张图,他们做了这些嗯巧妙的事情,基本上有一些词汇表是始终有效或始终无效的,你预先计算这些,然后嗯有一些只在某些上下文中有效、只在某些嗯栈上下文中有效,然后你实时计算它们。所以这嗯
[33:58.960] 从算法角度来说非常有趣,如果你喜欢算法嗯之类的东西的话。如果你不喜欢,嗯那就庆幸机器学习系的人基本上在替你做了这件事吧。嗯所以正因如此,几乎总是嗯如果你嗯如果你启用了这个,嗯并设置了合适的 JSON schema,你就会得到格式良好的工具调用。所以那那很好。
[34:27.040] 有一种情况,尽管有这些,你实际上还是嗯嗯无法得到格式良好的工具调用。嗯也许我可以来个快速小测验。这个非常非常难。所以我不知道有没有人能做出来。但有没有任何人知道在哪里即使这样也嗯也不够。得熟悉嗯LM 我猜。 >> 是的。嗯我我我觉得这已经足够接近我嗯想说的了。所以基本上嗯当你用完 token 时,模型只能生成这么多 token,你可能会遇到一种情况,你仍然处于通过自动机的一条有效路径上,但你不在最终状态。所以你生成了比如 JSON 输出的一部分。所以非常非常好。嗯还有我
[35:17.520] 我实际上遇到过这个。理论上嗯有一种方法可以做到,比如你数一下你还剩下多少输出 token,然后你把它们截断,但那是嗯如果嗯有人想在 next grammar 里把这个实现出来作为额外加分作业,你知道,我会很乐意很乐意接受这个。好,那现在嗯我们来讲 REST API 调用。嗯所以有嗯两 不同的方式嗯有不同的方式来表达工具,嗯我想可能大多数人都熟悉 REST API。这些是你与 web 服务交互的方式。嗯但实际上抱歉,还有一种调用 API 的方式,一种调用 API 的方式是通过程序化工具调用,基本上嗯你只给模型一个 Python 程序,然后你说用这个 Python 程序里 的东西来调用工具。所以如果你做类似这样的事情,你可能有比如 weather lib.py,嗯你这里有 get weather 函数嗯带有它的 city 和它的 units,嗯然后你只要说在你需要的时候调用这个函数,你给它执行 Python 的能力,它就能够调用那个工具。所以在程序化工具调用中,这嗯这 是可行的,但这不能嗯远程调用,也不能从你嗯在你嗯实现这个时使用的、嗯非程序化工具调用时的标准工具调用方法中调用。所以有一种方法可以把这个变成嗯REST API。有没有人用过 fast API?它是一个挺常见的。好。很多人。它是一个挺常见的库。
[37:02.880] 基本上这让你能做到的是,这让你能够嗯极其简单地创建一个 web 嗯 web 后端,嗯只需嗯设置一个 fast API,嗯给一个 API key,这样你可以让人针对这个 API 做验证,然后写一个 Python 装饰器,嗯 weather 就变成嗯变成这个。所以这很好嗯,有几个原因。 第一个原因也许是如果你不想让人嗯查看天气,嗯那么嗯你可以阻止他们查看天气。但可能更重要的是,如果你不想让人比如获取你的个人数据之类的东西,你可以要求一个 API key,嗯这会嗯让你能够比如屏蔽任何没有合适 API key 的人。嗯 另一个原因是这免费给你一个 JSON schema。嗯当我说免费时,当然你知道这是嗯在 fast API 中实现的东西,但你的整个 API 可以表示为一个 JSON schema,然后这个 JSON schema 可以原样提供给一个语言模型,然后那个语言模型可以用它嗯来你知道指定哪些调用是允许的,于是你就可以
[38:13.680] 进去处理这个,嗯每当 agent 发起一个工具调用时,你就可以把它发送到你的 API 服务器,然后它能够在 API 服务器上使用它。嗯,调用这些的另一个选项是你直接嗯用 curl 命令。curl 命令嗯基本上允许你嗯像这样直接调用这些 API。所以如果你有一个编码 agent 能访问 bash,它就有能力嗯像这样调用。所以这也许嗯如果你熟悉嗯 REST 和这类东西的话,也许还算比较直接。有有任何问题或评论或者……如果你还没玩过 fast API,它很好。它非常容易使用。
[39:00.640] 但嗯我为什么想先讲这个,是因为这有点像是嗯传统的编程方式,嗯你知道在 agent 之前。嗯有嗯一个叫做 MCP 的东西,即模型上下文协议,这是由 anthropic 提出的,嗯大概两年前还是一年半前,其想法是,这是被设计为一种标准方式来嗯给你的模型 额外的上下文。当我第一次看到这个的时候,我其实想的是,为什么我们需要这么做?我不明白为什么我们需要这么做。我们干脆让我们的智能体调用 API 就好了。嗯,但有一个重要的点,关于一两个重要的点,使得 MCP 不同于仅仅调用一个普通的 API。嗯,我会在这里解释它们。但嗯,首先我会 解释为什么我一开始不觉得,我原以为这其实并不必要。基本上原因是,每次你设置一个 MCP,你所做的就是有一个 AI 应用程序,然后你设置几个 MCP 客户端。所以比如这个是你的天气客户端,嗯,这个是你的天气 MCP,然后你的 GitHub MCP 之类的。所以你可以问 天气是什么,天气是什么,然后把它推送到你的 GitHub。嗯,我一开始认为这不必要的原因是,为什么你需要运行一个程序来调用一个 API 呢,对吧?我们已经有了调用 API 的好方法。我们只是,你知道,把它发送到 REST API 服务器。
[40:43.920] 但嗯,好吧。对。所以,这算是稍微跑题一下。嗯,我待会儿会回到那一点,但先稍微跑题一下,嗯,有一个非常好的库叫做 fast MCP。而 fast MCP 基本上被设计成 MCP 版的 fast API。所以如果你想为你想要的任何东西创建一个 MCP 服务器,你可以,嗯,基本上就像换掉 fast MCP,换掉 fast API,换上 fast MCP,然后你就可以,嗯,非常容易地创建一个 MCP 服务器。嗯,你也可以接收一个由类似 REST API 生成的规范,然后把它也直接转成一个 MCP。但这里,这里是你可能想要使用 MCP 而不是 API 的主要原因。嗯,原因是它给了你一层额外的 安全性。所以 MCP 有一个 MCP API 密钥。而这个 MCP API 密钥是你需要提供给运行你智能体的那个进程的东西。与此分开的是,你还有上游 API 密钥。所以比如,假设你在让你的智能体连接到你的 GitHub。上游 API 密钥就是你的 GitHub token,你会把它提供给 MCP 服务器,
[42:05.599] 但你不会把它提供给智能体。然后你提供给智能体的是 MCP API 密钥,它允许你认证进入 MCP 服务器。所以这之所以重要,是因为如果你把你的 GitHub token 给了你的智能体,然后你的智能体突然决定把它推送到你的公开 GitHub 仓库是个好主意,会发生什么? 不好,对吧?[笑声] 你的账号会被入侵,嗯,你的所有仓库都会被安装恶意软件之类的。所以你想给智能体一些相对无害的东西。嗯,这样即使它因为某种原因泄露了,比如那次泄露也是相对无害的,然后嗯,真正的凭证就得以保留,所以那基本上就是
[42:51.280] 背后的理由。所以嗯,总结一下,它们都让你能够把一组 API 添加进你的智能体。比如你可以通过一个普通的 JSON schema 来做,或者通过一个 MCP。嗯,但很多其他东西是不同的。所以比如对于发现来说,嗯,你可能需要获取一个 open API 文档。对于 MCP,有一个特殊的 API 允许你列出所有工具。嗯,对于调用来说,嗯,你在这里调用一个 HTTP 的东西,对于 MCP,有一个 MCP 传输,这可以通过各种方式实现。你通过标准 IO 连接,或者你通过一个 H,嗯,一个套接字之类的连接。
[43:39.599] 嗯,我已经谈过认证了,嗯,MCP 其实还有几个其他,嗯,有几个其他的比如便利之处,比如你可以添加资源、提示和扩展,但我不会对此详细展开。好。嗯,其实,嗯,还有两件其他事情我想提一下。嗯,我不想,嗯,我想我忘了把它们加到我的幻灯片里了。嗯,所以第一件事 是嗯 MCP 注册表。有一个官方的 MCP 注册表。所以如果你想找允许你做类似事情的 MCP,你可以,你知道,去这个注册表,找到,嗯,数量非常庞大的 MCP 中的任何一个。还有比如一百五十万个,嗯,MCP 服务器之类的网站,你可以去访问,它们是根据,嗯,受欢迎程度之类的东西排名的 之类的。另一件事是,嗯,我一直在讲很多关于匹兹堡天气的事,嗯,有趣的是,嗯,今天我准备所有这些幻灯片,当然是比较早的时候,但今天我们实际上遇到了匹兹堡天气同时既下雨又出太阳。所以我成功地弄坏了我自己的 API,因为它无法同时返回多种状态。但嗯
[45:03.280] 嗯,是的,那真是,嗯,相当巧的巧合。你可以同时看到倾盆大雨和明亮的那一面。好。嗯,回到,回到正经的事情上。好。嗯,所以另一个大的,嗯,算是最近的发展是并行工具调用。在并行工具调用中。 嗯,我们想要解决的基本问题,和我讲编解码器以及程序化工具调用时讲的是同一个问题,那就是如果你一次调用一个工具。嗯,那个,嗯,它甚至对一个简单的操作来说都可能变得非常长,因为你可能先查天气,然后查日历,然后查航班。嗯,但如果工具调用是独立的,你其实可以 同时调用它们。而这做起来相当简单。你只需要,就像在单个智能体响应中添加多个工具调用块。嗯,关于这个有一些细微之处。第一个是,嗯,你只能并行化那些彼此之间没有依赖关系的工具调用。所以,嗯,比如如果你在查匹兹堡的天气,读今天的日历, 查航班状态,那可能,嗯,可能是可以的。嗯,但如果你需要找一个客户 ID,用它来获取订单,然后退款选中的订单。显然,你不能那样做。所以,你能做的并行工具调用是有限制的。而且如果你的日历或你的航班依赖于天气,那么你知道,显然那也会是个问题。 所以,关于这个有一个问题。嗯,你是并行执行这些工具调用吗?答案是通常是的。你可以,嗯,用典型的 Python 语法,你知道,写一大堆工具调用,然后执行它们,然后嗯,用类似 async.io.gather 的东西来,嗯,在它们同时运行时返回它们的结果。所以这是,嗯,这是
[47:01.119] 相当常见。我还想指出的另一件事是,嗯,这是真正高效的语言模型与不太高效的语言模型之间的一个主要区别。而且,如今的智能体语言模型中存在这样一个奇怪的悖论:更昂贵的模型——更昂贵的模型——如果按逐个任务来衡量,实际上可能更便宜。这主要有两个原因。 第一个主要原因是更昂贵的模型可能更聪明。所以它们能更快地选定一个合适的解决方案。嗯,但另一件事是,嗯,更新的模型在并行工具调用方面做得好得多。所以它们会同时发起一大堆调用。所以如果你在使用一个编码智能体或类似的东西,嗯,你使用更好的,嗯,你 使用更好的模型,它们会同时查看一堆图像,或者它们会,嗯,同时写入一堆不同的文件之类的。那是因为它们在做并行工具调用。那么,嗯,有没有人知道,为什么它们在这方面变得这么厉害?它们,这曾经并不是一件大事,尽管并行工具调用 机制已经存在很久了。直到大概六个月前左右,这都还不是一件大事。是的。>> 强化学习就是迫使它们这么做的。>> 是的。完全正确。所以强化学习,嗯,在某种程度上迫使它们这么做了,因此这些模型受到了非常强烈的激励去快速完成任务,而并行工具调用就是
[48:37.839] 做到这一点的一个好方法。所以如果你做强化学习时,对任务执行的时长施加非常重的简洁性惩罚,你就能得到,嗯,多得多的并行工具调用。很好。那么,嗯,我今天这节课想讲的最后一件事是评估工具使用。所以我还不会立刻讲评估端到端的智能体任务。嗯,而是 讲只评估语言模型的工具可用性,因为这有点像语言模型要擅长,嗯,擅长智能体任务的一个前提条件。为此有一堆数据集。最有名的一个是 Berkeley function calling leaderboard,它有四个版本。嗯,它一开始是版本一,基本上就是,嗯,单轮 工具调用。嗯,然后它经过四个版本演变,现在它涵盖,嗯,多轮工具调用。它也确实有智能体工具调用,但这更多是,嗯,不是针对端到端编码智能体之类的东西。它是,嗯,工具调用智能体,而且它们还有工具调用鲁棒性。所以它们衡量,嗯,参数的幻觉。它们还衡量格式 敏感性。所以当我谈到,比如所有那些不同的格式时,嗯,它们也有关于这个的参数。所以,嗯,当你去评估整个,嗯,技术栈时,有很多东西是你想要,嗯,评估的。所以第一件事是语言模型是否为任务选择了合适的工具。所以它可能选了,比如,一个不合适的工具,根本无法,嗯,让你 完成那个,嗯,任务。嗯,另一件事是参数,嗯,也就是,你知道,你是否,你是否填入了正确的值。嗯,如果你在谈智能体工具调用,你可以谈它是否以正确的顺序做了这件事,然后如果你在做,嗯,智能体工具调用,你可以,嗯,衡量端到端的任务准确率。而所有这些都是这个排行榜中的某种指标。
[50:52.559] 然后与此分开的是,还有,嗯,效率。所以比如,嗯,你能多快地解决任务?比如,嗯,它花了多少 token?它花了多少钱?嗯,可靠性。所以,嗯,你知道,如果一个工具调用超时了,嗯,它会适当地重试吗?如果一个工具出故障了,它能选一个不同的吗? 还有,嗯,安全性。所以如果你有对抗性输出,你让它以不恰当的方式使用一个工具,嗯,你能做到这个吗?而所有这些都是,在这个基准的四个迭代中。它涵盖,嗯,所有这些维度。嗯,是的,其实我已经大致讲过了。所以另一个,嗯,真正有趣的,嗯,工具调用基准是,嗯,这个 open router,嗯,工具
[51:43.280] 调用错误率基准。我不知道有没有人,比如,用 open router 或者以前见过这个。也许没有。好吧。所以,嗯,这是针对同一个模型的。所有这些都是针对,嗯,我想这是 GLM 5.3。所以它就像,同一个,同一个模型,它衡量的是工具调用错误率,仅仅,它们唯一改变的是谁为你提供这个模型。而这是,嗯, 这显然相当重要,因为你会想,哦,我要用这个模型,也许你知道,不管是谁提供给我,它都会是一样的,但实际上差别在 15% 和大约 0.01% 到 0.05% 之间。有人知道,嗯,为什么可能是这样吗?
[52:40.319] 讲座中有一些,嗯,讲座中有一些提示,还有一些,嗯,不是一些提示,讲座中的一些提示 >> 是解码算法不同吗?也许有人用的是更便宜的模型版本或量化版本的模型。>> 是的,非常好的观点。所以我会,我会复述一下。所以第一点是解码或推理算法可能不同,而,嗯,一个非常大的区别 是它们是否在使用模型的量化,或者,比如,它们在使用什么级别的模型量化。所以我个人的经验是,嗯,FP8 模型,嗯,FP8 有点像,嗯,模型量化的默认级别,嗯,比 FP4 模型得到的,嗯,错误工具调用要少得多,因为 FP4 就像把它压缩得非常厉害。
[53:28.079] 它是在为推理提供商省钱,但它通常是一个更差的模型。没有很多 FP4 量化能让你获得相同的性能。另一个是,嗯,投机解码。嗯,我不认为我们在这门课上会大量讨论投机解码。 也许我会在长上下文时讲它,或者实际上也许,有一些专门针对智能体的算法挺有意思。所以也许我们可以讲一讲。但基本上,它就是你有一个更便宜的模型,嗯,它预测那个更昂贵的模型将要做什么,然后你用这个来,比如,加速你的推理。 嗯,无损的投机解码大概不应该造成差别,因为它,它就像不改变模型的底层结果。但如果它们在做的某种,比如,有损的投机解码,嗯,那可能,可能会让它变得不同。但那样的话,你知道,称它为同一个模型大概也是个坏,坏主意。嗯,还有一件事,嗯,我
[54:27.920] 提到,呃,有人有想法吗,这其实在今天的课上提到过。你能做些什么让你的工具调用更成功?>> 是的。>> 约束解码。对,正是如此。所以这些不同的提供商可能在使用不同的约束解码算法。嗯,实际上,很多很多这类提供商会实现自己的推理 算法。所以他们会从头完全实现自己的推理算法。嗯,有些提供商会使用开源的,比如VLM或SGLANG。而VLM或SGLang支持不同的基于语法的解码,呃,算法。所以,呃,有些提供商可能根本没有实现那个,因此他们完全依赖语言模型来做好 工具调用。嗯,否则,呃,他们可能做不到。工具调用可能失败的一个最终算是无聊的原因是,推理提供商可能不可靠。所以它可能有时候会宕机,然后工具调用就会失败。好。嗯,所以这些就是,嗯,这就是我今天要讲的主要内容。
[55:49.280] 嗯,所以工具使用基本上是一个分层的系统。嗯,你知道,工具增加了能力,比如检索、执行、生成、应用。它们才是让一个智能体成为智能体的东西。呃,但我们不能免费获得那个,呃。而且,嗯,你可以,呃,在提示中添加模式。 呃,模型发出调用,然后你验证、分派,并按ID匹配结果。我们可以添加约束,呃,比如基于语法的解码。嗯,它们并不保证语义正确性。所以,嗯,如果你有一个比如Python程序,即使你生成了一个,呃,你知道,可以被解析为Python的字符串,这个Python程序可能仍然是错的。嗯,而且有很多,呃,方式你可以 与它们交互,比如直接的REST调用和MCP。呃,然后我们有很多系统,嗯,用来编排依赖关系和并发,呃,并允许我们进行评估。所以,是的,那就是,呃,关于工具调用我想讲的内容。呃,这将会是harness,呃,作业或者第一个作业中会涉及的内容,在那个作业里你要构建你的智能体。
[56:53.280] 所以你需要,需要处理这个。嗯,但是,下次我们要讲长上下文LMS中的上下文管理。但是,嗯,有什么问题来收尾吗?好的。是的。是的。而且我要重复一下,以防后面的人没听到,但是第一个,嗯,呃,反思讲座并谈论你在 讲座中学到的东西的作业,将会发布在Canvas上。所以,确保你,呃,确保你提交它。谢谢。
CMU 11-768 Fall 2026 · Lecture 2 · Agent Capabilities 1: Tool Use
- 视频:官方视频
- 字幕:en-orig · auto captions
- 处理:连续字幕合并为自然段;每段保留首条字幕的起始时间戳
- 状态:用户审核通过;中英文按完整语义段合并,每段保留首条原字幕时间戳。
正文
[00:00.640] Okay. So, hi everyone. Uh, welcome to class number two. Today, uh, today I'll be talking about tool use for language model agents. And, uh, this is, you know, the the most fundamental thing about agents that, uh, you know, makes them different from a language model. Um so the basic idea here is uh that we're going to be um a tool is basically an interface through which a language model can invoke an external computer program. And uh this is a language model cannot do this on its own because it's fundamentally a token predicting machine. But this enables you to do you know many many different things. So you know you can search, you can call a calculator, you can call a browser, um you can call Python, you can call arbitrary APIs and so uh the language model kind of as you'll see the method for tool calling is standardized but what you do downstream with the tool call can be very different. So there's basically two uh benefits of tools and all of this is from one of the readings that I I posted on the website if you want to go back and read more about it. Uh this is a survey that uh I we wrote uh together Daniel and I and Zoro Wong, one of our our students. Um and the first thing is extending the ability of language models. So this is giving language models the ability to do something that they fundamentally cannot do. And so this could be like accessing
[01:40.079] information or actions that are outside the language model's um you know action space. The second thing is uh facilitating the language model. And so what I mean by this is this is something that fundamentally the language model can do but it's just a lot easier if you don't if you don't require the language model to do it. So um can anybody come up with an example or well I guess we already have an example in here. So like one thing the the language model fundamentally cannot do would be get the time four months ago or something like that. So the most recent information it saw is uh from four months ago and then its parameters are frozen. So there's no way it could know that without calling you know an external function. On the other hand, uh something in the realm of facilitating is language models can do math actually quite well nowadays, but they take a lot longer than calling a calculator to do math because they have to do reasoning like you ask them to multiply uh two seven-digit numbers and it will take them a very long time to do it where a calculator can do that really quickly. So those are the two kind of basic categories. So um to go a little bit more deeply into those uh you can do things like look up current information um and the benefit of this is this gives you you know fresh evidence to uh ground your answers uh do exact computation using like calculators or python this gives you the ability to execute more reliably or and quickly than using the language model itself. Um other things is uh access private states. So giving the model access to like information about the user so they can uh respond based on the user state um or uh make a change to your external environment. So this could be like browsing or or calling an API.
[03:33.280] So to have some examples of these um if we think about chat GPT uh chat GPT used to like literally just be text in and text out when it first came out. it, you know, the the only thing that it could do was give you textual responses to uh your queries. Now, it's kind of an everything app. It allows you to do so many different things. Um, so like what what are some of the examples of things that uh you know are your top use cases of uh of using chat GPD now? >> Yeah. >> Writing code. Okay. So uh what what tool would you need for something like that? uh like cursor or codeex I think they they can invoke like >> okay but that's not chat GPT right that's cursor or codeex yeah I mean chat GPT like in the chat GPT interface
[04:30.080] >> they can use blender so they they can render blender okay things so that that's an example of um something that requires executing code but also like displaying it in the appropriate format um any any other ones that people do yeah Just the web page generate images. >> Generate images. Yeah. So that that's calling an image generation tool. Any others? >> Yeah. So recommend products like a blender or something like this. And for this uh what what sort of tool do you think it would need? >> Some sort of like web searches like Google or Amazon to find. >> Yep. So you might need like arbitrary web search or you might need an API that directly links into Google or Amazon or something like that. Yeah. Any other like weirder weirder ones? Things you were surprised chat GPT was able to do? >> Yeah. >> You can render latex quite nicely. >> Okay. messed up files when I fix you the PDF >> and compile everything which is very handy sometimes. >> Yep. Ren, it can render latex. Well, I actually don't know if this is a tool or if this is just a front-end interface thing, but it might be just that it's rendered in your web browser.
[05:52.160] >> Oh, it creates a PDF. So, okay. Is a tool. Okay. Very cool. Yeah. >> Interact >> uh interact with like Slack or something like that. So, that's another specialized API. So all kinds of different things. Um I I kind of categorized these into a list of things that I think are um the most uh like typical tools and most of the other tools can kind of be categorized into each of these. So the first one is uh textual responses. So this is kind of the boring one where it just gives you an answer. Um there's two ways you can implement this within an agentic uh like loop. By the way, chat GPT is is an agent now. Uh if you're like if there was any question about it, chat GPD is not just a chat app. It's an agent because it makes uh iterative tool calls to answer your queries. So that's kind of the definition of an agent. Um but uh textual responses, there's two ways you can implement these. One way you can implement these is you can have a finish tool that says, "Okay, I'm done interacting with the user, so I'm just going to finish and and output some text." The other way you can do it is if the agent decides to not call a tool, you can just finish the agentic loop. So that's kind of uh you know the the simple u you know most obvious one. Another extremely common one. Um so all all of these are tools and so like theoretically all of them can be thought of as an API but uh just to break them down a little bit more. Um another one is searching the web and this is you know pulling in information um from all
[07:28.479] of these uh different settings. Um how many people have heard of retrieval augmented generation? Probably everybody everybody who took the NLP class here uh you know has heard of it but a lot of people. How many people have heard like rag is dead? [snorts and laughter] A fairly large number of people. So there there's been an argument in like language model circles that retrieval augmented generation was so like two years ago and like nobody cares about it anymore. My argument here is a retrieval augmented generation where you retrieve context and then generate answers based on it has become so normal that people don't even realize that they're using it anymore. And so um it's it's so alive that people think it's dead. Um but uh basically you know searching the web and retrieving information and then generating answers based on it is now essentially the norm uh within these uh these applications. Now so uh that's another tool that's provided very very broadly and like any chat uh interface. Another one is code execution and so this is uh throwing in uh you know a set of code to do uh calculations or or something like this. very useful for uh computation all the other stuff we talked about. Another common one is uh having some sort of image generation and uh this this is you know obviously another very popular use case in chat GPT. Um this one's a little bit
[08:56.320] different because like all of the other ones here uh that I was talking about basically you know mostly interface with text. Um here this is interfacing with uh this is interfacing with images. One interesting thing is uh you'll notice that this is not the same thing is here. So this is like water watercolor robot studying in a library where the query was actually different. And so a big part of calling these images is actually deciding what query to put in there. So the language model will like really really expand the query before it calls an image generation API. I don't know if you can see this anymore in chat GPT, but you used to be able to see in chat GPT when you downloaded the image um that it would have like a very different caption than the caption you gave and you could kind of like latently see what the uh what query the the image generator uh sent to the generate image tool. Then there's all all kinds of uh you know custom functions. So, um, like buy me buy me bananas, uh, milk and coffee. Um, so, you know, this could create a grocery cart, uh, for you and call the like Instacart API to do this. Um, and you can basically go as wild as you want with all these tools and and add whichever ones you want there. Okay, so there's a bunch of different ways you can think about tool calling.
[10:27.040] Um the first way you can think about tool calling is just you provide a list of uh 50 or 70 API functions that the agent is able to inter interact with and it can call these uh APIs and if you do that basically what you're doing is like every step you're calling one API or if you're doing parallel tool calling you're calling multiple APIs or something like this but code is kind of a special uh API uh because code is extremely uh you know expressive and you can view code as like a meta tool right so within this we have like the bakers baked 200 loaves of bread how many loaves of bread did they have left here this is calling an assignment tool an assignment tool this is calling a subtraction tool um this is calling a uh assignment tool you know etc etc so like essentially Um I I imagine that a lot of people have taken like a programming languages course or have some familiar familiarity with programming languages but basically you you can express each piece of code is a tree of these function calls um and these uh the tree can also be have loops and other uh control flow in it. So it's essentially you know a very rich way of calling uh tools. Um and so uh you can also pull in external libraries. So these are now the custom APIs that you pull into your uh pull into your system. So uh you know now if you're calling pandas now you've opened up all of the like tools in pandas right and um you know you can build your own utility functions. So you could call uh special purpose functions that you want uh as well. So code is kind of special. It's like one of the one of the you know special things that uh it's different from other tools in the way that it like opens up your ability to call tools in new ways. And so there's actually uh research work that demonstrates that this is very effective. Uh right now we basically
[12:44.079] take it for granted but this was not how uh not how we called tools like three or four years ago uh when we first started uh you know building agents with LLMs. And so the the standard then was like if you got a a query sorry this is very small but um it basically says determine the most cost-effective country to purchase the smartphone model Kodak 1. Uh the countries to consider are the US uh Japan, Germany and India. Basically, what this would require you to do was uh you would call your lookup rates tool on Germany. Um you would call your lookup phone price uh tool. You would call uh convert and tax. Then you would call lookup rates again. Then you would call uh look up phone price and you would step over and over and over again uh in order to uh finally get uh finally get the result. But if you write code, you can just write like a single program to perform this. And so uh this makes it like a much richer uh a much more efficient way of calling tools in addition to be being richer. And so this method called uh called Kodak has a paper uh about it and uh some of the core results from the paper are essentially the success rate goes up and the average number of interaction turns goes down. And this is even for tasks that didn't traditionally require code. These are for tasks that were like viewed as regular tool use tasks. Um but like code is just like a good medium uh for how you would do this.
[14:18.560] Um but there's a reason why people don't use code uh programmatic tool calling for everything. Um and it largely has to do with um with like the level of power that you want to give to the agent. So code is very highowered. So it's expressive. It gives you loop variables and libraries. This is good. But what could be a downside of this? Any ideas? Ju just with respect to loops variables uh loops and variables at first maybe. Yeah. >> Get stuck. >> Yeah, it could get stuck. So it could write an infinite loop and then you need to have something in your system to deal with infinite loops, right? That's uh that's a little bit annoying. Um what about libraries? any problem with that? >> Yeah, security problems would be one thing. Also, maybe just versioning and stuff like this, but um I'm not sure if people are familiar with this, but one of the major issues with agents in cyber security right now is the agents will pull in a library that has been compromised. Um the agent gets compromised and then your whole system gets compromised. So, uh this is something uh something you need to be very careful about. Um they're also uh harder con to constrain because they have the broad action space. So uh it's you know harder to validate and uh get predictable behavior. Um they also have higher impact. So they can you know use more disk uh sorry use more memory, use more disk, use more CPU and stuff like this. And so because of this um we'll talk about this more in the safety lecture, but like once you move to programmatic tool calling, you need to be uh you need to think about sandboxes and how you're going to contain the agent and stuff like that as well.
[15:59.600] Um any any questions about this? Cool. Okay. So I want to uh talk next about the mech uh mechanics of providing tools and right now uh every language model is basically pretty good at uh like calling tools but this was not you know taken for granted. I I think I mentioned this on Tuesday as well. Um but basically tool calls are um expressed as tokens like this. And so um you know a text continuation is the weather is sunny. A tool continuation is uh like a tool call and then you have get weather or something like this within the the tool call. And very often uh you have both in the same uh output. So if you remember react uh which was talked about before um I can actually draw this on the board but react basically you have your text up here and then you have your uh tool call and then you have your tool call down here. Yeah, this is like the end of the tool call. And so now you have the the model be being uh giving a response to the human uh while it's making the tool call. And then uh in here you have the like actual tool call that it's making. And so the react loop is no longer expressed as like separate code. It's expressed more as like just a single completion. um if you're using one of the reasoning models um that can reason uh like have long reasoning traces and stuff like that. In addition, you might have like the thinking tokens up here and then a message and then the tool calls. And so the thinking is like very verbose thinking that you don't show to the
[18:05.120] user. The text is the less verbose uh message that you show to the user and then the tool call is like the actual output you have there. Yeah, >> the tool call tokens has to be in the vocabulary of the model during pre-training also, right? >> Yes. >> So all of these service tokens are going to be vocabulary. >> Uh yes. So actually that's a good point. I said yes, but the answer might be no. I'm going to repeat the question first. So the question was um do these tokens have to be in the vocabulary when you do pre-training? Um, typically if you're pre-training on all of the internet, you don't necessarily have to have them in the vocabulary yet. Um we there are cases where you might do that but it's actually more typical to introduce them in a process of mid-training which is like uh between uh it's when you're training on like moderately large amounts of data on things in the format that you like and then uh you might do reinforcement learning after that but you might not necessarily have them when you pre-train on the whole internet.
[19:10.400] Cool. Um so I think this should likely be familiar to um you know uh people who have implemented things in uh previous natural language processing or or whatever courses. But um if you have the chat format like the open AAI chat format you have things like the system message, the user message, the assistant message and then uh these are represented as something like JSON in uh like in Python when you call the call the model but these get converted into something uh with like a special token here the system uh like this is a system prompt and then be concise and stuff like this. So like each chat message gets its own format and this is an example of the quen format but uh as I'll show later the other uh other functions are in different formats. So tools basically um add a structure to the request and so you have a tool definition like this and uh this tells you that it's a function. The function name might be get weather. Um the parameters are city and the type is a string and this is required. And this schema gets passed to for example the chat completions function that you you would use when calling openAI or something like this. So um when the prompt uh contains something like this, you might have uh this included in the tools section of the prompt and then the output uh ends up being something like name get weather uh with the appropriate arguments like the city of Pittsburgh.
[21:02.799] So um we we had a question about how you pre-train the models and um you might not be pre-training but at least at mid-training and beyond you will be training the model to fit a particular tool call format. The interesting thing is uh every model has a different tool call format. Maybe not everyone but many of the different ones. And so uh Quen has like im start tool call uh IM end. Uh Mistall has tool calls and then uh all of the tool calls. Deepseek has their like DSML DeepS markup language function calls. They they don't call it tool calls. they call it function calls and then evoke invoke and basically you know any of these works. Um there might be like minor minor differences in uh which one gets better performance or not if you train the same model with the same data. Uh but what you need to know is you need to know that these are different. So you can't just assume that like some parsing code that works with deepseek will suddenly work with quen and vice versa. Yeah. >> You said you add functionality. So need to provide.
[22:17.280] >> Um, so what do you mean by loose generalizability? >> Yep. fine tuning set of >> Yeah. So when you're when you're fine-tuning, you will want to match like if you're fine-tuning from a model that's already been trained, you 100% want to match the tool call format. You don't want to try to get it to do something it wasn't trained on. Um, and the good news is this is all implemented in like hugging face with the apply chat template uh function. And so you need to apply the chat template for the model you're using, but that's all implemented. If it's not implemented properly, you can go in and um like it you ask them and they'll go in and implement it or you do it yourself or something like that. But yeah, it's it's all standardized now. But I I want to people to know that this is going on under the hood because if you don't know this, you can make mistakes and uh and it will not be happy. Cool. So um once you have done this uh the next thing is um that you do tool call parsing and actually I'm going to talk about tool called kernel parsing in the next section. So um not immediately here but like let's assume
[23:47.919] that if uh the language model outputs this you have a way of parsing it into uh into the function arguments. you then um like have the you register the tool at initialization and um you uh have a way to resolve it so that you get a map from the name to the tool that you want to execute. So most agentic frameworks basically will will have a way that you can add new tools. Each tool gets its own name and then you have a Python function or something like that. Python, TypeScript, whatever language. And then it uh it will be dispatched to that with the appropriate arguments. And so then at each time you you parse uh you look up the tool, you validate the uh action from the arguments and you execute uh and then you return. But um at validation time, this can fail if the model gave you the wrong uh the wrong tool call. At execution time, this can also fail if there's like not something that was explicitly said is bad uh is like invalid but implicitly is invalid. So like for example, if you have an execute Python tool, it might accept any string as Python, but then when you actually try to run the Python, it it might fail. So that that would be like an execution error. And then if it does if it well whether it uh whether it fails or not, then uh you get an observation out of it. So this is another detail um that that's pretty helpful but also really annoying uh when you're implementing agents if you if you get it wrong. But basically each tool call is assigned an ID uh when
[25:33.279] you uh when you run it basically by um uh either the language model inference code or the agent code and then you get a result and the result has a matching call ID and this is useful especially in the case of parallel tool calling because I'm going to talk about parallel tool calling in a bit and having the IDs matched lets you know which tool call is associated assiated with with which result. But the uh the problem is uh for instance uh anthropic if you have a tool call with no matched tool result it will die on you and uh so it will tell you this is an invalid history and I'm not going to accept this history and and generate any more outputs for you. And so in my practical experience there's times when for example the assistant makes a tool call then suddenly uh your your program dies or something like that it fails to write out the tool result and then you resume it it doesn't have the result the associated result and uh anthropic fails to fails to work for you. So this is a little bit of a a detail that you need to know.
[26:47.120] Okay. So, um, any any questions there? Yeah. >> And, uh, great question. Are the tool calls asynchronous? Um, I'm going to talk about that in like the the next next section. Yeah. Cool. Okay. So, now now here's a very technically algorithmically difficult problem. Uh, that may be very interesting to you or maybe not not very interesting to you. But if it's not interesting to you, be glad that other people are solving it for you. Um, so, uh, language models are definitely not guaranteed to generate well-formed tool calls. Um, and this is an example. Uh, you can see that this is JSON that's missing the uh, last closing bracket.
[27:36.320] So, this is poorly formed JSON. You put this into your JSON parsing program and it will throw an exception and you won't be able to get the uh, the data out of it. So I I've seen a million people go in and try to like figure out if the brackets are missing and like add one post hawk, but you don't want to be doing that. That's not not fun. Um so there's a bunch of constraints uh that you uh could be assigning to each of the tool calls. So the first one is syntax. So it has to be valid JSON. So this is kind of like table stakes, right? So it it needs to parse. Um the second thing is uh shape. So make sure that if you have expected or required fields, you have the required fields. Um the third thing is types. So uh you know if you have city, the city must be a string. Oh sorry. Yeah. Um yeah. So if you have a city, city is a string. Um if you have uh values, uh you know the units are in the appropriate units. So this can all be expressed through um something called JSON schema or basically any schema library. Um so it's like this is a city uh the type is string and the units can be uh Celsius or Fahrenheit and city is required. So um the the good thing about this is this has machine readable validation rules. So you can check if like a call uh follows the schema. But um one way that you can express whether the schema is valid or invalid is by defining a grammar over uh over the schema. And how many people uh did like contextf free grammarss or like context
[29:22.159] or those sorts of things? Regular grammarss. How many people know regular expressions? Okay. A lot of a lot of people. Okay. So a regular expression is a regular grammar. Um does anybody know how you can parse a regular expression? >> Finite state automaton. Yeah, that's exactly correct. Um so a finite state automaton uh for for those who are less familiar with this is something that looks a little bit like this. Um, so you have a state and every time you take a token as input, uh, you move to a different state. So if you get A, you would move to this state. If you get B or C, you move to this state. And This this works on uh something called uh uh regular grammarss. So regular expressions like the the slashes and dot stars and stuff like this that you might use to search for search text are uh reg are regular expressions and they can be expressed through regular grammars. Um JSON schema cannot be expressed through a regular grammar. um it can be expressed through something called a contextf free grammar and you can uh the context free grammar can basically make a tree that looks a little bit like this. So um every JSON expression can have brackets on the side. It can have commas between its members. Uh this can be a string um and this can be a unit. And if uh the JSON schema is in the correct format, you should be able to create a tree uh that looks like this. If the JSON schema is in the wrong format, you might create a be able to create create most of a tree. But then when you get to a unit, a unit cannot be K. So basically this would uh this would fail even though a unit can be K, but uh we we defined this to not accept Kelvin as our our unit of temperature.
[31:42.320] So um basically if you can parse uh the tool call with a contextf free grammar uh defined from your JSON schema you can uh you can do this and I'm not going to go into a lot of details but a finite state automaton cannot parse a um a contextf free grammar but there's something called a push down automaton that can allow you to do this. So basically it adds a stack to uh the regular grammar and uh you push things onto the stack uh pop things off of the stack and eventually can um eventually can decide whether it's uh parsible or not. And so what you do is you start out at the very beginning um with uh a state in this push down automaton and you step through and uh validate your output as you um as you generate it from left to right and I'm giving some examples from X grammar uh and X grammar is a thing that's actually pretty widely used in uh all of the LM inference libraries. It's actually developed by people in the machine learning department here. Uh so what you uh what this means is every time you get an LLM predict the logits of the next token, you take a look at your grammar and if the grammar says this is a valid next token, uh you get a score of one and if you have an invalid next token, you get a score of zero. And you set all of the invalid next tokens to negative infinity. um for the output logits and then you renormalize so that you get probability only on the valid tokens. And so what this uh lets you do is this ensures that you generate valid output. Um, and so this is another figure from the Xgrammer paper and they do these uh tricky things where basically there are some vocabulary that are always valid or always invalid and you premputee these and then there what there are those that are valid only in some contexts only in some uh stack context and then you calculate them on the fly. So it's uh
[33:58.960] very interesting algorithmically if you like algorithmic uh stuff. If you don't like it uh be glad that the people in the machine learning department are doing it for you basically. Um so because of this almost always um if you are uh if you are have this enabled you will uh and set your appropriate JSON schema you will get wellformed to tool calls. So that that's uh that's great.
[34:27.040] There's one case where you actually can't uh uh get well-formed tool calls despite this. Um may maybe I can give a quick quiz. This is very very difficult. So I don't know if anybody can get it. But any anybody have an idea where even this would not be uh not be enough. Need to be familiar with uh with LMS I guess. >> Yeah. Uh I I think that's close enough to what I I wanted to say. So basically um when you run out of tokens, so models can only generate so many tokens and you might run into a place where you're still on a valid path through the automaton, but you're not at the final state. So you generate like part of a JSON output. So very very good. Um and I
[35:17.520] I've actually encountered this. There's uh theoretically a way you could do that which is like you count the number of output tokens that you still have left and you you cut them off but that's uh if if somebody wants to implement that in next grammar as a extra credit assignment you know be happy to happy to have that okay so now um let's go to rest API calling um so there's uh two different ways to um there's different ways to Express tools and um I'd say probably most people are familiar with REST APIs. The these are the ways you interact with web services. Um but actually sorry there's one other way to call APIs and one way to call APIs is through programmatic tool calling where basically um you just give the model a Python program and you say use the stuff in this Python program to call tools. And so if you do something like that you might have like weather lib.py pi and uh you have the get weather function in here uh with its city and its units and uh then you just say call this function whenever you need to and you give it the ability to execute Python and it will be able to call that tool. So in programmatic tool calling this uh this works but this is not um callable remotely and it's also not callable from the like standard method of tool calling that you use um that you use when you uh implement this uh not through non-programmatic tool calling. So there's a way to turn this into uh REST APIs. Has anybody used fast API before? It's a pretty common Okay. a lot of people. It's a pretty common library.
[37:02.880] And basically what this allows you to do is this allows you to create a web uh web backend uh extremely simply by just uh setting up a fast API uh giving an API key so you can get people to validate against the API and then writing a Python decorator where uh weather becomes uh becomes this. And so this is good uh for a couple reasons. The first reason is maybe if you don't want people uh looking at the weather um then uh you can prevent them from looking at the weather. But probably more importantly if you don't want people like getting your personal data or something like that you can require an API key and uh this will uh allow you to block anybody who doesn't have an appropriate API key for instance. Um the other reason why is this gives you a JSON schema for free. uh and when I say for free of course you know this is something that's implemented in in fast API but your entire API can be expressed as a JSON schema and that JSON schema can then be provided as is to a language model and that language model can then use it uh to you know specify which calls are allowed and so then you could
[38:13.680] go in and process this and um whenever the agent made a tool call you could then send it to your API server and they it could use that on the API server Um, another option for calling these is you can just uh use the curl command. And the curl command um basically allows you to call these APIs uh directly like this as well. And so if you have a a coding agent that has access to bash, it has the ability to um to call like this. So this is maybe maybe reasonably straightforward if you're familiar with uh REST and stuff like this. Any any questions or comments or If you haven't played around with fast API, it's nice. It's very easy to use.
[39:00.640] But um the reason why I wanted to cover this first is this is kind of like the traditional way of of programming uh you know before agents. Um there's uh something called MCP the model context protocol and this was introduced by anthropic uh maybe twoish years ago or a year and a half ago and the idea was this is was designed to be a standard way to uh give your model additional context. When I first saw this I actually was like why do we need to do this? I don't understand why we need to do this. Let's uh let's just let our uh agents call APIs. Um but there is one uh important point about one one or two important points that make MCP different from just calling a normal API. Uh and I'll I'll explain them here. But um first I'll explain why I didn't real I didn't like I thought this was not actually necessary. And basically the reason why is every time you set up an MCP, what you do is you have your AI application and then you set up a couple MCP clients. So like maybe this is your weather client uh your this is your weather MCP and your uh your GitHub MCP or something like that. So you can ask what the weather is what the weather is and push it to your GitHub. Um uh and the reason why I didn't think this was necessary originally was because like why do you need to run a program to call an API, right? We already have good ways to call APIs. We just, you know, send it to the the REST API server.
[40:43.920] But um okay. Yeah. So so that's a little bit of an aside. Um, uh, I'll I'll get back to that in a moment, but for a little bit of an aside, uh, there's a really nice library called fast MCP. And fast MCP is basically designed to be fast API for MCP. So if you want to create an MCP server for whatever you want, you can um, just like basically swap out fast MCP and swap it uh, swap out fast API and swap in fast MCP and you can uh, create an MCP server very easily. Um, you can also take in a spec that was generated by like a REST API and just turn it in into an MCP as well. But here here's the main reason why you might want to use MCP uh as opposed to an API. Uh, and the reason why is because it gives you an extra layer of security. And so MCPs have an MCP API key. And this MCP API key uh is something that you need to provide to the process that's running your agent. Separately from this, you have the upstream API key. So like let's say you are getting um getting your agent to connect to your GitHub. The upstream API key would be your GitHub token and you would provide that to the MCP server,
[42:05.599] but you would not provide it to the agent. And then what you provide to the agent is the MCP API key, which allows you to authenticate into the MCP server. And so the reason why this is important is what happens if you give your agent the GitHub your GitHub token and your agent suddenly decides that it's a good idea to push that to your public GitHub repository. Not good, right? [laughter] Your account gets compromised and uh you get malware installed onto all your repositories or something like this. So you want to give the the agent something that is relatively harmless. Uh so that even if it leaks it for whatever reason like that leak is relatively harmless and then the um the actual credentials get get preserved and so that was basically
[42:51.280] the reasoning behind it. So um just to go into a summary, they all give you the ability to add a set of APIs into uh into your agent. Like you could do that through a regular JSON schema or through an MCP. Um the uh but a lot of other things are different. So like for discovery um you might need to fetch an open API uh document. For MCP there is a special API that allows you to list all of the tools. Um for invocation um you call an HTTP uh thing here for um MCP there's an MCP transport and this can be through various ways. You connect through standard IO or you connect through an H uh uh a socket or something like that.
[43:39.599] Uh I already talked about authentication and um MCP actually has a few other um has a few other like conveniences like you can add resources, prompts and extensions, but I'm not going to go into a lot of detail about that. Cool. Um actually, um there's two other things I'd like to mention. um there I don't want to uh I I guess I forgot to add them to my slide. Um so the first thing is um MCP registry. There's an official MCP registry. So if you want to find MCPS uh that allow you to do something like this, you can, you know, go to this registry and find uh any of a very large number of MCPS. There's also like a million and a half uh MCP server like websites that you can go to that are are ranked based on uh popularity and stuff like this. Another thing is um I've been talking a lot about the Pittsburgh weather and uh the funny thing is uh today I prepared all of these slides like earlier of course but today we actually got Pittsburgh weather that was simultaneously rainy and sunny at the same time. And so I managed to break my own API because it cannot return multiple states at the same time. But uh
[45:03.280] uh yeah, it was uh quite the coincidence. You can see the torrential downpour and the the bright side at the same time. Okay. Uh back back to serious stuff. Cool. Um so another big uh kind of like development pretty recently is parallel tool calling. in parallel tool calling. Um the the basic problem we want to solve is the same problem that I talked about when I talked about like the codec and the programmatic tool calling which is if you call tools one at a time. Um the uh it it could become very long for even a simple operation because you might do a weather and then do a calendar and then do a flight. Um, but if tool calls are independent, you can actually call them at the same time. And this is done pretty simply. You just like add add multiple tool call blocks to a single agent response. The um there's a few nuances about this. The first one is um you can only paralyze tool calls if they don't have dependencies on each other. So, um, like if you were looking up the weather for Pittsburgh and reading today's calendar and looking up flight status, that might be, uh, might be good. Um, but if you need to find a customer ID, use it to fetch orders and refund the selected order. Obviously, you can't do that. So, there's limits to the parallel tool calling you could do. And if your calendar or your flight was dependent on the weather, then you know, obviously that'd be a problem, too. So, there was a question about this. Um, do you execute the tool calls in parallel? And the answer is typically yes. You can just uh use typical Python uh syntax to you know have a whole bunch of tool calls and then execute them and then uh use something like async.io.gather to uh to return the results of them when they run in the same time. So this is uh uh this is
[47:01.119] pretty common. Another thing I'd like to point out is um this is a major difference between really efficient language models in note efficient language models. And there there's this weird weird paradox in agentic language models nowadays that more expensive models more expensive models can actually be cheaper if you measure them on a taskbytask basis. And there's two major reasons for this. The first major reason is more expensive models can be smarter. So they pick like an appropriate solution more quickly. Um but another thing is um more recent models do parallel tool calling uh a lot better. So they make a whole bunch of calls at the same time. So if you're using a coding agent or something like this, uh you use the the better uh you use the better models and they are doing like a bunch of view images at the same time or they're uh like writing a bunch of different files at the same time or something like that. That's because they're doing parallel tool calling. Well, um does anyone have an idea of like why they got so much better at this? They like this was not a huge thing even though parallel tool calling mechanisms have existed for a long time. This was not a huge thing until maybe like six months ago or something. Yeah. >> Reinforcement learning just forced them to do that. >> Yes. Exactly. So reinforcement learning uh kind of forced them to do that and so the models were very heavily incentivized to fish finish tasks quickly and parallel tool calling is one
[48:37.839] of the good ways to do that. So if you do reinforcement learning with a very heavy like brevity penalty on on how long uh the task execution is, you can get uh like a lot more parallel tool calling. Cool. So um the final thing I'd like to talk about in this lecture today is evaluating tool use. And so I'm not going to talk about evaluating endto-end agentic tasks immediately yet. um but rather talk about evaluating just the tool usability of language models because it's kind of like a prerequisite for language models to be good at um uh good at agentic tasks. And there's a bunch of data sets for this. The most famous one is the Berkeley function calling leaderboard and this has four versions. Uh it started out with version one which was basically um single turn uh tool calling. Um it's then evolved through the four versions and now it covers um multi-turn tool calling. It also does have aentic tool calling but this is more um not for like endto-end coding agents or something like that. It's uh tool calling agents and they also have tool calling robustness. So they measure um hallucination of arguments. They also measure format sensitivity. So when I talked about like the all the different formats uh they have uh parameters about that as well. So um when you uh go in to evaluate the whole uh stack there's a number of things that you want to uh evaluate. So the first thing is did the language model choose the appropriate tool for the task. So it might have picked like a an inappropriate tool that can't uh allow you to do that uh the task at all. Um the other thing is arguments uh which is uh you know whether you you add the right values. Um if you're talking about agentic tool calling you can talk about whether it did it in the right order and then you can uh measure endto-end task accuracy for if you're doing uh agentic tool calling. And all of these are kind of metrics in this leaderboard.
[50:52.559] Then separately from that there's also um efficiency. So like uh how quickly can you solve the task? Like um how many tokens did it take? How how much did it cost? Um reliability. So um you know if a tool call times out uh does it retry appropriately? If a tool is out of order, can it choose a a different one? And also um safety. So if you have adversarial outputs where you ask it to use a tool in an inappropriate way, uh can you do this? And all of these are like over the four iterations of this benchmark. It covers uh all of these dimensions. Um yeah, I kind of covered that already actually. So one other uh really interesting benchmark uh for tool calling is uh this open router uh tool
[51:43.280] call air rate benchmark. I don't know if anybody like uses open router or has seen this before. Maybe no. Okay. So um this is for the same model. All of these are for uh I think this is GLM 5.3. So it's like the same the same model and it's measuring the tool call error rate simply the only thing they varied is who serves the model to you. And this is uh this is pretty important obviously because you think oh I'm going to use this model maybe you know it's going to be the same regardless of who provides it to me but actually the difference is between 15% and like 0.01 to 0.05%. Any idea uh why this might be?
[52:40.319] There were some uh there were some hints in the lecture and some uh not some hints in the lecture >> is decoding algorithms different maybe someone's using like cheaper version of the model or quantized version of the model. >> Yeah, great great points. So I'll I'll repeat it. So number one is the decoding or the inference algorithm could be different and um one very big difference is whether they're using quantization of the model or not or like what level of quantization of the model they're using. So my my personal experience is um uh FP8 models uh FP8 is kind of like the default level of uh quantization for the model um get a lot fewer uh mistaken tool calls than FP4 models because FP4 is like compressing it very heavily.
[53:28.079] It's saving money for the inference provider, but it's it's usually a worse model. There aren't very many FP4 quantizations that can allow you to get the same performance. Another one was uh speculative decoding. Um I don't think we're going to talk about speculative decoding a huge amount in this class. Maybe I'll talk about it during long context or actually may there are a few algorithms specifically for agents which are interesting. So maybe we can talk about it. But basically what it is is you have another cheaper model um that predicts what the more expensive model is going to do and then you use that to like speed up your inference. um spec lossless speculative decoding probably shouldn't make a difference because it it's like not changing the underlying result of the model. But if they're doing some sort of like lossy speculative decoding uh then that might might cause it to be different. But then you know calling it the same model is also probably a bad uh a bad idea. Uh there's one other thing um that I
[54:27.920] mentioned uh and anybody have an idea this was actually mentioned in the uh in the class today. What can you do to make your tool calls more successful? >> Yeah. >> Constraint decoding. Yeah, exactly. So these different providers might be using different constraint decoding algorithms. Um just practically many many of these providers will be implementing their own inference algorithm. So they'll have their own inference algorithm completely implemented from scratch. Um some of the providers will be using an open source one like VLM or SGLANG. And VLM or SG lang support different grammar-based decoding uh algorithms. And so uh some of these providers just might not have that implemented and so they're entirely relying on the language model to do good tool calls. Um otherwise uh they might not. A final kind of like boring reason why tool calls might fail is the inference provider might be unreliable. So it might go down some of the time and then the tool call would fail. Cool. Um so these are the um that that's the main thing that I I had for today.
[55:49.280] Um so tool use is basically a layered system. Um you know the tools add capabilities such as retrieval, execution, generation, application. They're what make an agent an agent. Uh but we can't get that uh for free. And um you can uh add schemas to the prompt. Uh the models emit calls and then you validate dispatch and match results by ID. And we can add constraints uh like grammar-based decoding. um they don't guarantee semantic correctness. So um if you have like a Python program, the Python program might still be wrong even if you generated uh you know a string that could be parsed as Python. Um and there's a number of uh ways you can interface with them like direct rest calls and MCPS. Uh and then we have a lot of systems that um orchestrate dependencies and concurrency and uh allow us to evaluate. So yeah, that that's uh what I wanted to talk about for tool calling. Uh this will be something that is covered in the harness uh assignment or the first assignment where you build your agent.
[56:53.280] So you'll need to need to deal with this. Um but and next time we're going to talk about context management for long context in long context LMS. But um any questions to wrap up? Okay. Yeah. Yeah. And I'm going to repeat in case people didn't hear in the back, but the first um uh assignment for reflecting on the lecture and talking about something you learned in the lecture is going to be up on Canvas. So, make sure you uh make sure you submit it. Thank you.
