Docs/建立正确心智模型1

为什么需要 Agent,而不只是 Chat API

10 min read·185 LOC·0 tools
Agent 不是会聊天的模型,而是能在状态中持续决策和行动的系统。

很多人第一次做 AI 应用时,都会从一个很自然的起点开始:把用户输入丢给模型,然后把模型输出展示出来。

这当然没错。事实上,很多场景根本不需要 Agent,一个简单的 Chat API 就能解决问题。问题在于,当任务开始要求模型去找信息、做判断、执行动作、根据结果修正下一步时,单轮对话就会越来越吃力。

这一章的目标,就是把这条边界讲清楚。我们不会急着写复杂代码,而是先建立一套后面整本教程都会反复用到的心智模型:什么时候只需要一个“会回答”的模型,什么时候你其实需要的是一个“会持续决策和行动”的系统。

从 Chat API 开始#

假设我们要做一个最小 AI 问答页面,代码可能像这样:

TypeScript
const response = await model.generate({
  system: "你是一个 TypeScript 助手",
  prompt: userInput,
});
 
return response.text;

这个模式非常适合下面这类任务:

  • 改写一段文案
  • 解释一个概念
  • 把一段中文翻译成英文
  • 根据你已经提供的上下文做总结

这些任务的共同点是:模型只需要基于当前输入生成一个输出。它不需要自己查资料,不需要调用工具,也不需要把问题拆成多个步骤。

我们可以把这类系统称为 Chatbot,它的核心职责只有一件事:接收输入 -> 生成回复

这类系统简单、便宜、延迟低,而且已经能覆盖非常多的真实需求。
所以在继续往下之前,先记住一个重要判断:

不是所有 AI 应用都需要 Agent。能用简单方案解决的问题,就不要先把系统做复杂。

再看 Workflow#

当单轮问答不够时,很多团队会自然走到第二步:加一条固定流程。

例如,我们希望系统完成这样一个任务:

读取一篇文章,提取重点,再输出一页摘要。

这时我们可能会写出如下流程:

  1. 先调用模型提取文章大纲
  2. 再调用模型把大纲整理成摘要
  3. 最后调用模型润色语言

这已经不是简单的聊天了,而是一个 Workflow。它比 Chat API 更强,因为它允许我们把任务拆成多步。但它仍然有一个很明显的特点:每一步都是预先写死的

这类系统适合处理:

  • 流程稳定
  • 输入结构固定
  • 每一步都可以提前设计好的任务

例如:

  • OCR 后做结构化提取
  • 客服工单分类后再分发
  • 会议录音先转写再总结

它的优点是稳定、可控、容易调试;缺点也很明显:只要真实情况稍微偏离预期,固定流程就会开始别扭。

问题在决策#

来看一个更接近 Agent 的任务:

帮我阅读这个 TypeScript 项目,告诉我怎么启动它;如果 README 不完整,就继续查 package.json 和配置文件。

这个任务麻烦的地方,不在于“模型要写出一段文字”,而在于它必须自己决定:

  • 先看哪个文件
  • README 是否已经足够
  • 如果不够,下一步该读 package.json 还是 tsconfig.json
  • 如果遇到多个脚本,哪个更可能是启动入口
  • 是否还要继续查别的线索

这时你很难提前写出一条完全固定的流程,因为系统是否继续、往哪走、何时停止,都依赖中间结果。

这就是 Agent 出场的地方。

Agent 是什么#

这套教程里,我们采用一个非常工程化、也非常克制的定义:

Agent 是一个围绕状态运行的系统。它会根据当前目标和已有观察,决定下一步动作,并把动作结果写回状态,再继续决策,直到任务完成或停止。

这个定义里最重要的不是“智能”,而是下面这几个要素:

  • 目标:当前想完成什么任务
  • 状态:系统目前已经知道什么
  • 动作:下一步可以做什么
  • 观察:动作执行后得到了什么结果
  • 停止条件:什么时候应该结束

把它写成最小形态,大概就是下面这个闭环:

TypeScript
while (!done) {
  const nextAction = await decide(state);
  const observation = await act(nextAction);
  state = update(state, observation);
}

请注意,这里最关键的不是模型本身,而是这个循环。

模型只负责一部分工作:根据当前状态判断下一步该做什么。
真正让系统像 Agent 的,是它具备了“行动之后再看结果,并基于结果继续前进”的能力。

三种系统的差别#

我们可以把三者放在一起看:

类型核心机制适合的问题主要局限
Chatbot单轮输入输出问答、改写、总结、翻译不会主动查资料,不会多步行动
Workflow预先设计好的多步流程流程稳定、结构明确的任务遇到分支和例外时不灵活
Agent根据中间结果持续决策开放式、多步、路径不确定的任务更复杂,成本更高,更难调试

可以把它们理解成三种不同的工程选择,而不是三种“能力等级”。

这点很重要。
Agent 不是 Chatbot 的升级版,也不是 Workflow 的上位替代。很多时候,最好的系统反而是:

  • 外层是固定工作流
  • 某个节点里嵌一个 Agent
  • 简单节点仍然只用普通模型调用

也就是说,Agent 是一种可选能力,而不是所有 AI 系统的默认答案。

用同一任务来比较#

我们用同一个任务来比较三种方案:

