← 进阶 vibe coding让 AI 通过工具获取信息和执行操作

免费文章 · 05 理解工具、工作流与 Agent

让 AI 通过工具获取信息和执行操作


  上一节,我们讨论了怎样根据任务特点组合模型与工作步骤,并结合效果与成本,选择合适的工作方式。接下来,我们要让这些安排真正连接到外部系统:从应用中读取当前资料,再把生成的内容保存为以后能够继续读取、修改的草稿。

  比如,我们要求 AI“参考最新资料,写完后保存”。但模型该通过什么工具取得资料?草稿应该保存到哪里?操作完成后,又怎样取得实际结果?这些问题不仅涉及工具怎样调用,也涉及我们应该为 AI 提供什么样的工具。

  这一节,我们先理解模型与程序怎样通过工具协作,再从实际任务出发,学习如何设计职责清楚、粒度合适的工具,并让它们返回后续工作需要的信息。随着工具增多,我们还会学习怎样组织和提供这些能力,最后通过真实调用记录,检查工具设计是否真正满足任务需要。

工具怎样连接模型与外部系统

  当资料保存在外部应用中,模型要使用最新内容,就需要有办法读取它;如果还要保存生成的草稿,也需要有执行写入的能力。工具就是模型与外部系统之间的连接。

  例如,模型提出读取当前作品要求的请求,工具程序取得资料,再由运行环境将结果提供给模型;保存草稿时,则通过工具把标题和正文写入指定章节。工具既能让模型取得当前需要的信息,也能执行改变外部系统状态的操作。

  工具可以由应用自行实现,也可以使用平台提供的搜索、计算或浏览等能力。无论工具来自哪里,都需要让模型知道有哪些操作可以使用、需要提供什么参数,以及执行结果怎样返回。

一次工具调用是怎样完成的

  我们常说“AI 调用了保存工具”,但实际完成一次调用,需要模型与运行环境共同配合。以应用自行提供的工具为例,可以分为四个环节:

  1. 应用提供工具定义。 名称和说明告诉模型工具能做什么、什么时候适合使用;参数结构说明需要提供哪些字段及其类型。实际执行程序仍在应用一侧。
  2. 模型生成调用请求。 模型根据当前任务选择工具,填写参数,返回结构化的调用请求。
  3. 运行环境执行操作。 应用接收请求,将参数交给对应的工具程序,由程序检查输入和业务条件,再执行读取或写入。
  4. 执行结果返回模型。 运行环境将读取内容、保存回执或错误信息提供给模型,供它继续工作。

  图中,蓝色箭头表示调用请求,绿色箭头表示执行结果。真正的正文写入发生在右侧工具程序中。模型负责提出请求,运行环境负责执行和回传。

  在常见的工具调用协议中,每次请求都有对应的调用标识,用于关联请求与返回结果。这样,即使同一个工具连续调用多次,或者多个请求并行完成,也能准确区分每份结果来自哪次调用。

  一次模型返回也可能包含多个工具调用。彼此独立的读取可以并行执行;如果下一步依赖前一次的结果,就需要等结果返回后,再确定接下来的操作。

从任务倒推需要哪些工具

  了解工具怎样工作后,接下来就要决定:我们究竟应该为 AI 提供哪些工具?

  应用内部可能已经有大量接口,但这些接口通常按数据和功能模块组织,而 AI 面对的是具体任务。如果直接把所有接口交给模型,原本可以由程序完成的查找、拼接和整理,也可能变成模型需要逐步处理的工作。

  因此,设计工具时,我们可以从任务倒推:需要哪些外部能力?每个工具应该负责多大范围的工作?又需要返回什么结果?

找出任务需要的外部能力

  先看任务要完成什么,以及哪些工作需要借助外部系统。模型可以根据已有资料组织情节、撰写正文,但读取应用中的最新记录、查询章节状态和持久保存草稿,都需要相应的程序支持。

  以“完成第一章并保存为待审草稿”为例,我们可以整理出四项需要:

任务中的需要

对应工具

职责

取得当前要求、设定和大纲

read_work

提供写作依据

读取指定章节

read_chapter

取得正文与修订信息

了解已有章节

list_chapters

返回章节目录与状态

保存待审草稿

save_draft

按业务条件写入指定章节

  这样,工具的设计就有了明确依据。我们需要的是完成任务所必需的能力,而不是先凑齐一套增删改查接口。 本次没有删除作品或正式采用稿件的要求,就不必额外开放这些操作。

