Sarvam AI(网页) · 2026/9/29

构建 AI Agent:一份第一性原理指南

Sarvam AI 发布《构建 AI Agent 的第一性原理指南》,提出 Agent 就是“语言模型 + 循环 + 工具 + 指令”,技能、记忆、领域知识都只是把正确文本放到模型面前的方式。全文用网店客服 Agent ShopBot 贯穿,演示一次客服请求的六步循环,并强调一切都只是单一上下文窗口里的文本,窗口的大小、注意力、成本与速度是核心瓶颈。

构建 AI Agent:一份第一性原理指南

Agent 就是一个在循环中运行的语言模型,它拥有可以调用的工具,以及告诉它该如何行为的指令。本指南从这一想法出发,一步步搭出一个可用的客服 Agent。

研究 · 2026 年 9 月 29 日 · 25 分钟阅读 · 分享

Agent 就是一个在循环中运行的语言模型,它拥有可以调用的工具,以及告诉它该如何行为的指令。其他的一切——技能、记忆、领域知识——都只是把正确的文本在正确的时间放到模型面前的方式。

如何阅读本文

本指南从上到下读一遍即可。每一节都先给一个小而具体的例子,再上升为通用规则。最后几节把所有内容拼成一个你本周就能动手做出来的 Agent。

一个贯穿全文的例子。大多数章节都使用同一个 Agent,好让各部分彼此衔接:ShopBot,一家名为 Kirana Express 的网店客服 Agent。顾客会问它类似“我的订单到哪了?”或者“这个坏掉的水壶我要退款”之类的问题。它可以查询订单、核对退款规则,并在限额内发起退款。

整个过程请牢记一个观念:模型只知道此刻存在于它上下文窗口里的内容。它没有隐藏的数据库,不记得昨天发生了什么,也无法访问你的系统——除非你给它一个工具。下面每一个设计决策,本质上都在回答同一个问题:模型应该看到哪些文本,以及什么时候看到?

1. 什么是 Agent

Agent 是一个能自己决定下一步、执行这一步、查看结果、然后重复直到任务完成的模型。正是这个循环让它成为 Agent。

先看三个层级

- 普通 LLM 调用:文本进,文本出。一次性。例子:“为延迟的订单写一封礼貌的道歉信。”它写了一封。结束。 - 聊天机器人:同上,但会记住到目前为止的对话。顾客:“我的订单晚了。”机器人:“抱歉!订单号是多少?”仍然只是说话。 - Agent:能用工具对世界采取行动,并循环直到目标达成。机器人调用 get_order("KE-4471"),发现卡住了,调用 create_ticket(...),然后告诉顾客它做了什么。

从聊天机器人到 Agent,跨越的是两样东西:工具(它能做,而不只是说)和循环(它会自己一直走下去,直到它认为自己完成了)。

循环,一步一步来

下面就是顾客输入“订单 KE-4471 在哪?”时真实发生的事情。

一个问题,一个循环。顾客问 ShopBot:“订单 KE-4471 在哪?”

第 1 步(共 6 步),你的代码 → 模型:提示词 + 工具 + 消息 1. 你的代码把系统提示词、工具列表和顾客的消息发给模型。 2. 模型回复的不是答案,而是一个请求:调用 get_order,order_id = "KE-4471"。 3. 你的代码对真实的订单数据库执行这个函数。模型本身从不接触数据库。 4. 你的代码把结果(status: shipped, eta: 26 Sep)追加到对话中,再把全部内容发回给模型。 5. 模型现在有足够信息作答。它回复纯文本:“昨天已发货,应该会在 9 月 26 日前送到。” 6. 因为这条回复里没有工具请求,你的代码停止循环,把文本展示给顾客。

模型是负责决策的大脑,你的代码(称为 harness,即执行框架)是负责行动的身体。只要模型还在请求工具,循环就会继续。

用代码表示,整个 Agent 大致就是这样:

# 谁来调用它:你的 web 服务器,每收到一条用户消息调用一次。 def run_agent(conversation_so_far): while True: reply = call_model(system_prompt, tool_definitions, conversation_so_far) conversation_so_far.append(reply) # 没有工具请求,说明模型认为它已经完成了。 if not reply.tool_calls: return reply.text # 执行模型请求的每一个工具,然后再次循环。 for tool_call in reply.tool_calls: result = run_tool_for_real(tool_call.name, tool_call.arguments) conversation_so_far.append(tool_result(tool_call.id, result))