用户问:“这个项目怎么启动?如果 README 没写清楚,请自己继续找。”

Chat API#

你只能把已有内容直接喂给模型,然后让它回答。

如果没有额外上下文,模型只能猜。
如果你手动把一堆文件都贴进去,模型上下文又会迅速膨胀。

Workflow#

你可以设计:

  1. 先读 README
  2. 再读 package.json
  3. 最后输出启动步骤

这样已经比单轮问答强很多,但它默认这三步总是正确的。如果 README 已经足够,这个流程还是会继续执行。反过来,如果真正的关键线索在 docker-compose.ymlMakefile 里,这条流程又会漏掉它。

Agent#

Agent 的处理方式更像这样:

  1. 先决定从 README 开始
  2. 读完后判断信息是否足够
  3. 如果不够,再决定读取 package.json
  4. 根据脚本内容判断还要不要继续查配置文件
  5. 信息足够后停止,并输出答案

这里最关键的变化是:路径不是预先固定的,而是根据观察动态生成的。

Workflow 为什么会失效#

很多人第一次接触 Agent 时,会有一种疑问:

我把流程写复杂一点,不就等价于 Agent 了吗?

不完全是。

固定工作流的问题不在于“步数太少”,而在于它对未来路径做了过多假设。现实任务中最难提前写死的,往往正是这些部分:

  • 哪一步才是真正重要的信息来源
  • 当前结果是否已经足够
  • 失败后是否要换条路继续
  • 是继续深入,还是应该停止

一旦任务存在这些不确定性,系统就不再只是“执行预设步骤”,而是在做基于环境反馈的决策。这时再用纯 Workflow 去模拟,代码往往会迅速膨胀成一大堆分支判断,最后既不灵活,也不好维护。

Agent 的意义就在这里:把“下一步该做什么”这件事从硬编码分支里解放出来,交给模型在约束内做决策。

什么时候用 Agent#

说到这里,容易出现另一种误解:既然 Agent 更灵活,那我们是不是应该尽量都做成 Agent?

答案同样是否定的。

先看代价#

Agent 的代价非常真实:

  • 请求次数更多
  • 延迟更高
  • token 成本更高
  • 状态管理更复杂
  • 调试难度更大
  • 行为不确定性更强

所以真正重要的问题不是“Agent 强不强”,而是“这件事值不值得用 Agent 来做”。

适合的场景#

当一个任务同时满足下面几项时,可以优先考虑 Agent:

  • 任务需要多步完成
  • 每一步的路径不能完全提前写死
  • 系统需要根据中间结果决定下一步
  • 任务需要调用工具或访问外部资源
  • “是否继续”和“查什么”本身就是问题的一部分

典型例子:

  • 代码库分析助手
  • 资料调研助手
  • 能搜索、读取、整理信息的研究助手
  • 会使用工具完成任务的自动化执行器

不适合的场景#

如果任务更接近下面这些特征,优先考虑简单方案:

  • 只是单轮问答或改写
  • 流程非常稳定,完全可以提前写死
  • 不需要调用外部工具
  • 不需要根据中间结果改变路径
  • 成本和延迟比灵活性更重要

典型例子:

  • 文案润色
  • 固定模板摘要
  • FAQ 问答
  • 表单数据转结构化 JSON

一句话总结就是:

如果系统只是“回答”,那多半不需要 Agent;如果系统必须“边做边判断”,才值得考虑 Agent。

本教程的主线案例#

为了让后面的章节不碎片化,我们会围绕一个统一案例展开:

用 TypeScript 构建一个“研究与工程助手”。

这个助手一开始只会做很简单的事:理解任务、调用一个工具、拿到结果后继续回答。
随着教程推进,我们会一点点给它补上更完整的能力:

  • 第 2 章:先让它拥有最小 Agent Loop
  • 第 3 章:让它学会稳定地调用工具
  • 第 4 章:让它能用 ReAct 方式边想边做
  • 第 5 章:让它具备显式规划能力
  • 第 6 章:解决上下文组织问题
  • 第 7 章:让它通过 RAG 读取外部知识
  • 第 8 章:接入 MCP 生态
  • 第 9 章:把重复任务沉淀成 Skill
  • 第 10 章:把这些能力组装成一个真正可用的 Agent

你可以把整套教程理解成一条连续的升级路径:
我们不是在学很多零散概念,而是在亲手把一个 Agent 从“能跑”慢慢做成“能用”。

小结#

这一章最重要的不是记住术语,而是记住边界:

  • Chat API 适合单轮生成任务
  • Workflow 适合流程稳定、步骤已知的任务
  • Agent 适合路径不确定、需要根据观察持续决策的任务

Agent 的本质,不是“更会聊天”,而是:

  • 会维护状态
  • 会决定下一步动作
  • 会根据动作结果继续前进

后面所有章节,本质上都在回答同一个问题:

如果我们真的要做一个 Agent,它最小应该长什么样?

下一章#

下一章我们会把上面的抽象真正落成代码,用 TypeScript 写出一个最小可运行的 Agent Loop。
到那时你会看到:Agent 最核心的骨架,其实并不复杂,它本质上只是一个围绕“决策 -> 执行 -> 观察 -> 更新状态”持续运行的循环。