如果你已经会写页面、调用接口和处理加载状态,就可以开始理解 Agent 开发。
我们先从一句话开始:Agent 应用让 AI 根据用户的目标选择下一步,再由你写的程序执行。
这句话里的“选择”和“执行”分别是谁负责,是理解 Agent 的关键。下面用一个博客助手,把这件事一步步拆开。
本文讲的是如何开发这样的应用。你不需要先训练一个模型,也不需要一开始就掌握一堆 AI 框架。
一、先看一个你已经会做的页面
假设你要给博客做一个文章管理页面,页面上有三个功能:
- 点击“查看文章”,显示已经发布的文章。
- 输入关键词,点击“搜索”,查找相关内容。
- 编辑好文章,点击“保存草稿”,保存当前内容。
其中,“查看文章”的逻辑可能是这样:
async function getPosts() {
const response = await fetch("/api/posts")
if (!response.ok) {
throw new Error("Failed to load posts")
}
return response.json()
}
用户点击按钮,事件处理函数调用 getPosts(),然后把返回结果显示到页面上。
用户点击按钮 → 程序调用接口 → 接口返回数据 → 页面显示结果
这里,什么时候查询、搜索什么、要不要保存,主要由用户操作和你写好的页面流程决定。
现在我们希望用户少点几个按钮,只说一句话:
看看我已经写过哪些文章,帮我推荐三个还没写过的 React 选题。
这就开始接近 Agent 的使用场景了:用户描述想达到的目标,应用需要安排中间的操作。
二、接入一个 AI 聊天框,就能完成吗?
我们先做最简单的一版:把用户的话发给模型,让它回答。
模型可能推荐:
可以写 React 入门、useState 用法和 useEffect 用法。
但问题来了:你的博客可能早就写过这三篇。
如果应用没有把文章列表提供给模型,它就没有可靠依据判断你写过什么。 即使模型给出了自信的回答,也不能说明它真的查询过你的博客。
你当然可以直接编写一个固定流程:
程序先查询文章 → 把文章列表和用户问题发给模型 → 模型推荐选题
如果需求一直这么简单,这样就够了。
接下来,我们给它多一点灵活性:当模型需要了解已有文章时,可以请求查询;如果标题信息不够,还可以请求读取某篇正文。这个时候,就需要介绍“工具”。
三、工具,就是你允许 AI 调用的业务能力
你已经有一个 getPosts() 函数,可以查询文章。
要把它开放给模型使用,需要告诉模型两件事:
- 这个能力叫什么:
getPosts。 - 什么时候使用:需要了解本站已经发布的文章时使用。
工具如果需要参数,还要说明参数的名称、类型和用途。例如搜索工具需要一个关键词。
给模型看的,是工具的说明和参数格式;真正执行查询的函数,仍然由你的程序负责。
模型不会因为听说了 getPosts 这个名字,就直接访问你的数据库。
它会通过模型服务的工具调用机制,返回一个类似这样的请求:
{
"name": "getPosts",
"arguments": {}
}
这是为了理解而简化的结构,不是某个 SDK 的完整响应。
你的程序收到之后,检查这个工具是否允许调用、参数是否有效,再执行对应的函数。不要执行任意生成的代码,也不要把未知工具名当成可以运行的命令。
用一段交互记录来看,会更直观:
用户:推荐三个我还没写过的 React 选题。
模型返回工具请求:
getPosts()
程序执行查询,把结果交回模型:
- React 入门
- useState 基础
- useEffect 基础
模型返回最终回答:
可以考虑状态提升、组件组合、表单状态管理。
下面分别说明它们适合解决的问题……
注意,中间“查询文章”这一步是程序真实执行的。页面上的一句“正在查询文章”,本身并不代表查询发生过。
这个过程就叫 Tool Calling,也就是工具调用。
你可以先把它记成:
用户原来通过按钮调用的业务能力,现在也可以由 AI 提出调用请求。
四、为什么还需要“循环”?
刚才的例子只查了一次文章,就给出了回答。
但有时事情不会这么顺利。假设文章列表里有一篇叫《React 实战笔记》,光看标题,很难判断它是否已经讲过“表单状态管理”。
如果你提供了 readPost 工具,模型就可以继续请求读取正文:
第一轮:模型请求 getPosts
程序返回文章列表
第二轮:模型请求 readPost,读取《React 实战笔记》
程序返回正文,发现里面已经讲过表单状态管理
第三轮:模型根据正文调整选题
返回三个建议和对应理由
上一轮拿到的结果,会影响下一轮选择的动作。 这就是 Agent 执行循环最值得理解的地方。
负责协调这个过程的,是你写的程序:
把用户目标和已有信息发给模型
↓
模型返回了什么?
↙ ↘
工具调用请求 最终回答
↓ ↓
检查后执行工具 把回答交给用户
↓
把工具结果加入已有信息
↓
继续调用模型
这里不是让模型无限运行。程序要规定最大执行次数和每次调用的超时;信息不够时,也可以停下来请用户补充。
例如,用户没有说明想写哪个技术方向,应用可以询问:
你更想写 React 基础,还是项目实战?
所以你写的不只是一个请求函数,还包括“什么时候继续、什么时候等待、什么时候结束”。
五、前端、服务端和模型分别负责什么?
现在把这几个角色放到一起:
| 角色 | 在博客助手里负责什么 |
|---|---|
| 用户 | 提出目标,补充要求,审阅结果 |
| 前端页面 | 接收输入,展示进度和结果,提供取消等操作 |
| 服务端程序 | 调用模型,检查并执行工具,管理任务是否继续 |
| 模型 | 根据收到的信息,提出工具调用或生成回答 |
| 业务接口 | 真正查询文章、读取正文或保存草稿 |
可以把它们之间的关系画成这样:
前端页面 ←→ 服务端程序 ←→ 模型
↕
业务接口
在这个例子里,模型密钥和工具执行放在服务端。浏览器主要处理用户交互,不需要持有模型密钥。
对于前端开发者,很多工作还是熟悉的,只是页面需要表达更多状态:
| 你熟悉的工作 | 在 Agent 页面里的变化 |
|---|---|
| 输入框 | 收集“帮我完成什么”的目标 |
| loading | 显示正在查询文章、读取正文等具体进度 |
| 接口错误提示 | 告诉用户哪一步失败,能否重试 |
| 列表或卡片 | 展示选题、推荐理由和参考文章 |
| 表单确认 | 让用户检查准备保存的草稿 |
| 状态管理 | 区分执行中、等待补充、完成、失败、已取消 |
进度最好来自程序实际发生的事件。例如查询接口确实返回了五篇文章,再显示“已找到 5 篇文章”。
“取消”也需要前后端配合:页面通知服务端停止任务,服务端再尝试中止正在进行的调用。仅仅隐藏 loading,不代表后台已经停止。
如果你只负责页面,可以和后端约定好任务接口及状态。如果你要独立完成整个应用,就需要再掌握服务端的模型调用和工具执行逻辑。
六、AI 能调用接口,是不是就可以让它随便操作?
这里可以直接套用你熟悉的后端鉴权思路:请求来自模型,也一样要经过检查。
例如,给助手增加“保存草稿”能力时:
- 服务端确认当前用户是否有保存权限。
- 检查标题、正文等参数是否符合要求。
- 页面按产品约定展示待保存内容,让用户确认。
- 确认后调用保存接口,成功了再显示“已保存”。
你不能因为模型说“用户已经同意”,就跳过程序里的确认记录;也不能因为模型生成了符合 TypeScript 类型的数据,就认为所有参数都合法。
还有一个容易忽略的问题:保存请求超时,不一定代表没有保存成功。重试时要能识别同一次保存操作,避免生成两份草稿。
初次练习时,可以只开放查询和读取工具。先跑通获取真实信息、生成答案的过程,再增加写入能力,会更容易理解和排错。
七、什么时候需要 Agent,什么时候固定流程就够了?
把同一个博客里的三个功能放在一起,就能看出区别:
| 需求 | 可以怎么做 | 原因 |
|---|---|---|
| 把一个中文标题翻译成英文 | 一次模型调用 | 输入和目标都很明确 |
| 查询文章,生成摘要,再翻译摘要 | 固定工作流 | 主要步骤可以提前写好 |
| 检查已有内容,遇到不明确的地方再读正文,最后推荐选题 | Agent | 后续操作取决于前面查到了什么 |
这也是一种常见的工程区分:工作流主要由预先写好的代码安排步骤,Agent 则让模型参与动态选择下一步。参考:Anthropic — Building effective agents
在实际产品里,两者可以一起使用。例如“选题推荐”让模型灵活判断,“保存草稿”继续走固定的校验和确认流程。
可以先问自己:
下一步操作能不能提前确定?还是必须看到前一步的结果,才能决定要查什么、做什么?
需要动态判断时,才值得进一步评估 Agent。普通代码也能根据结果分支;关键是这个判断是否适合交给模型,以及它是否比固定规则带来更好的效果。
八、先记住四个词,再做一个小练习
现在再看术语,就没有那么抽象了:
- 模型:根据输入生成回答,也能提出工具调用请求的 AI 服务。
- Prompt(提示词):你交给模型的任务说明,例如“推荐三个适合初学者、且尚未写过的选题”。
- Tool(工具):程序允许模型请求使用的能力,例如查询文章。
- Context(上下文):这次调用模型时,实际提供给它的信息,例如用户要求、文章列表和刚读取的正文。
这里的上下文很像你调用一个函数时传入的数据:页面上有某条信息,不等于模型就收到了它。要让模型参考文章列表,程序就需要把列表加入请求。
至于 RAG、MCP、长期记忆和多 Agent 协作,可以在需要时再学习。理解前面的工具调用和执行循环,就足够开始第一个小功能。
可以按这个顺序练习:
- 做一个输入框,把用户的问题发给模型,显示回答。
- 提供一个查询已有文章的工具,让模型能够请求使用它。
- 把工具查询结果交回模型,让它据此推荐选题。
- 在页面显示“正在查询”和“已完成”,并处理查询失败。
- 测试空文章列表、工具报错和推荐重复选题,检查结果是否符合预期。
这时,别只看回答是否流畅。打开任务记录,确认工具真的执行了,返回的数据真的被交给模型,推荐的选题也没有明显重复。
你会发现,前端开发经验可以一直用得上:接口定义决定有哪些能力,状态管理决定用户看到什么,异常处理决定失败后怎么办。Agent 开发在这些基础上,增加了一个由模型参与选择下一步的过程。