确定工具的职责与粒度

  知道需要哪些能力后,还要决定一次调用负责多少工作。

  如果工具拆得太细,模型就需要完成更多调用和中间处理;如果封装得太多,又可能把原本需要分别判断的操作绑在一起。我们可以根据实际任务,在三种设计方式之间选择:

设计方式

工具示例

主要特点

基础操作

read_file、write_file

灵活,但模型需要自行处理文件路径和业务约定

业务动作

read_chapter、save_draft

对象和职责明确,程序可以落实相应规则

组合能力

get_writing_context

把多个相关操作封装在一个工具中,一次返回整理好的结果

  那么,什么时候值得把多个操作合成一个工具?

  关键要看中间是否还需要模型作出判断。例如,按照指定章号取得要求、目录和已有正文,如果这些资料总是一起使用,就可以考虑让程序统一整理,再交给模型写作。这样能减少机械的读取与拼接。

  但如果任务只是修改一段对白,直接读取对应章节可能更合适,没有必要每次都取得整套写作资料。工具应该封装多少工作,要由实际使用需要决定。

  另外,组合工具时还要考虑操作后果。保存草稿与正式采用虽然都涉及章节状态,却需要不同的确认条件。比如,本次只授权 AI 保存待审草稿,正式采用仍由人决定,因此不应把两个动作合并成一次自动执行。

让模型理解工具的用途和结果

  划分好工具的职责,接下来还要让模型知道什么时候使用、怎样使用。模型主要依据工具的名称、说明和参数结构选择调用,因此,这些信息需要准确表达工具的用途与要求。

名称、说明和参数怎样配合

  名称帮助模型辨认动作,说明交代适用情形和使用边界,参数结构则约定调用时需要提供什么。三者共同回答:这个工具能完成什么、什么时候应该使用、需要哪些输入。

  例如,“管理作品”很难区分读取、保存还是删除;“将指定章节保存为待审草稿”则明确了操作对象和结果。如果同时提供保存草稿与正式采用的工具,还要说明两者在什么条件下使用。

  参数同样需要清楚。对象标识、数据类型、取值范围和格式应当明确,能够用枚举或结构化字段表达的条件,就不必全部交给自由文本。对于应用已经确定的作品标识,也可以由程序直接提供,减少模型填写错误的机会。

  不过,参数结构负责约束输入形式,操作权限和业务条件仍需要程序在执行时检查。

返回内容要支持下一步工作

  工具返回的结果会成为模型后续工作的依据。它可以是文字、结构化数据,也可以包含所用接口支持的图像或文件。除了实际内容,还可能需要提供来源位置、对象标识和当前状态,让后续操作能够准确衔接。

  例如,读取章节时,模型需要正文才能理解内容,也可能需要章节编号和修订信息来完成后续保存。如果检索结果很多,可以先返回相关片段和读取位置,需要时再取得完整内容。

  返回内容不是越多越好,而是要让模型获得完成下一步所需的信息。

  比如,save_draft 保存成功后,可以只返回章号、修订和草稿状态;需要核对完整正文时,再通过读取工具取得。这样既保留了必要的操作依据,也避免在保存回执中重复返回整篇文章。

  对于需要程序继续处理的结果,应提供稳定的结构化字段;需要模型理解的内容,则要保留清楚的含义。结果只返回了一部分时,也应说明范围,并提供继续读取的方式。

由程序落实操作条件和失败处理

  模型知道怎样调用工具以后,还需要保证这些请求能够被正确执行。工具说明帮助模型选择操作,真正的权限与业务条件则由程序负责落实。

  例如,读取资料时,需要确认当前用户有权访问;保存草稿时,还要检查目标章节、当前状态以及是否允许覆盖。即使外部文档要求执行某项操作,也不能因此获得超出当前授权的权限。

  这里我们通过草稿修订理解程序的作用。模型生成新稿时,会依据当时读取的章节修订提出保存请求。如果在此期间,人已经修改了正文,程序就应拒绝使用旧修订的保存请求,避免覆盖新内容。

  这样,“不要覆盖人的修改”不只是一句提示要求,而是由保存程序实际执行的业务规则。

  操作失败时,返回结果也应帮助后续处理:参数有误,就说明哪项输入不符合要求;修订已经变化,就提示重新读取;权限不足,则明确当前限制。

  此外,还要说明操作是否已经生效。如果写入结果尚不确定,就需要保留这一状态,供后续核查,避免贸然重复执行同一个操作。