这就是全部思路。真实的 harness 会加上限制(最多 20 次循环)、超时、日志和权限检查,但形状从不改变。

类比:一个带着电话和手册的新员工

把模型想象成一个第一天上班的聪明新员工。他们机灵、读书多,但对你公司一无所知。系统提示词是经理早上给他们的简报。工具是他们有登录权限的系统:订单看板、退款表单。技能是架子上的一本本流程手册,只有在任务需要时才去翻。记忆是他们的笔记本,记着上周这位顾客发生了什么。领域知识是他们可以检索的公司 wiki。用户消息则是走到柜台前的顾客。

一个没有简报、没有登录权限的新员工只能闲聊。把简报、登录权限和手册给他,他就能把工单结掉。构建 Agent 就是在布置那张柜台。

Agent 由什么定义

四件事。改动其中任何一件,你得到的就是另一个 Agent:

- 目标与角色——它是用来做什么的(“为 Kirana Express 的顾客解决订单问题”)。 - 工具——它在现实中究竟能做什么。 - 指令与知识——它应该如何行为,以及它需要知道什么。 - 停止条件——什么时候算完成,或者什么时候必须转交人工。

模型本身(Claude、GPT、Sarvam-M 等)是引擎。两个 Agent 可以共用同一个模型,却因为上面这四件事不同而成为完全不同的 Agent。

2. 解剖:一切都只是一个窗口里的文本

Agent 的每一个部分最终都会变成单一上下文窗口里的文本,模型每一轮都从上到下读一遍。没有别的通道。这是本指南最重要的心智模型。

当人们说“这个 Agent 有记忆”或“这个 Agent 知道我们的退款政策”时,他们的意思是:某些代码在模型读取之前,把那段文本放进了窗口。

模型在一轮里实际看到的东西

当顾客向 ShopBot 申请退款时,发给模型的请求大致长这样,顺序如下:

一个窗口里的全部文本。选择 ShopBot 请求中的某一部分,看看是谁写的、什么时候进入窗口的。

系统提示词:本次请求 15 行中的 3 行 [ 系统提示词 ] 你是 ShopBot,Kirana Express 的客服 Agent…… 退款金额超过 2,000 卢比需要人工处理。…… [ 工具定义 ] get_order(order_id) —— 按 KE 编号查询一个订单…… issue_refund(order_id, ...) —— …… [ 技能索引 ] refunds:如何处理退款和退货请求;delivery-issues:延迟、丢失或损坏的配送 [ 记忆 ] 顾客 Priya 在 9 月 2 日有一次延迟配送。偏好印地语。 [ 对话 ] 用户:我的水壶到货时是坏的,订单 KE-4471。助手:(调用 get_order KE-4471)工具结果:{item: kettle, price: 1499, delivered: 22 Sep}

系统提示词——它是什么:角色、规则、语气、边界;谁写的:你,Agent 的构建者;何时进入窗口:每一轮,始终在最顶部。

模型会读完所有这些,然后产出下一块内容:要么是一次工具调用,要么是一条回复。

为什么窗口是瓶颈

窗口很大,但并不免费。实践中三个限制很重要:

- 大小。它能容纳的 token 数量是固定的。把一份 300 页的政策手册粘进去,你可能就没地方了,或者每一轮都要为它全部付费。 - 注意力。里面的文本越多,模型就越容易漏掉那唯一重要的一行。埋在第 40 页的规则,执行起来不如第一屏里的规则可靠。 - 成本与速度。模型每一轮循环读的每个 token 你都要付费。一个 20 步的 Agent 会把系统提示词重读 20 遍。

所以,构建 Agent 的手艺,主要就是决定什么进入窗口、以及什么时候进入。常驻文本(系统提示词、工具定义)应当简短且必要。其他一切只应在需要时才加载。技能、记忆和检索的存在,都是为了这一个原因。

3. 为什么我们要创建不同的 Agent

我们把工作拆给不同的 Agent,理由和公司设立不同团队一样:每个团队需要不同的简报、不同的系统权限,以及不同的层级……

FDE 判断

对 FDE 而言,本文把交付要点落在上下文工程:系统提示词与工具定义应精简常驻,技能、记忆、检索按需加载,循环需设上限、超时、日志与权限检查,工具执行与模型决策严格分离。这正是 FDE 在客户现场把模型接入真实系统、兼顾成本与可靠性的日常动作,可作为企业 AI 交付的通用范式。