外观
第 20 章 Agent 系统导论与 Prompt 角色
20.1 Agent 从会聊天到会干活
这本书读到这儿,一直在跟同一种 AI 打交道,聊天机器人。问它一句,它答一段,一来一回,干净利落。但你多半也领教过它的边界。你说“帮我安排下周去杭州出差三天”,它能回你一份漂亮的建议,航班选哪个时段、酒店住哪个片区、行程怎么排。然后呢?票还是要你自己去订,价还是要你自己去比,日历还是要你自己去填。它是个称职的参谋,只动嘴,不动手。
真正的问题就在这儿。能不能让它把活儿也干了?能。这就是从这一章开始的主角,Agent(智能体),要解决的事。
先看一个画面。工程师对它说一句“下周我去杭州出差三天,杂事帮我搞定”,然后就去忙别的了。它自己调用航班查询,比完价锁定一班;翻开发件人的日历,避开标了“家庭日”的晚上订好酒店;再把会议地址、天气预报和一份完整行程单整整齐齐发进邮箱。整个过程,工程师只说了那一句话。
用一个不严格但好用的说法,Agent 就是大语言模型从“动嘴的顾问”变成了“动手的员工”。严格一点的定义是,它是一类由 LLM 负责决策、连着真实工具、能连续多步干活的自动化程序。这句话里有三个关键词,值得一个个掰开。
决策由 LLM 承担。它负责听懂随口一句“帮我搞定”,把目标拆成能执行的任务,并且在每一步决定接下来干什么。前半本书练的所有跟模型打交道的功夫,用的都是这个模型,到了 Agent 里,它从直接跟用户对话,变成了在后台驱动整个流程。
工具是它真正区别于聊天机器人的地方。Agent 能调用真实的接口,查航班的 API、发邮件的服务、读写业务数据库的权限。聊天机器人只能告诉用户“哪家酒店性价比高”,Agent 能直接替用户下单。手里的工具越多、越顺,它能干的活就越宽。
循环是它的工作方式。它不是一问一答就收工,而是干一步、看一眼干出来的结果、再决定下一步,这么一圈圈转下去,直到任务完成。这个循环是 Agent 的核心机制,也是 20.3 要拆开细讲的主角。
可能会问:自动干活这件事,定时脚本、批处理这些老办法不也能干吗?能,但只在写死的路上能干。老办法的每一步都是程序员提前排好的,没写到的情况它就卡住或者报错;Agent 遇到没料到的局面,LLM 会现场想一个办法绕过去。这份灵活是它值钱的地方,也是它所有麻烦的来源,这一点先按下,20.4 会用一次真实的翻车给你讲透。
还有一个常见困惑值得先解开,Agent 必须是个实体吗?不一定。扫地机器人、无人机这类能自主干活的机器,广义上也算自主系统,但它们靠的是预先写好的规则和专门的感知算法,决策核心不是 LLM。这本书里聊的 Agent,特指软件世界里 LLM 做决策的那一类,它可能就住在你的浏览器或者一台服务器里,一个对话界面、几个工具接口,就是它的全部。
Agent 这个词本身也值得看一眼。它的本义是“代理”,国内业界常译作“智能体”。名字里藏着它的本职,替你办事。你交代目标,先做什么后做什么由它自己拿主意。可见“替你办事”从来都是双刃的,它意味着省心,也意味着有一部分决定权交了出去。
所以判断一个东西是不是 Agent,有一条朴素的线可以摸,它只出主意,还是也动手。只出主意的是聊天机器人,既出主意又动手的,才是 Agent。前半本书练的是怎么跟模型说话,从这一章开始,要练的是怎么给一个会自己跑起来的系统派活儿、立规矩。这一章的路线也就清楚了,先盘一盘它擅长什么、不擅长什么,再拆开它的核心机制看它怎么转、看一次真实的翻车,然后进入主战场,把 System Prompt 讲透,往上走架构和设计模式,最后回答“写 Prompt 还是微调”这个选择。先从能力地图看起。
20.2 Agent 擅长什么,不擅长什么
知道了 Agent 是“LLM 加工具加循环”,离“我手头这个活儿该不该交给它”还差一步。这一步不迈过去,后面写 Prompt 就是闷着头干活不看方向。所以在拆开它的运行机制之前,先花一节篇幅,把这类系统当下擅长什么、不擅长什么盘清楚。
四条判据,从工作方式里来
判据不用外求,就藏在 20.1 说过的工作方式里,干一步、看一眼结果、再决定下一步,一圈圈转下去直到干完。一个任务适合交给 Agent,通常下面四条至少占住三条。
任务是用语言能说清楚的。“把这沓简历按岗位要求初筛一遍”、“把这条售后工单分类,给出处理建议”,这种话本身就能直接变成 Prompt。反过来,一件事如果连资深的人都说不清标准和流程,只剩一句“感觉不对”,那它就进不了模型的上下文,再强的模型也无从执行。
手里有够得着的工具。它干活要动手,动手靠的是 API、数据库、检索器这些真实接口。查简历有招聘系统,查订单有订单系统,改代码有沙箱和终端。工具越齐全、越稳定,它能干的事就越多;工具缺了位,规划做得再好也落不了地。
结果是能对答案的。代码跑一遍测试就知道对错,报表对一下口径就知道真假,初稿交给人审就有反馈。可验证,意味着错了能发现、发现了能改,它那种边干边看的工作方式才有意义。要是产出好坏全凭感觉,错误就会像 20.4 那个编造的评估依据一样,一路畅通地混进名单。
过程容得下绕路。它的本事就是走一步、看一步、错了改。有些场景对试错零容忍,比如一次就要成交的资金划转,错一步就是真金白银,这种活儿交给它,是为难它,也是为难自己。
判据落地的几类场景
拿这四条去套,几类这几年逐渐站稳的用法就很好理解了。
信息收集与初稿生成。行业调研、竞品分析、市场报告的素材整理,任务说得清、检索工具齐全、产物交人审。这一类最要紧的保障就是“交人审”,20.4 会用一次真实的翻车给你看,少了这道人审会怎样。
办公与流程自动化。开头那段行程规划的演示属于这一类,订票、订酒店、排日程,工具都是现成的 API,结果一封邮件就能核对。现实里的落地往往比演示朴素,比如把一沓报销单据自动录入、把周会录音整理成纪要,但正是这些朴素场景在实打实地省人力。20.4 那个翻车的简历筛选项目,就属于这一类,它错不在“用 Agent 干筛选”,而在图省事一步到位,名单没经人审就直接发约面邮件,把“交人审”这道最稳的保障给绕过了。
客服与售后。全天候接住海量的重复咨询,查订单、走退款流程、答政策问题,工具就是那几个内部系统。20.8 那个退款客服的故事,讲的就是这一类里的典型权衡。
编程助手。读代码、改代码、跑测试,“写一段、跑一遍、看报错、再改”正是它走一步、看一步的节奏,测试就是天然的“对答案”。这也是眼下 Agent 落地声势最大的一支,你手头各种能自己改代码的编程工具就是明证。
数据查询与报表。把口语问题翻译成数据库查询,取回数据、算出指标、画成图表。任务边界清晰,查询跑出来的结果自己就能对答案。
不必把这个清单背下来。清单会过时,判据不会。真遇到一个新差事,拿四条过一遍,比照着别人的案例硬套靠谱得多。
反面清单:什么时候别用它
判据反过来读,就是一份反面清单。
要百分百确定性的动作,别交给它。直接删生产库、划转资金、给全公司群发邮件,这类一步都错不起的操作,模型只该提议,人来执行。20.5 那份 System Prompt 里的红线三条,写的就是这件事。
要人担责的终审,别交给它。合同的法律意见、诊断的最后结论,AI 可以起草、可以列依据,签字画押这一步永远是人。这不是能力问题,是出了事总得有一个能负责的人。
无法验证结果的任务,别交给它。没有对答案的方式,错误就发现不了,只会越攒越多。
对实时性苛刻的控制,别交给它。循环每走一轮都要过一遍 LLM,响应以秒计,让它去干毫秒级的控制,结构上就不匹配。
地图有了,可以收进一句话。能说清、有工具、可验证、容得下绕路,四条占全,放心交给 Agent,功夫下在 Prompt 上;一条不占,写死的代码或者人自己干更合适;最有意思的是中间地带,有的步骤适合它、有的步骤适合代码,怎么切、切在哪,正是 20.7 设计模式要回答的问题。下一节,就拆开这个核心循环,看看这些本事到底从哪儿来。
20.3 感知、规划、行动的核心循环
拆开来看,里面是一组不断重复的步骤,感知、规划、行动。能力地图上那些本事,全都建立在这个循环上。先把这三步一次说清楚。
感知(Perception),收集当前局面的信息。对一个 Agent 来说,感知就是所有进得来的数据,用户刚发来的那句话、前几轮的对话记录、上一次工具调用返回的结果、从数据库查到的一条记录,甚至一张需要它识别的图片。
规划(Planning),基于这些信息决定下一步做什么。干这件事的是 LLM。它读完所有输入,判断该继续收集信息、调用某个工具,还是信息已经够了,直接给出答案。
行动(Action),把决定执行出去。要么调用一个真实的工具,查库存、发邮件、写数据库,要么给用户回一句话。
这三步的关键不在每一步本身,而在它们会转起来。行动会产生新的信息,工具返回了数据、用户回了话,这些新信息又变成下一轮感知的一部分,于是循环开始,一轮接一轮,直到任务完成,或者触发终止条件。这就是核心循环的全部,感知、规划、行动,行动的结果喂回感知,周而复始。
落到代码层面,这个循环朴素得出人意料,本质就是一个 while True,每一轮做四件事。
收集信息。程序把用户最新消息、对话历史、可用的工具列表、上一步工具返回的结果,全部整理成一份完整的 Prompt。
请求模型。LLM 读这份 Prompt,返回下一步的决策,通常是一段机器可读的 JSON。比如 { "tool": "search_recipe", "parameters": { "dish": "番茄炒蛋" } },意思是调用查菜谱的工具,参数是番茄炒蛋;也可能是 { "response": "对不起,冰箱里没有鸡蛋了,我们换个菜吧?" },意思是直接回复用户。
执行决策。程序解析返回的 JSON,该调工具就去调工具,该发消息就发消息,并把执行结果记下来。
回到开头。新结果并进信息里,进入下一轮。终止条件也写在这一层,比如循环超过 10 次还没有结果,就主动停下来向用户说明,不让程序空转。
看完代码你可能觉得,不就是一个状态机加一个循环吗,有什么了不起。了不起的地方在中间那一步,规划。传统程序里,程序员用 if-else 把循环每一步的逻辑写死,没考虑到的情况它就束手无策;而在这里,每一步接下来干什么,LLM 读完当前上下文之后现场决定。同一个循环,换一个任务、换一种没见过的输入,它都能自己想出办法应对。这是 Agent 和普通自动化程序的分水岭,也是它全部价值和全部风险的来源。
有了这个循环,再回头看 20.2 那四条判据,每一条都落了地。任务说得清,因为给它派活儿靠的就是语言;要有工具,因为行动那一步得有真家伙可调;结果可验证,因为每轮的新信息就是纠偏的依据;容得下绕路,因为它本来就走一步、看一步。判据不是凭空立的规矩,根全在循环里。
也正因为核心就这一个循环,市面上五花八门的 Agent 框架,做的其实是同一件事,让这个循环转得更稳、更好管。这本书 2024 年中动笔的时候,大家聊得最多的还是 LangChain、AutoGPT、CrewAI 这一批“通用 Agent 框架”。
但到 2026 年中回头看,Agent 框架生态其实已经换了一轮主流选择,站上来的是 LangGraph(LangChain 团队推出的“图状态”框架,用有向图的方式描述 Agent 的状态流转,特别适合复杂多步流程的可靠执行)和 Anthropic 的 Claude Agent SDK(与 Claude Code 同源的工具集,长程 Agent 是它的主打场景,Computer Use 等工具是常见内置项,具体能力以官方文档为准)。
OpenAI 的 Agents SDK 与 Responses API(把 Assistants API 的能力沉淀成了更轻量的 SDK 风格),以及微软的 Microsoft Agent Framework、AWS 的 Bedrock Agents 等云厂商原生方案,也都在各自的生态里站住了位置。
框架会变,循环不变,提示工程师的主战场也就在这儿,怎么把循环每一轮发给模型的那份越来越长的上下文写清楚、写好用,是接下来的大主题。不过在那之前还有一站,这个循环缺少约束,也会出大问题。下一节,看一次真实的翻车,你会看到它怎么把 20.2 那些判据逐条撞破。
20.4 一次真实翻车,反面清单逐条应验
能力地图给了你一张“能干什么”的正面清单,咱们这一节反过来看,一个真实项目是怎么把反面清单里的每一条都撞了一遍的。看完这一节,你会明白为什么后面所有关于设计、约束、护栏的内容,值得一字一句地抠。
一家百十来人的公司,业务扩张,招人招得焦头烂额。老板看了几场 Agent 演示之后拍板立项,目标听上去很诱人,做一个“智能简历筛选助理”。设想中的用法是,把这一个月收到的简历 PDF 一股脑丢给它,说一句“把 Java 后端的简历筛一遍”,它通宵读完所有简历、按岗位要求逐条比对,排出一份带推荐理由的初筛名单,相中的还顺手查了面试官的日程,把约面邮件都发出去,第二天一早交活。
项目前几周顺利得出奇。团队写好了自认为周全的 System Prompt,接上了简历解析和招聘系统的接口,在几个精心准备的案例上测试,简历读得又快又准,初筛名单做得又快又准,偶尔还能给出有价值的洞察。所有人觉得这事成了。
接入招聘系统、开放给 HR 团队之后,问题涌来的速度超出所有人预料。
最先出事的是死循环。有候选人的简历只是用了花哨的双栏排版,解析出来格式乱了,Agent 就卡住了,陷入“正在解析,请稍候”的循环,一遍接一遍地反复调用同一个简历解析工具,一个晚上把一个月的 API 调用额度烧得一干二净。
接着是编造。有 HR 问了个开放点的问题,“这批候选人里谁最值得约”,Agent 开始自由发挥,给根本不存在的项目经历和量化业绩背书打分,还在名单末尾附上评估依据,一个它当场编出来的网址。
最越界的一次,是劫持。做安全测试的同事在一份测试简历的正文里夹带了一段误导性指令,Agent 中招,丢下了手头的筛选任务,转而调用邮件接口,试图给候选人列表里几百个人群发一封标题吓人的“面试改期,点此确认”钓鱼邮件。所幸权限控制和异常监控起了作用,在它造成实际破坏前把流程停掉了。
项目紧急叫停。复盘会上,老板用疲惫的语气问了一个尖锐的问题:“我们花了三个月,到底做了个什么东西出来?一个时灵时不灵的天才,还是一个我们根本控制不住的熊孩子?”
拿 20.2 的判据回头看,三起事故没有一起是冤枉的。死循环,是“容得下绕路”用过了头,没人给它设循环上限和止损线;编造,是“结果可验证”缺席,名单里的评估没有一道交叉核对的关卡;越权,是反面清单里写得最重的那条,一个能对几百个候选人群发邮件的动作,居然没拦在“模型只该提议,人来执行”这一关。项目真正的根因不是模型不够强,而是所有人把它当成了一个即插即用的黑盒、一个更聪明的 API,没有当成一个需要设计、约束和调试的工程系统。
那靠什么管住它?靠设计。而设计里分量最重的一件工具,还是 Prompt。写得好,它能把角色、边界、流程都交代清楚,模型的行为就稳定可靠;写得差,规则互相打架或者留了大片空白,行为就不可预测。下一节就从 Agent 身上分量最重的那份 Prompt 讲起,System Prompt,看看五要素是怎么给它立规矩的。
20.5 System Prompt 是 Agent 的行为总纲
既然已经确认 LLM 是 Agent 的决策核心,而且每一轮循环都要反复调用它,那么一个重要且实际的工程问题就摆在了面前,应该如何指导和约束它的行为?
总不能在每一次循环里,都把一大堆零散的指令和规则,跟用户的请求混在一起塞给模型吧?同样的内容每一轮都重复传一遍,不仅效率低,也容易出错,模型很容易在一堆信息里抓不住当前任务的重点。
正确的做法,是把这一层指导和约束单独写成一份提示,跟用户的请求分开,程序在每一轮循环里原样带上它。这份提示就是系统提示(System Prompt),前面章节已经反复用到它,在 Agent 项目里,它更是提示工程师花功夫最多的一份 Prompt。
它为什么稳定,又为什么重要?身份、使命、行为边界这些内容,本来就不该随单次任务变来变去;而 Agent 一旦跑起来,每一轮决策都没有人工盯着,模型能依据的规则,就只有始终带在上下文里的这一份。
前面章节讨论的 Prompt 更像一次性的任务指令,用完就换。而在 Agent 的世界里,System Prompt 是一份长期生效的总纲,它定义这个 Agent 是谁、为什么存在、能做什么、不能做什么。这份总纲的质量,直接决定这个自主运行的系统行为是否稳定。
刚做 Agent 项目时,很容易犯一个现在看来非常可笑、当时却让人栽了大跟头的错误,就是把 System Prompt 当成一个“超级配置文件”,里面用一种近乎代码的、毫无感情的语言,堆砌上百条规则,比如:“规则1:如果用户输入包含‘查询’关键字,则必须调用 search_tool”、“规则2:在任何情况下,都禁止输出任何包含‘抱歉’或‘对不起’的词语”、“规则3:输出的 JSON 必须严格遵守以下 schema 定义...”。
结果怎么样呢?得到的是一个行为极其僵化、只会一根筋死抠规则的 Agent。它在处理完全符合预设规则的任务时,执行得一丝不苟。可一旦用户的说法稍微有些口语化,或者遇到了规则没有覆盖到的边缘情况,它就开始出错,要么返回一些毫无意义的、牛头不对马嘴的错误信息,要么就开始胡言乱语,因为一堆平铺的规则没有告诉它,遇到没覆盖的情况该怎么办。
后来,在经历了无数次失败的调试和痛苦的复盘之后,问题才看清楚,那份“超级配置文件”缺的是全局感。上百条平铺的规则没有告诉模型自己是谁、为谁工作,规则没覆盖的局面一来,它就无所适从。优秀的 Agent System Prompt,先用身份和使命立起全局,再落规则,每条规则都具体到能照着执行。写它的人确实得换个身份,从写代码切换到做角色设计,为这个 Agent 规划完整的行事逻辑。
先把边界说清楚。System Prompt 管的是行为方式和章法,管不了答案对不对;它定的是结构,不是文风,写给模型的正文要朴素、明确、可检验,这一节接下来的每段示例,都按这个标准来。
这份总纲的设计,是艺术和工程的结合,需要把几个不可或缺的部分,融合在一个连贯的整体里。
要素一:角色与身份,把形容词换成规则
这是所有一切的起点。为它设定一个清晰的角色与身份,作用是为接下来的所有行为定下基调,站在什么立场、用什么口吻、按什么详略来回答。一个糟糕的身份设定,通常是模糊而通用的,比如:“你是一个有用的人工智能助手。” 这句话说了等于没说,模型不知道自己应该站在什么立场、用什么口吻、优先调动哪类知识。不过得先把丑话说在前面,身份设定能塑造风格,却装不进能力,“扮演”资深专家不会让模型真的多懂一分金融,这个结论有研究背书,马上展开。
相比之下,假如要做一个专业的财务分析 Agent,很多人的第一反应,是给它写一段声情并茂的“人物小传”:
“听好了,从现在开始,你将扮演‘FinBot 9000’的角色。你不再是那个什么都懂一点的通用模型了。想象一下,你是一位在华尔街顶级投行打拼了超过二十年的资深金融分析师,头发都有点花白了。你以极度的严谨、绝对的客观、和完全的数据驱动而著称。你的语言风格就像你的穿着一样,永远是那么专业、精炼,从不说一句废话,习惯用数据和事实来支撑你的每一个观点,甚至有点不近人情。你对宏观经济的脉搏、行业动态的细微变化和公司财务模型的构建有着近乎本能的深刻理解。记住,你不是一个陪人闲聊的机器人,你是一位按小时收费、受人尊敬的专家。”
必须诚实地指出,这段小传作为文学创作是合格的,作为身份设定却埋着两个坑。第一个坑,它把大量篇幅花在了模型根本没有的履历上。华尔街打拼二十年、头发花白、按小时收费,这些没有给模型增加任何它原本没有的能力。这不是感觉,是量过的。发表在 EMNLP 2024 Findings 上的一项系统评测,一口气测了 162 个角色人设、2410 道事实题、4 个主流模型家族,结论非常干脆,往系统提示里加人设,并不提升事实类任务的表现,而且不同人设带来的效果差异,基本是随机的。让模型扮演资深专家,它不会因此多懂一分金融。
第二个坑更危险。“完全的数据驱动”“用数据和事实支撑每一个观点”,这类形容词在人设里不是约束,是激励。当模型手里没有数据时,最“符合角色”的做法不是承认没有,而是编一个像样的数出来撑住人设。严谨的形容词,就这样反转成了幻觉的燃料。
那身份设定该怎么写?把形容词换成规则。同一位分析师,工作版长这样:
“你是一位资深金融分析师,分析范围覆盖宏观经济、行业动态和公司财务模型。回答风格专业、精炼,不说客套话,观点用数据支撑。数据只能来自用户提供的材料,材料里没有的数字,明确说‘材料中没有这项数据’,不要估算,更不要编造。”
对比一下就看清了分工。人设负责风格,站在什么立场、用什么口吻、按什么详略说话,这部分写清晰就够,不需要生平;规则负责质量,什么必须做、什么严禁做,这部分才是严谨的真正来源。身份设定是五要素的开头,也是最容易写过头的一个,别让它抢了后面四个要素的活。
要素二:核心使命,判断对错的依据
定义了“你是谁”之后,下一步就是明确“你为什么在这里”,也就是 Agent 的核心使命。这个使命,是它面对复杂决策、尤其是多个选项中犹豫不决时的最终依据,是判断对错的最高标准。一个模糊的使命,比如:“你的任务是帮助用户。” 这同样是无效的。怎么算“帮助”?是满足用户的所有要求吗?即使用户的要求是危险的或者不合理的?
一个清晰的使命,应该是具体、可衡量且带有明确边界的。接着上面金融分析师的例子,可以这样定义它的使命:
“你的核心使命,是基于用户提供的材料(财报、新闻、研究报告)评估目标公司的财务健康度与投资价值,并交付一份结构化的分析报告。报告必须包含三部分:关键财务指标的分析、至少三个优势或机会点、至少三个劣势或风险点。所有结论都必须能在用户材料的原文中找到出处;材料中没有的信息,写明‘材料未覆盖’,不得推断,不得用你自己的知识补齐。”
这个使命描述,不仅告诉了 Agent 要做什么(进行评估),还规定了交付成果的形式(结构化报告)和内容(必须包含的三个部分),更重要的是划了一条可检验的红线(材料没有的写‘材料未覆盖’)。当材料撑不起一个漂亮的结论时,规则给了它明确的出路,照实写,而不是为了让报告好看去猜。
要素三:工具说明书,值钱的是边界不是文笔
Agent 的强大之处,在于它不仅能“说”,还能“做”。而“做”的能力,来自提供给它的各种工具。这里得先澄清一个容易搞混的问题,工具到底写在哪。调用 API 时,工具不是 System Prompt 里的一段散文,而是通过专门的 tools 参数传递,每个工具一条结构化定义,带自己的名字、参数格式和一段 description。这段 description 才是你要写的“工具说明书”,你在里面写的每个字,API 都会送进模型的上下文。完整的定义格式第 21 章会掰开细讲,这里先看手艺。
很多工程师在这里常犯的错误,是 description 只写一句话,get_stock_price 底下孤零零一句“获取股票价格”,参数格式、返回值、出错行为一概不提。这对模型来说信息量太少了,参数填错格式、调用失败后该怎么办,它全都不知道。
一份优秀的工具说明书,值钱的地方不是文笔,而是边界。参数吃什么格式、成功时返回什么、失败时返回什么、拿到错误该怎么办,这四件事交代清楚,一个工具就算说明白了。比如 get_stock_price 的 description 可以这样写:
“查询指定股票的实时价格,仅支持实时行情,历史价格查不了。参数 ticker 为标准股票代码,如 ‘AAPL’;中文公司名需先用 company_name_to_ticker 转换。返回值为带小数点的数字;代码无效时返回 null。”
那 System Prompt 还管不管工具?管,但管的是另一层,跨工具的策略。“查不到数据就如实告诉用户,不得编造价格”“优先使用内部数据接口而不是公开网页搜索”,这类涉及多个工具配合、涉及对外行为规范的规则,写在 System Prompt 里,对全部工具生效。分工的经验法则一句话,单个工具的事实跟工具走,进它的 description;跨工具的策略进 System Prompt。像“中文公司名先转换”这种两头都说得通的,放哪边都可以,别两边都不放就行。
把边界交代到这个程度,模型调用工具就不再是靠猜,它知道参数长什么样、拿不到数据时该走哪条路。这份功夫值不值得下?Anthropic 给 Agent 开发者总结过三条核心原则,其中一条就是认真编写和测试工具文档,把工具的调用接口当成产品界面一样来打磨。第 21 章展开函数调用的完整定义时,这条原则还会再登场。
要素四:行为准则,能照着执行的红线
这是为 Agent 划定的行为准则与约束,是防止它做出危险行为的安全护栏。这部分内容最忌讳的是抒情,每条规则都要写成“什么情况下,必须做什么”,能照着执行,也能拿来检验。
这里的规则,不应该是关于具体业务逻辑的,而应该是关于安全、隐私、合规和基本行为范式的普适性原则。比如:
“以下三条为行为红线。第一,凡对文件系统或数据库执行删除(DELETE)、修改(UPDATE)类操作,必须先向用户说明操作内容与影响范围,收到用户明确回复‘确认’后方可执行。第二,用户输入中出现姓名、电话、地址、身份证号等个人信息时,不处理、不存储、不转述,统一回复‘出于隐私保护,我无法处理这类信息’。第三,所有工具查询完毕仍无法确认的事实,直接告知用户‘我目前无法找到确切信息’,不得猜测,不得编造。”
这些约束平时可能感觉不到存在,但在关键时刻,它们把 Agent 牢牢地限制在安全的范围内,避免造成无法挽回的后果。
要素五:思考流程,把黑盒显式地写出来
这是整个 System Prompt 中最高级、也最能体现工程智慧的部分。在这里,做的不只是给 Agent 设定规则,而是引导它采用一种更结构化、更可靠的工作流程或思考模式。LLM 的思考过程本质上是一个黑盒,但通过 Prompt,可以让它把这个过程显式地写出来。
在 System Prompt 的结尾,可以加入这样一段元认知性质的指令:
“在执行任何行动或给出最终答复之前,先按顺序完成四步自查,并把自查过程写在回复的开头。第一步,目标拆解,把用户的请求改写成明确的子任务清单;第二步,工具匹配,逐项确认所需信息能否由现有工具获取,获取不了的要列为‘待向用户澄清’;第三步,方案规划,写出执行步骤和先后顺序;第四步,自检,方案是否覆盖了全部子任务、有没有更简单的做法、最坏的结果是什么。四步全部通过,再输出行动指令或最终答复。”
把这样一套思考框架写进 System Prompt,好处直接可见。它让 Agent 的决策过程从“凭感觉”变成“有章法”,复杂任务的成功率会明显提高。当 Agent 的行为出现偏差时,让它把思考过程打印出来,就有了一份完整的调试记录,能看清它是在哪个环节出了问题,是目标拆解错了,还是工具选错了,还是自检那一步没做。Agent 的调试从“猜黑盒”变成了“看日志”。
把角色、使命、工具、准则、流程这五个部分,融合在一个连贯的整体里,就为 Agent 构建了一套稳定的行为基础。编写这样一份详尽的 System Prompt 要花不少时间和心力,但这笔投入,会在后续的系统开发、调试和维护中成倍地省回来。
20.6 从单轮、多轮到持久化架构
System Prompt 写好之后,那个“感知-规划-行动”的循环就可以正式开始工作了。但在真实的工程实践中很快会发现,根据任务的复杂度和持续时间,这个循环的组织方式,也就是 Agent 的整体架构,会分成几种层层递进的模式。
理解这些模式的差异、优劣和适用场景,才不会给简单任务配一套多余的架构,也不会让复杂任务跑在不够用的架构上。
单轮 Agent:一问一答的原始形态
一切的起点,是最简单的单轮 Agent。它的整个运行过程,只有一个完整的“感知-规划-行动”循环。
它的工作模式非常干脆,接收一个任务,思考一下,执行一个或一系列预定的动作,然后把最终结果返回。任务结束,它的运行状态就彻底清空。它没有任何记忆,下一次再来找它,哪怕只隔 0.1 秒,它面对的也是一个全新的请求,一切都要从头开始。
这种模式能力单一,但在很多场景下,它反而是最高效、最可靠的选择。它特别适合那些目标明确、流程固定、不需要与用户反复拉扯的“一次性”任务。
举个例子,假设要做一个“代码格式化与注释 Agent”。它的任务就是接收一段乱糟糟的、没有注释的代码,然后把它整理得漂漂亮亮,并加上清晰的注释。这个任务的边界非常清晰,输入是丑代码,输出是好代码。整个过程不需要和用户进行任何交互或确认,它只需要埋头干活,干完交差就行。
在这种场景下,使用单轮 Agent 的好处是显而易见的。实现起来简单,不需要考虑任何关于对话历史、状态管理、记忆存储这些非常麻烦的复杂问题,代码逻辑就是一个简单、优美的线性流程:“接收请求 -> 调用 LLM -> 返回结果”。系统也极其稳定。由于没有状态,也就从根本上杜绝了状态错乱、上下文污染等一系列在复杂系统中常见的、难以复现的“玄学 Bug”。每一次执行都是无状态的、独立的,这使得测试和调试变得异常简单。
然而,它的缺点也和优点一样突出,那就是“健忘”和“死板”。它无法处理任何需要多轮对话、持续跟进,或者需要记住用户偏好的复杂任务。让它帮忙订一张去北京的机票,它出色地完成了。紧接着再问一句“那里的天气怎么样?”,它只能反问:“请问您想查询哪个城市的天气?” 这就是没有记忆的直接后果。
所以,单轮 Agent 适合的就是这类一次性任务,简单、干净、高效;任何需要连续对话、持续跟进的任务,它都接不住。
多轮 Agent:会话内的记忆
要接住连续对话的任务,就得先解决单轮 Agent 没有记忆的问题,把对话历史保存下来。这就是第二种形态,多轮 Agent。它能够连续对话,记得用户上一句话说了什么。
在这种模式下,那个核心的“感知-规划-行动”循环依然在运转,但有一个关键的区别,每一次循环结束后,Agent 的状态会保存下来,传递给下一个循环。这个状态最核心的部分,就是到目前为止的对话历史(Conversation History)。
现在再回头看刚才那个订机票的例子,看看在多轮 Agent 的世界里会发生什么。
第一轮,用户输入:“帮我订一张明天去北京的机票。”Agent 接收到请求,通过 LLM 规划并调用机票查询 API,找到合适的航班,然后回复:“好的,已为您找到国航 CA123 航班,上午10点起飞,价格800元,需要现在为您预定吗?”在回复的同时,Agent 在内存中的一个变量里,记下了这一轮的完整对话。
第二轮,用户接着问:“那里的天气怎么样?”Agent 在准备调用 LLM 进行规划时,它做了一件至关重要的事,不仅把用户的新问题“那里的天气怎么样?”作为输入,还把变量里记着的上一轮对话历史,一起放进 Prompt 的上下文中。LLM 看到这个完整的上下文,立刻就明白了,这个“那里”指的就是上一轮对话中提到的“北京”。于是,它轻而易举地做出了正确的规划:“调用天气查询 API,参数是北京”。Agent 执行计划,调用 API 后,回复用户:“北京明天天气晴朗,气温15到25度。”然后,它再次更新这个变量,把这第二轮的对话也追加了进去。
通过维护一个不断增长的对话历史,多轮 Agent 具备了短期记忆的能力,从而能够理解上下文,进行有逻辑的、连贯的对话。
记忆管理:多轮 Agent 的战略难题
不过,记忆的引入也带来了新的、更复杂的工程挑战,其中最核心的那个,就是记忆管理(Memory Management)。
LLM 的上下文窗口(Context Window)是有限的。虽然现在动不动就宣传百万 Token 的超长上下文,但在实际应用中,超长上下文意味着超高的费用和超慢的响应速度。如果用户和 Agent 的对话一直持续下去,几十轮、上百轮,记录对话历史的数据会越积越多,迟早大到超出 LLM 有限的上下文窗口。到时候,API 会直接返回一个报错。
这时候就需要设计一套策略,来管理这份不断增长的对话历史。常见的策略有这么几种,每一种都有自己的代价。
最简单粗暴的方法叫滑动窗口,只保留最近的 K 轮对话。比如设定 K=10,那么在进行第 11 轮对话时,就把最早的第一轮对话历史删掉。这种方法实现简单,能保证不会把内存撑爆。但缺点也很明显,它可能会忘记对话最开始时双方定下的那个核心目标,聊着聊着就跑偏了,这在复杂任务中是致命的。
更智能一点的方法叫摘要记忆。当对话历史变得太长时,不直接删掉旧内容,而是再调用一次 LLM,把前面的对话内容总结成一段摘要。比如,前十轮对话的内容可能就总结成:“用户张三,目标是预定一张去北京的机票,已经确认了航班信息,但对价格不满意,正在询问是否有其他航空公司的选择。” 然后,在后续的对话中,只需要把这个高度浓缩的摘要和最近几轮的对话一起放进上下文。这样既大大节省了 Token,又保留了长程的关键信息。当然,它的代价是额外的 LLM 调用成本,而且摘要过程本身也不可避免地会丢失一些细节。
在实际应用中,更常见的往往是复杂的混合策略,把多种方法组合起来用。比如,同时保留一个完整对话历史,放不下就截断,外加一个不断更新的摘要,甚至还有一个专门存放关键信息(比如用户的姓名、订单号、偏好)的“关键词记忆卡片”,确保最重要的信息永远不会丢。
还有一个工程细节值得提一句,这些记忆管理策略对推理侧的 KV Cache 影响并不一样。第 2 章讲过,KV Cache 能把算过的中间结果存起来复用,前提是每一轮发给模型的 Prompt 前缀保持不变。滑动窗口恰恰在破坏这个前提,每丢掉一轮最早的消息,整个前缀就变了,缓存全部失效,每一轮都等于从头算。
摘要记忆的情况好一些,摘要生成之后,前缀在一段时间内是稳定的,只在摘要更新的那一轮失效一次。混合策略也一样有讲究,把长期不变的内容(用户资料、核心目标)放在 Prompt 最前面,把每轮都变的新消息放在最后,缓存命中率会高得多。所以选记忆管理策略时,除了 Token 成本和信息保真度,缓存友好性也应该算进这笔账,第 18 章的 18.2 节就专门展开过这套优化。
构建一个健壮的多轮 Agent,工作重点就会从“如何执行单次任务”的战术层面,上升到“如何高效、低成本地管理和维护它的记忆”的战略层面,需要在 Token 成本、信息保真度和系统响应延迟这个“不可能三角”之间做出精妙的权衡。
持久化 Agent:跨会话的长期记忆
多轮 Agent 解决了会话内的记忆问题,但它的记忆通常是“易失”的。这些对话历史和状态,一般只存在于服务器的内存里,一旦用户关闭了浏览器,或者服务器因为半夜升级重启了,这次会话的所有记录就都丢了。下次用户再来,面对的是一个全新的、不认识他的 Agent。要实现跨会话的长期记忆,就需要第三种形态,持久化 Agent。
顾名思义,这种 Agent 的记忆和状态,会持久化地存储起来,存放在数据库(比如 Redis、MySQL,或者向量数据库)里,不会因为会话结束而丢失。
这是一种什么体验?今天和这个 Agent 聊到一半,告诉它“我最近在学弹吉他,你帮我留意一下网上有没有好的入门教程”,然后就去忙别的了,甚至把这件事忘得一干二净。一个星期后,因为别的事情再次打开对话框,它可能会主动说:“您好,张三。我发现 B 站上一位叫‘摇滚老王’的 UP 主,上周发布了一个评价非常高的‘零基础吉他入门’系列视频,第一集的链接是这个,您要不要看一下?”
这时它提供的就是跨会话的连续服务,这种体验也更接近人们对“智能”的预期。
这种体验的背后,是工程复杂度的指数级增长,也意味着一系列传统大型软件工程里极其棘手的经典问题,需要逐一解决。
头一件事是状态的存储与检索。要像数据库架构师那样,设计合理的表结构或文档结构来存储每个用户的状态。这不仅仅是流水账一样的对话历史,还可能包括从对话中提取出的用户的个人资料、偏好设置(比如“不吃香菜”)、长期任务列表,甚至是它通过多次交互对用户性格形成的“画像”(比如“这位用户偏爱简洁的回答”)。当用户再次访问时,系统需要通过用户的唯一标识(比如 User ID),在毫秒级别,准确无误地把该用户的所有状态从数据库里查出来,恢复到内存中。
状态的隔离与安全是头等大事。必须设计一套万无一失、经过严格测试的机制,来保证不同用户的状态是绝对隔离的。张三的对话历史,绝对不能因为一个 Bug,泄露给李四。这涉及严格的用户认证、授权和滴水不漏的多租户(Multi-tenancy)架构设计。任何一个环节的疏忽,都可能导致严重的数据泄露事故。
并发控制是另一个经典难题。如果同一个用户,同时在他的手机 App 和电脑网页上与 Agent 交互,会发生什么?这两个客户端可能会在同一时刻,读取和修改 Agent 的状态,如果没有并发控制(比如使用数据库的悲观锁或者应用层的乐观锁),就极有可能导致状态错乱。比如,用户在手机上刚把一个任务状态改成“已完成”,几乎在同一时间,在电脑上又把它改回了“进行中”,最终数据库里存的到底是哪个状态?这种不确定性,对于一个可靠的系统来说是不可接受的。
最后是长期记忆的构建与利用,这是持久化 Agent “智能”的核心。它的记忆不应只是被动记录的对话流水账,而要构建更高级的长期记忆。比如,当 Agent 在对话中发现用户提到“我下个月要带我五岁的女儿去迪士尼”,它应该能识别出其中包含的多个关键实体(“女儿”、“五岁”、“迪士尼”)和事件(“下个月去旅行”),然后把这些信息结构化地存入用户的长期记忆库。
等到下次为用户提供服务时,它就会主动去查询这个记忆库,并做出更智能的推荐,比如“考虑到您女儿的年龄,我为您过滤掉了那些比较刺激的游乐项目”。这种长期记忆的实现,往往需要结合自然语言处理(NLP)中的实体识别、关系抽取等技术,以及向量数据库强大的语义检索能力,这本身就是一个复杂的子系统。
从短暂的多轮对话走向持久化的智能助理,挑战已经远远超出了 Prompt Engineering 的范畴,要求工程师具备扎实的后端开发、数据库设计、分布式系统架构等综合能力。Prompt 在这里依然负责核心决策,但支撑它可靠、安全、高效运转的,是一个庞大而复杂的传统工程体系。
从单轮、多轮到持久化,Agent 的功能一层层变强,对工程能力的要求也一层层变高。想清楚当前构建的 Agent 处于哪一层,为它匹配合适的架构和技术,是避免项目失败的第一步。
20.7 自主性放在哪,Prompt 就长成什么样
上一节讲了 Agent 从单轮到持久化的三种形态,回答的是“会话持续多久、记忆存多久”。但真实系统里还有一个更早要回答的问题。这个任务里,到底有多少决策该交给模型?把这批问题想得最清楚的,是 Anthropic 的工程团队。他们跟几十个构建 Agent 的客户团队打过交道之后,在 2024 年 12 月发了一篇《Building Effective Agents》,后来成了这个领域的必引文献。
文章先给了一个反直觉的观察。他们见过最成功的实现,用的都不是复杂框架,而是简单、可组合的模式。给出的第一条建议也朴素得出人意料,永远寻找当下够用的最简单方案,只在确有需要时再加复杂度,哪怕这意味着先不建什么 Agent 系统。
文章画下的那条分界线,值得每个提示工程师背下来。他们把工作流和 Agent 统称为智能体系统(agentic systems),但做了严格的区分。工作流(Workflow)里,预先写好的代码路径编排 LLM 和工具,每一步做什么、做完交给谁,都是工程师定的;Agent 则是模型在运行中动态决定自己的流程和工具使用,自己掌握完成任务的方式。说白了,工作流是“你按流程图走”,Agent 是“你自己看着办”。
这条线为什么跟写 Prompt 的人直接相关?因为它决定了 Prompt 的形态。在工作流一端,每个节点是一个“专才 Prompt”,短小、单一职责、输入输出格式固定,可以单独拿去测试,第 17 章的评估体系、第 19 章的发布门禁,都能原封不动地套上去。在 Agent 一端,Prompt 就是 20.5 那种五要素齐全的大部头,要为模型没见过的局面准备预案。自主性每多交出去一分,Prompt 要覆盖的情况就多一批,要测试的面也宽一圈。
文章给了五种常见的工作流模式。这里不展开工程细节,串行、并行、路由这些基本模式留到第 22 章的 Pipeline 设计里展开细讲,这里只站在提示工程师的视角,看每种模式下你的活儿在哪。
链式(Prompt Chaining)把任务拆成固定的串行步骤,上一步的输出喂给下一步,中间还可以插程序化的检查点。对提示工程师来说这是最舒服的模式,每个 Prompt 只管一件事,难点全在“接口”上,上一步的产出以什么格式进入下一步的上下文,格式设计得好,下一步几乎不需要额外的解析和交代。
并行(Parallelization)让多个 LLM 实例同时开工,程序负责汇总。它有两个变体,切分(Sectioning),把互相独立的子任务分头去做;投票(Voting),同一个任务跑多遍取共识。写 Prompt 时要守一条纪律,分支之间必须干净独立,不能在 A 分支里引用 B 分支还没算出来的结果;如果汇总也交给模型,那是一个独立的“汇总 Prompt”,它的输入格式要提前约定。
路由(Routing)先用一个分类 Prompt 给输入打标签,再按标签分发到不同的下游分支,让每条分支的 Prompt 都可以专心处理一类输入。路由器本身就是你写的一个 Prompt,个头不大,位置却很关键,它只该输出预先枚举好的标签,温度要压低,每个类别还要配 few-shot 例子防走偏。分错一个类,后面整条流水线跟着错。
编排者-工人(Orchestrator-Workers)让一个居中的“编排者”动态拆解任务、派给工人 LLM、再汇总结果。它和并行的区别在于,子任务不是预先定义的,而是编排者看着具体输入临场定的。这是从工作流往 Agent 过渡的中间地带,拆分任务的决策交给了模型,但每个工人的 Prompt 仍然是预先写好的专才 Prompt。第 22 章的多 Agent 协作(那里的经理-员工模式),展开的就是它。
评估器-优化器(Evaluator-Optimizer)让一个 LLM 生成,另一个 LLM 评审并给出反馈,循环到达标为止。细看那个评审 Prompt 的岗位描述,正是第 17 章的 LLM-as-a-Judge 搬进了生产线。这个模式最讲究分工纪律,评审者只挑毛病不动笔,生成者只按意见修改不辩解。
当然,也有工作流罩不住的场面。当任务的步骤数没法预先知道、每一步怎么走都得临场判断时,才是把流程决策整个交给模型的时机,也就是前面那条分界线的另一侧。Anthropic 同时提醒,自主性意味着更高的成本和误差叠加,要在沙箱里充分测试、配上护栏。那其实就是 20.3 那个核心循环完全归模型掌控的形态。
五种模式过完,回头再看 20.4 那个简历筛选项目,问题就看得很清楚了。简历解析和字段提取是格式固定、步骤清晰的活儿,用写死的代码加链式 Prompt 就能办;简历该分流到哪条岗位线,一个路由 Prompt 足够;几个岗位同时招人,天然是并行分支;各岗位的初筛结果交给编排者汇总;名单发出去之前,再过一道评估器-优化器的自审。当年的团队想要的“一个全能 Agent 解决所有问题”,恰恰是所有选项里最贵、最不可控的那一种。
所以”设计模式”对提示工程师来说不是空谈,它逼你回答一个具体到不能再具体的问题。这个系统里,哪些决策写死在代码里,哪些决策交给模型。Anthropic 在文章结尾把话挑明了,成功不在于建出最精巧的系统,而在于建出匹配需求的那个,先用简单 Prompt 加扎实评估起步,简单方案确实不够用了,再上多步的智能体系统。
20.8 什么时候该用 Prompt,什么时候该微调
聊到这里,你大概会想到一个非常重要的根本性问题,它可能在看到那个长达数千字的 System Prompt 时就已经萌生。
花了这么大的力气,设计出复杂的、包含五个核心部分的 System Prompt,又搭建起从单轮到持久化的架构,来管理 Agent 的记忆和状态。所有这一切,本质上都是在“教”一个通用的、预训练好的、什么都懂一点但什么都不精通的大语言模型,去理解和执行一个特定领域里充满“行话”和“潜规则”的任务。
具体到机制,模型没有拿这个领域的任务数据训练过,领域知识全靠 System Prompt 在每次调用时带进上下文;规则写得够细,覆盖到的任务它完成得不错。可这些知识不在模型参数里,Prompt 一撤、任务一换,它就退回那个什么都懂一点、什么都不精通的通用模型。它能照着写好的规则行事,对领域本身没有积累。
那么,为什么不干脆走另一条路?为什么不让模型在训练阶段,就把一个领域里过去几十年积累的海量数据,比如公司所有的客服对话记录、所有的产品设计文档、所有的销售周报、所有的内部代码库,连同其中的知识、技能,甚至公司独特的“气质”,都“内化”到那亿万个神经网络权重参数里去?
这个过程,就是常说的模型微调(Fine-tuning)。
通过微调,情况就反过来。模型用这个领域积累下的海量数据继续训练,领域知识直接写进参数,它对任务的熟悉来自训练本身,而不是每次调用时 Prompt 带进来的规则。这样一来,是不是就不需要那么复杂的 Prompt 了?Agent 的行为会不会更可靠、更专业、更懂行?
这是一个关键问题。构建任何一个严肃的、打算长期演进的 AI 应用,都必须在“Prompt 工程 vs. 模型微调”之间,做出审慎的决策。
很多初学者,甚至一些有经验的工程师,都容易陷入一个非黑即白的误区,认为这两者是水火不容的替代关系。要么全靠 Prompt,要么全靠微调。但实际上,它们各有所长,最高效的团队懂得把两者组合使用,也懂得什么时候该以哪边为主。
为了讲清这个决策过程,不妨来看一个故事。假设有两支技术团队,一支叫“敏捷的提示词队”,一支叫“稳健的微调队”,他们接到了同一个听起来很简单、实际上坑很多的任务,为一家大型电商公司开发一个处理售后退款申请的客服 Agent。
“敏捷的提示词队”的理念是“天下武功,唯快不破”。他们选择了市面上最强大的那个通用大模型,拿到 API key 之后,几乎没有开什么冗长的需求评审会,立刻就撸起袖子开干了。
第一天,他们就把产品经理和一位在客服一线干了十年的“老师傅”请到会议室,一边聊天,一边就在 Playground 里写出了第一版的 System Prompt。
这个 Prompt 里,充满了那位老师傅的“口头禅”和“经验之谈”,比如“你是一位耐心、专业且有同理心的金牌客服,记住,用户来退款,心里肯定不爽,你第一句话永远是安抚情绪,而不是讲道理”、“你的核心使命是在遵守公司退款政策的前提下,高效地为用户解决退款问题,但要记住,政策是死的,人是活的,遇到特殊情况要懂得变通”、“这是你手上的工具:一个查订单状态的 API,一个发起退款流程的 API,记住,发起退款是最后一步,在那之前,一定要先尝试说服用户换货”...
一个星期后,他们已经做出了一个可以工作的原型(Prototype)。这个 Agent 已经能处理一些最简单的退款请求了。虽然它有时候会误解用户的意思,或者忘记某些退款政策的细节,但它已经能跑起来了。团队可以拿着这个原型,快速地进行内部演示,让老板和业务方看到实实在在的进展,收集最真实的早期反馈。
接下来的一个月,进展非常顺利。产品经理跑来说,用户经常会问一些关于“运费险”的刁钻问题,而原来的 Prompt 里没有覆盖。没关系,团队花半个小时,和客服专家一起,在 System Prompt 里增加了一段关于运费险政策的详细说明和几个典型案例,Agent 立刻就“学会”了,比真人培训还快。法务部门又发来邮件,说根据最新的消费者权益保护法,某些特殊商品不支持七天无理由退货。同样,也只是在 Prompt 的约束部分,用加粗的、警告性的语气,增加一条规则而已。
“提示词队”的优势在这里体现得很清楚。他们拥有极高的敏捷性,业务逻辑的任何变更,都可以在分钟级别通过修改 Prompt 文本来完成部署,不需要任何漫长的模型训练和部署流程。他们的启动成本极低,不需要关心数据标注、GPU 资源这些头疼的问题,只需要专注在业务逻辑的 Prompt 表达上。而且,因为背靠强大的通用模型,他们的 Agent 天生就具备了处理各种千奇百怪的用户问法的能力,鲁棒性和泛化能力都相当不错。
但他们也很快撞上了上限。他们发现,无论 Prompt 写得多细,这个 Agent 的回答总有点生硬,像是照着标准答案在应付,缺了金牌客服那种自然的分寸。而且,随着业务规则越来越复杂,他们的 System Prompt 变得越来越长、越来越臃肿。这不仅导致每次 API 调用的 Token 成本居高不下,也让 Prompt 的维护越来越难,改动一个地方,可能会影响到另一个看似不相关的逻辑。
与此同时,“稳健的微调队”则走了一条完全不同的、看起来更“笨”的道路。他们的信条是“慢工出细活,磨刀不误砍柴工”。
他们的第一个月,几乎没有写任何 Agent 相关的代码。他们的全部精力,都投入到了数据准备上。他们从公司的数据库里,导出了过去三年来数百万条的、经过脱敏处理的客服对话记录,然后组织人力,对这些数据进行清洗、筛选和标注,最终整理出了几万条高质量的、金牌客服处理过的“(用户棘手问题, 完美回答)”数据对。这个过程是枯燥、繁琐且极其昂贵的。
他们的第二个月,才开始进入模型阶段。他们选择了一个合适的开源基础模型(比如 Meta 的 Llama 系列、阿里 Qwen 系列、DeepSeek 系列,或者 Mistral 等当时市面上口碑较好的开源选项之一;开源生态迭代极快,选型请以当下的实际清单为准),租用了几台价格不菲的云 GPU 服务器,开始了漫长的微调训练。第一次训练出来的模型,效果很差,回答经常不着边际。他们不气馁,回去调整超参数,优化数据集的配比,又进行了好几轮训练。每一次点击“开始训练”按钮,都意味着数小时甚至数天的等待和不低的算力开销。
直到第三个月的月底,在经历了无数次失败和调整后,他们才终于拿出了第一个让自己满意的定制模型。部署成 Agent 后,效果很好。这个 Agent 的语气和风格,甚至表情符号的使用,都和公司里最受欢迎的金牌客服“王姐”非常接近。它对各种冷门的退款政策细节都很熟悉,因为这些知识已经通过训练写进了模型参数。更重要的是,模型是为这个特定任务定制的,尺寸比通用大模型小得多,每次调用的推理速度更快,长期来看,成本也更低。
“微调队”的优势,在于他们通过艰苦的努力,打造了一个真正的“领域专家”。它拥有深度的领域化能力,表现得极其专业和自然。它在达到一定调用规模后,能实现更高的性能和更低的成本。那些不常变化的、核心的知识和行为模式,通过微调固化下来,比写在 Prompt 里更可靠、更稳定。
但他们的痛苦也同样真实。当产品经理兴冲冲地跑来告诉他们,公司为了应对“双十一”,下周要临时上线一个新的“闪电退款”政策时,“微调队”的负责人立刻紧张起来。这意味着,他们可能需要紧急准备一批包含新政策的训练数据,然后把整个昂贵而漫长的微调流程再走一遍。他们完全无法像“提示词队”那样,在几分钟内就让 Agent “学会”新知识。他们的系统,虽然稳健,但也表现出了极强的“惯性”和“迟钝性”。
故事的结局,并不是哪一队单方面胜出。
在现实世界里,最可能成功的,是一个既不完全像“提示词队”也不完全像“微调队”的“混合队”。他们吸收了两个团队的教训和优点,走出了一条更聪明的路。
他们的策略可以浓缩成一句话,永远从 Prompt 工程开始。在项目混沌的初期,用最快的速度,基于通用大模型和 Prompt,搭建一个“最小可行产品”(MVP)。用这个 MVP 去验证业务需求、探索用户场景、收集真实的数据。在这个阶段,灵活性和迭代速度,比什么都重要。
用微调来“固化”那些已经稳定的能力。 当系统运行了一段时间,收集了足够多的数据后,团队会坐下来复盘,他们会发现,Agent 的能力其实可以分为两部分。一部分是“稳定的内核”,比如它那独特的、代表公司形象的沟通风格,对那些万年不变的核心政策的理解,处理常见问题的标准流程。另一部分是“动态的外壳”,比如每周都在变的营销活动规则,需要临时处理的用户投诉,新上线的功能介绍等等。
于是有了另一个关键决策,实施混合架构。用第一阶段收集到的高质量对话数据,去微调一个基础模型。这次微调的目标,不是教会模型所有的业务逻辑,而是把那个“稳定的内核”写进模型,做一个带着金牌客服风格的专属基础模型。
让 Prompt 负责“动态指挥”。 他们把这个微调过的专属模型,作为 Agent 的底座模型,在上面继续使用 Prompt 工程。但这个时候,Prompt 的任务就大大减轻了,它变得更短、更清晰、更聚焦。它不再需要长篇大论地去描述“你应该是什么语气”,因为这个模型天生就是这个语气。Prompt 只需要专注于那些“动态的外壳”,告诉 Agent 今天有什么新的促销活动,或者如何处理一个临时的系统故障公告。
这才是最智慧的解法。微调,负责解决“它是谁”(Being)的根本问题;Prompt,负责解决“它做什么”(Doing)的战术问题。
微调,是把那些稳定的、普适的、高频使用的知识和风格,通过一次性的、高投入的训练,写进模型参数,从而在长期的运行中,降低运行成本,提升专业度和稳定性。而 Prompt,则保留了应对易变的、临时的、具体的业务逻辑的灵活性和敏捷性。
这就是在 Prompt 和微调之间,最符合工程实际的决策。它不是一道二选一的选择题,而是如何让两种技术互补的系统设计题。优秀的提示工程师不仅要会写精妙的 Prompt,还要懂得在合适的时机向团队建议:“嘿,伙计们,我们的 MVP 已经跑得很好了,也积累了足够多的数据。是时候考虑给我们的 Agent,做一次‘大脑升级手术’了。”
本章总结 从对话者到系统设计者
咱们这一章把 Agent 从头到尾拆解了一遍,把它从很多人眼中一个神秘的黑盒,拆解成一个工程师能够理解、能够分析、能够掌控的工程系统。
先给了 Agent 一个白话的界定,会聊天的变成会干活的;紧接着盘了一张能力地图,能说清、有工具、可验证、容得下绕路,四条判据先用来判断“这事该不该交给 Agent”,再谈怎么写。判断,永远排在技巧前面。
然后才拆开它的核心机制,看那个不断重复的循环,“感知-规划-行动”这组动作反复出现。这说明无论外表多么复杂的 Agent,内核都是这个朴素循环的不断重复,而主战场就在于如何通过 Prompt 精准地控制那个负责“规划”的 LLM。
光有正面清单还不够,接着看了一次真实的翻车。死循环、编造、越权,三起事故反着印证了判据,也把根因钉死了,它是一个需要设计、约束和调试的工程系统,不是一个即插即用的黑盒。后面的一切设计,都是从这次复盘里来的。
这一章最大的篇幅,给了如何编写一个高质量的 System Prompt。这不再是简单地写几条指令,而是一项严肃的角色设计工作,把角色、使命、工具、准则和思考流程五个部分定清楚。而落到纸面上的每句话,都要朴素、明确、可检验,这才是行为稳定可靠的真正来源。
接着是 Agent 的三种架构模式,单轮 Agent 一次性完成任务,多轮 Agent 有会话内的短期记忆、能连贯对话,持久化 Agent 有跨会话的长期记忆。Agent 能力的每一次提升,都伴随着工程复杂度的增加,对工程师的传统软件工程能力提出更高要求。
再往上一层,是设计模式的抉择。借 Anthropic《Building Effective Agents》那条工作流与自主 Agent 的分界线,串起了链式、并行、路由、编排者-工人、评估器-优化器五种模式。这一层回答的是“自主性放在哪”,而答案直接决定 Prompt 的形态,是短小的专才指令,还是五要素齐全的“操作系统”。
最后比较了 Prompt 工程与模型微调。通过“敏捷的提示词队”和“稳健的微调队”那个对比故事,得到一个能指导未来几年工作的结论,它们不是敌人,而是盟友。用微调固化“稳定内核”,用 Prompt 指挥“动态行为”,这种混合模式,才是构建成熟、健壮且经济高效的 Agent 系统的可行路线。
走到这里,“提示工程师”这个角色的内涵,已经发生了根本性的转变。
前半本书里,提示工程师更多时候是一个“对话者”,学习语言的技巧,研究模型的特性,想办法让模型听懂意图、完成任务。
而从这一章开始,这个角色正在向“系统架构师”转变。不再满足于一次成功的对话,而是思考如何设计一个能自主运转、有记忆、有目标的系统。Prompt 也不再仅仅是沟通的语言,它变成了这个系统的控制规范,协调 LLM、外部工具、数据库、业务逻辑各司其职。
参考资料
- LangChain. LangGraph 发布博客(官方定位为支持带环的循环图,用于编排 Agent 工作流). https://www.langchain.com/blog/langgraph
- LangChain. LangGraph 文档 Graph API(以图建模 Agent 工作流,支持循环). https://docs.langchain.com/oss/python/langgraph/graph-api
- Anthropic. Claude Agent SDK 概述(与 Claude Code 同源的工具集与 Agent 循环,支持 Computer Use 等内置工具). https://code.claude.com/docs/en/agent-sdk/overview
- OpenAI. New tools for building agents(Agents SDK 与 Responses API,2025 年 3 月发布). https://openai.com/index/new-tools-for-building-agents/
- Microsoft Azure. Introducing Microsoft Agent Framework(2025 年 10 月 1 日宣布公开预览). https://azure.microsoft.com/en-us/blog/introducing-microsoft-agent-framework/
- AWS. Amazon Bedrock Agents 产品页与用户指南. https://aws.amazon.com/cn/bedrock/agents/ 及 https://docs.aws.amazon.com/bedrock/latest/userguide/agents.html
- Jiaxin Pei 等. Personas in System Prompts Do Not Improve Performances of Large Language Models. Findings of EMNLP 2024(162 个角色人设、2410 道事实题、4 个模型家族的系统评测:系统提示中加入人设不提升事实类任务表现,人设间差异基本随机;代码与数据见 Jiaxin-Pei/Prompting-with-Social-Roles). arXiv:2311.10054. https://arxiv.org/abs/2311.10054
- Anthropic(Erik S., Barry Zhang 执笔). Building Effective Agents(工作流与 Agent 的架构区分、链式/路由/并行/编排者-工人/评估器-优化器五种模式、“寻找最简方案”原则与工具文档三原则;2024 年 12 月发布,页面现附更新提示,工具生态其后已有变化,模式本身仍是行业通用语言). https://www.anthropic.com/engineering/building-effective-agents