工具多起来以后,怎样组织和提供

  工具较少时,模型容易辨认各自的用途。但随着应用接入更多业务,相似的操作可能出现在不同领域,工具定义也会占用更多上下文。这时需要考虑两个问题:怎样让模型区分工具的用途,以及怎样让它只接触当前需要的能力?

用命名空间组织工具

  命名空间可以把同一领域的工具组织在一起。 例如,一个同时处理小说写作和视频素材的工作台,可以用 writing 组织章节与设定工具,用 media 组织素材工具。两者都可能提供搜索功能,但所属领域不同,模型也就更容易判断该使用哪一个。

  有些接口采用扁平的工具名称,也可以使用 writing_search、media_search 这样的前缀表达归属。

  分组不必追求复杂。工具较少、用途明确时,直接使用清楚的名称即可;只有当业务增多、工具容易混淆时,才值得引入更细的组织方式。命名空间帮助区分用途,并不改变工具本身的操作权限。

按当前任务提供工具,按需发现其余能力

  分组解决了工具怎样辨认的问题,但如果每次仍把全部工具定义提供给模型,上下文负担并不会因此减少。

  因此,应用可以根据当前任务、权限和工作阶段,选择需要提供给模型的工具。例如,整理访谈素材时,先提供检索、读取和保存方案的能力;如果之后需要制作字幕,再补充相关工具。

  对于工具数量较多、任务需求又难以提前确定的情况,还可以借助宿主支持的工具发现与按需加载机制,在需要时取得其他工具的详细定义。

进阶:按需发现与加载工具

  当工具数量较多时,支持工具搜索的宿主(Codex、Claude Code、ChatGPT、AI API)可以先向模型提供工具概览或发现入口,再根据任务加载相关工具的完整定义。

  这与《渐进式信息披露》中的资料组织方式相似:先知道有哪些能力可用,再按需取得具体说明。

  需要区分的是,工具服务端的完整注册目录,与当前进入模型上下文的工具定义,并不是一回事。 按需加载通常由宿主负责,具体能力取决于所用系统。

  发现工具本身也有成本。工具较少时,直接提供往往更简单;当每次只使用大量工具中的一小部分时,再考虑按需加载是否更合适。

继续阅读官方资料

  如果希望进一步了解工具设计与实现,可以根据需要查阅以下官方资料:

用真实任务检验工具设计

  工具设计好以后,我们还需要通过实际任务检查:模型能否选对工具、填写正确参数,返回的信息是否足够,以及工具的职责和粒度是否合理。

  接下来,我们用同一项章稿任务,比较“分散读取”和“组合读取”两种方式。把几个读取操作合成一个工具,能否减少不必要的调用,又会不会带来重复的信息?

运行工具读写实验
  1. 沿用已经准备的课程实验仓库,启动公共页面,打开工具读写实验。
  2. 先根据任务判断需要哪些外部能力,选择“分散读取”或“组合读取”,运行一个条件;也可以加载本节课堂实录,观察两种条件。
  3. 对照模型实际选择的工具、输入参数、返回内容和程序独立读回。需要比较另一种设计时,保持任务与模型配置相同,只切换工具集。

  实验要求 AI 完成第一章,并保存为待审草稿。两组使用相同的资料、初始状态和保存规则,只改变读取工具的组织方式。

条件

提供的工具

主要观察什么

分散读取

read_work、list_chapters、read_chapter、save_draft

模型怎样选择不同工具、取得所需资料

组合读取

get_writing_context、read_chapter、save_draft

合并读取后,是否减少调用和重复信息

  我们可以先查看课堂实际使用的工具定义,再对照模型发出的调用请求,看看工具说明怎样影响模型的选择。

查看课堂使用的工具定义

  下面是实验中实际提供给模型的 save_draft 工具定义。留意它的名称、用途说明和参数结构:模型需要知道什么,才能正确提出保存请求?

plaintext
{
  "type": "function",
  "function": {
    "name": "save_draft",
    "description": "保存第一章草稿。使用读取到的作品与正文修订;修订过旧时拒绝保存并要求重新读取。回执只有标识和状态,正文可另行读取。",
    "parameters": {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "type": "object",
      "properties": {
        "chapterNumber": {
          "type": "number",
          "const": 1,
          "description": "本次教学任务的第一章"
        },
        "expectedWorkRevision": {
          "type": "integer",
          "exclusiveMinimum": 0,
          "maximum": 9007199254740991
        },
        "expectedChapterRevision": {
          "type": "integer",
          "minimum": 0,
          "maximum": 9007199254740991
        },
        "title": {
          "type": "string",
          "minLength": 1
        },
        "body": {
          "type": "string",
          "minLength": 1
        }
      },
      "required": [
        "chapterNumber",
        "expectedWorkRevision",
        "expectedChapterRevision",
        "title",
        "body"
      ],
      "additionalProperties": false
    }
  }
}
查看一次实际工具请求

  本次任务只说明要完成什么,没有规定工具名称和调用顺序。下面是模型实际提出的一次读取请求:

plaintext
{
  "name": "read_work",
  "arguments": {}
}

  可以看到,模型选择了 read_work,没有额外填写参数。这是因为当前作品已由应用绑定,无需模型再次指定 workId。其他操作所需的章号、正文等信息,则通过对应工具的参数提供。

  下面是分散读取组中 read_work 的实际返回。模型通过工具取得了当前作品要求、设定和大纲,接下来就可以根据这些资料生成章稿。

  取得资料后,模型调用 save_draft 保存草稿,再通过 read_chapter 读取已保存的正文。

从调用记录发现下一步改进

  两组都完成了资料读取、草稿保存和读回确认。我们先看分散读取组的保存结果,以及程序独立读回的内容:

查看保存参数与独立读回

  在“工具读写实验”中选择“分散读取”,展开 save_draft 的“参数与原始返回”,查看模型实际提交的保存参数。

参数

本轮的值

含义

expectedWorkRevision

1

依据第 1 版作品要求

expectedChapterRevision

0

保存前第一章尚无正文

  程序会核对这些修订是否仍然有效,避免用旧内容覆盖新的修改。本次保存成功后,章节修订变为 r1。

  再查看“程序独立读回”,将数据库中实际保存的正文,与保存请求及模型随后 read_chapter 取得的内容对照,确认三者是否一致。

  核对两组实际保存的数据库,正文都与保存参数及后续读取结果一致。可以确认,两种工具设计都完成了本次保存任务。

  不过,再比较调用过程,就会发现一个值得注意的差异:

条件

保存前怎样取得资料

工具调用 / 模型请求

分散读取

读取作品要求和章节目录

4 次 / 4 次

组合读取

读取组合上下文,又单独读取当前章

4 次 / 4 次

  组合工具已经包含当前章的状态,模型却又调用了 read_chapter,重复取得“尚无草稿”的结果。把多个读取操作合成一个工具,并不意味着模型就会自动减少重复调用。

  那么,问题可能出在哪里?我们可以先检查 get_writing_context 的说明,是否明确告诉模型已经返回了哪些内容,以及什么情况下才需要单独读取章节。

  下一轮可以针对这些说明进行调整,再用相同任务比较:重复读取有没有减少,模型是否仍能取得完整依据,保存和读回是否正常。工具粒度是否合理,最终要看它能否让任务完成得更顺畅,而不是只看工具数量减少了多少。

  本轮每种条件只运行了一次,还不足以判断哪种设计始终更好,但已经为下一次改进提供了具体方向。

为访谈剪辑方案确定工具边界

  现在,我们要让 AI 从一批访谈素材中,找到某位人物谈“第一次接手项目”的原话,标明素材和时间位置,整理成待审剪辑方案。应用已有素材库和逐字稿,本次不需要修改原片或发布视频。

  应该为 AI 提供哪些工具? 哪些读取操作值得组合,哪项写入应独立保留?如果工作台还有字幕、画面生成和发布等数十个工具,又应该怎样组织和提供?

查看答案与解析

  可以先提供访谈片段检索工具,由程序完成逐字稿搜索与素材定位,返回相关原话、素材标识、时间范围及必要上下文。如果需要进一步核对,再提供精确读取工具。

  剪辑方案则通过独立的 save_edit_plan 工具保存,由程序核验素材和时间范围,返回方案标识、修订与待审状态。保存方案不需要同时开放修改原片和发布视频的能力。

  工具增多后,可以按素材、字幕、生成、发布等用途组织。本次先提供检索、读取和方案保存工具;其他能力在需要时再通过支持工具发现的应用或 API 加载。

  这样,工具的选择与组合就来自当前任务,而不是机械地提供全部接口。

  通过这一节,我们不仅了解了工具调用怎样完成,也学会了从任务出发设计工具,再根据实际记录检查它们是否好用。

  不过,工具返回结果后,任务可能还需要继续。下一节,我们将进一步学习 Agent 怎样根据工具反馈决定下一步行动,把多次调用组织成连续的工作过程。

讨论

登录后参与讨论