1. 为什么“20+真实场景”才是Agent开发的分水岭
1.1 从“能跑通”到“能交付”之间隔着什么
我见过太多人学Agent开发的路径是这样的:看几篇讲ReAct模式的文章,照着官方文档跑通一个“查天气”的Demo,然后觉得自己会了。结果一到真实项目里,面对一个“帮我把这批客户咨询自动分类并生成回复草稿”的需求,直接卡住——因为Demo里没有多轮状态管理,没有异常兜底,没有并发控制,更没有成本核算。
这就是“20+真实场景全链路教程”这个标题背后真正值钱的东西。它不是在教你Agent是什么,而是在教你Agent从需求到上线中间那几十个决策点怎么拍板。全链路的意思,是从场景拆解、架构选型、工具编排、记忆设计、评测迭代,一直到部署监控,每一环都得有可复用的方法论。
我自己的经验是,一个Agent项目真正的工作量分布大概是这样的:核心推理逻辑占20%,工具和数据管道占30%,异常处理和边界情况占30%,评测和调优占20%。大部分人只学了那20%,剩下80%全靠踩坑补。这篇内容我想做的就是把这80%摊开讲清楚。
1.2 哪些人适合啃这块硬骨头
先说清楚适配人群,免得你浪费时间。如果你是完全零基础、连Python函数和HTTP请求都没写过,那建议先去补基础,Agent开发不是入门第一站。但如果你符合下面任意一条,这篇内容会对你有直接帮助:
- 有后端或前端开发经验,想把自己的工程能力迁移到Agent方向;
- 已经跑通过一两个Demo,但不知道怎么把它变成能给别人用的产品;
- 在做企业级应用,需要评估Agent到底能不能扛住真实业务量;
- 带团队做AI应用,需要一套可复制的场景落地框架。
关键词里的“AI智能体”“Agent”“实战开发”“全链路教程”,本质上指向同一件事:把Agent当成一个正经软件系统来工程化,而不是当成一个玩具来演示。下面我按真实项目的推进顺序,把每个环节拆开讲。
2. 场景拆解:20+场景不是凑数,是覆盖决策矩阵
2.1 场景分类的正确姿势
很多人拿到“20+场景”会以为是20个互不相干的案例,其实真正有价值的是场景背后的决策矩阵。我习惯按两个维度给Agent场景分类:一个是交互复杂度(单轮问答、多轮对话、长任务执行),另一个是工具依赖度(纯推理、单工具调用、多工具编排、外部系统深度集成)。
把这两个维度一交叉,就能得到一张四象限图。比如“智能客服FAQ”落在低交互复杂度、低工具依赖度这一格,用最简单的RAG加提示词就能搞定;“自动生成周报并发送邮件”落在中交互复杂度、中工具依赖度;“跨系统数据核对与异常上报”则落在高交互复杂度、高工具依赖度。
为什么要这么分?因为不同象限的Agent,架构选型完全不同。低象限的用单体提示词就够,高象限的必须上多Agent协作加状态机。你要是拿低象限的方案去做高象限的事,系统一定崩。
2.2 我实际用过的场景清单与优先级
下面这张表是我在多个项目里沉淀下来的场景优先级参考,按“落地难度”和“业务价值”排了序。新手建议从难度1到3开始,别一上来就啃难度5的。
| 难度 | 典型场景 | 核心技术点 | 建议起步方案 |
|---|---|---|---|
| 1 | 文档问答、知识检索 | RAG、向量检索 | 单体Agent+检索工具 |
| 2 | 表单填写、信息抽取 | 结构化输出、校验 | 提示词约束+JSON Schema |
| 3 | 多轮客服、意图路由 | 状态管理、意图分类 | 有限状态机+Agent |
| 4 | 数据分析、报表生成 | 代码执行、工具编排 | 代码解释器+多工具 |
| 5 | 跨系统任务自动化 | 多Agent协作、长任务 | 编排框架+持久化状态 |
这张表的关键在于,难度不是线性增长的,而是每升一级都会引入新的失败模式。难度1的失败主要是检索不准,难度3的失败就变成状态丢失和意图误判,难度5的失败可能是整个任务链在第三步就断了却没人发现。所以“全链路”的核心,是每一级都要配套对应的可观测性和兜底机制。
2.3 场景选错了,后面全白搭
我踩过最大的坑,就是早期接了一个“看起来很简单”的场景:帮运营自动回复用户评论。当时觉得不就是分类加生成吗,结果上线后发现,用户评论里充满了反讽、谐音、多语言混用,分类准确率死活上不去,生成的内容还经常踩雷。
后来复盘才明白,场景选型要评估“容错成本”。评论回复这种场景,错一条就可能引发舆情,容错成本极高,不适合作为早期Agent落地场景。反而是“内部工单初筛”“会议纪要整理”这类场景,错了有人工兜底,容错成本低,适合快速迭代。
所以选场景的时候,除了看技术难度和业务价值,一定要加一列“容错成本”。容错成本高的场景,要么等技术成熟,要么必须设计人工审核环节。
3. 架构选型:单体、编排还是多Agent
3.1 三种架构的适用边界
Agent架构大致分三档:单体Agent、编排式Agent、多Agent协作。这三档不是越复杂越好,而是要看场景匹配。
单体Agent就是一个大模型加一组工具,所有决策都在一次推理里完成。优点是简单、延迟低、调试容易;缺点是上下文一长就容易“忘事”,工具一多就容易选错。适合难度1到2的场景。
编排式Agent是把任务拆成多个步骤,用一个编排层(可以是代码,也可以是另一个Agent)来控制流程。每一步可以是独立的Agent调用,也可以是纯代码逻辑。优点是可控性强、每步可观测;缺点是需要设计流程,灵活性下降。适合难度3到4。
多Agent协作是让多个各有专长的Agent互相通信、分工完成复杂任务。优点是能处理高度复杂的任务;缺点是调试地狱、成本高、容易出现“Agent之间互相甩锅”。适合难度5,且必须有完善的日志和追踪。
我的建议很直接:能用单体就别上编排,能用编排就别上多Agent。每增加一层复杂度,你的调试时间至少翻倍。
3.2 编排框架怎么选
市面上Agent编排框架不少,选型的时候我主要看四点:状态管理能力、工具集成生态、可观测性、以及是否容易做单元测试。
状态管理是重中之重。一个多轮任务,用户可能在第三步改了需求,Agent得能回滚或者重新规划。如果框架不支持持久化状态,你就得自己造轮子。工具集成生态决定了你接外部系统要花多少时间。可观测性决定了出问题的时候你能不能快速定位。单元测试能力决定了你敢不敢改代码。
我个人的经验是,不要迷信“全自动”的框架。很多框架号称能自动规划、自动反思,但实际用下来,自动规划出来的步骤经常不靠谱,还不如你自己写死流程。所以我现在更倾向于“半自动”方案:流程由代码控制,每个节点内部用Agent做决策。这样既有Agent的灵活性,又有代码的可控性。
3.3 一个真实的架构决策案例
之前做过一个“合同条款风险审查”的Agent。需求是上传合同,自动标出有风险的条款并给出修改建议。
一开始想用单体Agent,把合同全文塞进去让它一次性输出。结果发现两个问题:一是合同太长,超出上下文窗口;二是模型容易漏掉中间部分的条款。
后来改成编排式:先用代码把合同按条款切分,然后每个条款单独过一个Agent做风险判断,最后再用一个Agent汇总。这样每个Agent的上下文都很短,准确率大幅提升。但新的问题是,条款之间的关联风险(比如付款条款和交付条款互相矛盾)单条款审查发现不了。
最终方案是两阶段:第一阶段逐条审查,第二阶段把第一阶段的结果作为输入,专门做跨条款一致性检查。这个案例让我深刻体会到,架构不是一次定好的,而是随着你发现新的失败模式不断演进的。
4. 工具编排与记忆设计:Agent的手和脑
4.1 工具设计的三个原则
Agent的工具就是它的手。工具设计得好不好,直接决定Agent能不能干活。我总结三个原则:
第一,工具粒度要适中。太粗的工具(比如一个“处理订单”工具包揽所有逻辑)会让Agent无法精细控制;太细的工具(比如“查询数据库第3行第5列”)会让Agent陷入选择困难。好的粒度是“一个工具做一件完整的小事”,比如“根据订单号查询订单状态”。
第二,工具描述要像写给新员工的说明书。模型选工具靠的是描述,描述里要写清楚:这个工具干什么、什么时候用、输入输出是什么格式、有什么限制。我见过太多人工具描述就写一句话,然后抱怨模型选错工具。
第三,工具要有防御性。模型可能会传错参数、传空值、传超长文本。工具内部必须做校验和兜底,不能假设输入永远正确。我一般会在工具入口加一层参数校验,不合法就直接返回明确的错误信息,让模型知道哪里错了。
4.2 记忆系统的分层设计
Agent的记忆分三层:短期记忆(当前对话的上下文)、长期记忆(跨会话的用户偏好和历史)、工作记忆(当前任务的中间状态)。
短期记忆最直接,就是对话历史。但要注意上下文窗口限制,不能无限塞。我的做法是保留最近N轮完整对话,更早的做摘要压缩。
长期记忆需要外部存储,常见的是向量数据库。但这里有个坑:不是什么信息都值得存。我早期把所有对话都存进向量库,结果检索出来的全是噪音。后来改成只存“用户明确表达的偏好”和“任务的关键结论”,检索质量立刻上来了。
工作记忆是最容易被忽视的。一个长任务执行到一半,中间状态存哪里?如果只存在内存里,进程一重启就全丢了。我的做法是把工作记忆持久化到数据库,每个步骤完成后更新状态,这样即使中断也能恢复。
4.3 记忆检索的实战技巧
记忆检索的核心是“什么时候去检索”。我的经验是,不要每轮都检索,那样既慢又容易引入无关信息。更好的做法是在任务开始时检索一次,拿到相关背景,然后在任务过程中按需检索。
检索的query也很关键。直接用用户原话检索,效果往往不好,因为用户的话可能很口语化。我一般会先用模型把用户意图转成结构化的检索query,再去检索。这一步多花一点时间,但检索质量提升明显。
还有一个技巧是给记忆加时间衰减。越久远的记忆权重越低,这样Agent的决策会更贴近用户当前的状态。实现上就是在检索排序时,把时间因素作为一个权重加进去。
5. 全链路实操:从零搭一个可用的Agent
5.1 环境准备与依赖安装
假设我们要做一个“技术文档问答Agent”,能读取本地文档、回答技术问题、并在不确定时主动说“我不知道”。这是难度1到2的场景,适合作为第一个完整项目。
先准备环境。Python 3.10以上,主要依赖包括大模型SDK、向量数据库客户端、文档解析库。我用的是比较通用的组合,你可以按自己实际情况替换。
pip install openai chromadb pypdf tiktoken这里解释一下每个依赖的作用:大模型SDK负责调用模型,向量数据库负责存文档向量,文档解析库负责把PDF转成文本,分词库负责计算token数量做上下文控制。选这些是因为它们都比较轻量,本地就能跑,不需要额外部署服务。
注意:向量数据库在生产环境建议用独立部署的方案,本地文件版只适合开发和测试。因为本地版在并发写入时容易出问题。
5.2 文档入库与向量化
第一步是把文档切分并向量化。切分策略很关键,切太大检索不准,切太小丢失上下文。我的经验是按语义切分,每段300到500字,段间保留50字重叠。
from pypdf import PdfReader import chromadb def load_and_split(pdf_path, chunk_size=400, overlap=50): reader = PdfReader(pdf_path) full_text = "" for page in reader.pages: full_text += page.extract_text() chunks = [] start = 0 while start < len(full_text): end = start + chunk_size chunks.append(full_text[start:end]) start = end - overlap return chunks client = chromadb.Client() collection = client.create_collection("tech_docs") chunks = load_and_split("manual.pdf") collection.add( documents=chunks, ids=[f"chunk_{i}" for i in range(len(chunks))] )重叠的作用是防止一个完整的句子被切断,导致检索时语义不完整。这个参数我调过很多次,50字左右是比较平衡的值。
5.3 Agent主循环与工具定义
Agent的核心是一个循环:接收输入、决定是否调用工具、执行工具、把结果喂回模型、继续推理直到得出最终答案。
import json def search_docs(query, top_k=3): results = collection.query(query_texts=[query], n_results=top_k) return "\n".join(results["documents"][0]) tools = [{ "type": "function", "function": { "name": "search_docs", "description": "搜索技术文档,当需要查找具体技术细节时使用", "parameters": { "type": "object", "properties": { "query": {"type": "string", "description": "搜索关键词"} }, "required": ["query"] } } }] def run_agent(user_input, max_turns=5): messages = [{"role": "user", "content": user_input}] for _ in range(max_turns): response = call_llm(messages, tools=tools) if response.tool_calls: for call in response.tool_calls: args = json.loads(call.function.arguments) result = search_docs(**args) messages.append({"role": "tool", "content": result}) else: return response.content return "抱歉,我无法在限定步骤内完成这个任务。"这里max_turns是防止Agent陷入死循环的关键。我见过Agent因为工具一直返回空结果,反复调用同一个工具直到烧光token。设一个上限,超了就优雅退出。
5.4 提示词里的关键约束
系统提示词决定了Agent的行为边界。我的模板里必含这几条:只基于检索到的内容回答、不确定时明确说不知道、不编造文档里没有的信息、回答要引用来源。
SYSTEM_PROMPT = """你是一个技术文档助手。 规则: 1. 只根据search_docs返回的内容回答,不要使用你自己的知识。 2. 如果检索结果不包含答案,直接说"文档中没有相关信息"。 3. 回答时标注信息来源的段落。 4. 不要编造任何文档中不存在的内容。"""第2条特别重要。很多Agent的幻觉问题,根源就是提示词没有明确允许它说“不知道”。你给了它必须回答的压力,它就只能编。
6. 评测与迭代:怎么知道Agent到底行不行
6.1 建立评测集比调提示词更重要
我见过太多人把时间花在反复改提示词上,改了半天也不知道到底变好了还是变差了。没有评测集,调优就是盲人摸象。
评测集怎么建?从真实用户问题里采样。至少准备50到100条,覆盖常见问题和边界情况。每条标注期望答案或者期望行为(比如“应该调用搜索工具”“应该说不知道”)。
评测指标我一般看三个:准确率(答案对不对)、工具调用正确率(该调工具时调了没、调对没)、幻觉率(编造信息的比例)。这三个指标里,幻觉率是最要命的,宁可Agent说不知道,也不能让它编。
6.2 迭代的优先级排序
发现问题后,改哪里?我的优先级是:先改检索,再改提示词,最后才考虑换模型。
因为大部分Agent的失败,根源在检索没找到正确信息,而不是模型不行。检索问题又分两种:文档没入库(覆盖问题)和检索没召回(排序问题)。前者补文档,后者调切分策略和检索参数。
提示词的问题通常是约束不够明确。比如Agent该调工具没调,往往是工具描述写得不够清楚,或者提示词里没说清楚什么时候该调。
换模型是最后手段,因为成本高、影响面大。而且很多时候换个更强的模型,只是掩盖了检索和提示词的问题,并没有真正解决。
6.3 一个评测驱动的优化实例
回到文档问答Agent。第一版评测下来,准确率只有60%,幻觉率15%。分析失败案例发现,大部分错误是检索没召回正确段落。
调整切分策略,从固定400字改成按段落切分,准确率升到72%。然后发现有些问题需要跨段落信息,单次检索不够,改成检索top5再让模型筛选,准确率升到81%。最后优化提示词,明确要求引用来源,幻觉率降到4%。
整个过程没有换模型,全靠检索和提示词优化。这就是评测驱动的价值:每一步改动都有数据支撑,知道钱花在哪、效果有多少。
7. 常见问题与排查技巧实录
7.1 高频问题速查表
| 问题现象 | 可能原因 | 排查方向 |
|---|---|---|
| Agent不调用工具 | 工具描述不清、提示词没引导 | 检查工具description和system prompt |
| 反复调用同一工具 | 工具返回结果模型无法理解 | 检查工具返回格式,加错误提示 |
| 回答编造信息 | 提示词没允许说不知道 | 加"不确定时明确说明"约束 |
| 上下文超限 | 对话历史或检索结果太长 | 加摘要压缩、限制检索条数 |
| 响应特别慢 | 串行调用太多、检索慢 | 并行化工具调用、加缓存 |
| 多轮对话丢失状态 | 状态没持久化 | 检查工作记忆存储 |
7.2 几个我踩过的深坑
坑一:工具返回格式不统一。有的工具返回JSON,有的返回纯文本,模型处理起来很混乱。后来我强制所有工具返回统一的结构化格式,问题解决。
坑二:检索结果直接塞给模型。检索出来的段落可能包含大量无关内容,直接塞进去会干扰模型判断。后来加了一步“相关性过滤”,让模型先判断哪些段落真正相关,再基于相关段落回答。
坑三:没有超时控制。某个外部工具卡住,整个Agent就挂在那里。后来给所有工具调用加了超时,超时就返回错误让模型决定下一步。
坑四:日志不够详细。出问题的时候不知道Agent中间想了什么、调了什么。后来把每一轮的模型输入输出、工具调用参数和结果全部落盘,排查效率提升巨大。
7.3 并发场景的特殊处理
关键词里有人问“Agent怎么扛并发”,这是个好问题。Agent的并发瓶颈通常不在模型调用,而在工具和状态管理。
工具层面,如果工具有外部依赖(比如查数据库),要加连接池和限流。状态层面,如果多个请求共享状态,必须加锁或者用无状态设计。我的做法是每个请求独立状态,不共享,这样天然支持水平扩展。
模型调用层面,要注意速率限制。我一般会加一个请求队列,超过速率就排队,而不是直接失败。同时做好重试和降级,模型调用失败时返回一个兜底回复,而不是让用户看到报错。
8. 从Demo到产品的最后一公里
8.1 可观测性建设
Demo和产品的最大区别,是产品出问题的时候你得知道问题在哪。Agent的可观测性至少要覆盖:每次请求的完整链路、每轮模型调用的输入输出、每次工具调用的参数和结果、整体耗时和token消耗。
我一般用结构化日志,每条日志带上request_id,这样能把一次请求的所有相关日志串起来。关键指标包括:平均响应时间、工具调用成功率、模型调用失败率、平均token消耗。这些指标要能实时看,出问题能告警。
8.2 成本控制
Agent的成本主要来自模型调用。控制成本的手段有几个:缓存(相同问题直接返回缓存结果)、模型分级(简单任务用小模型,复杂任务用大模型)、上下文压缩(减少不必要的token)、限制最大轮数(防止死循环烧钱)。
我做过一个统计,加了缓存之后,重复问题的成本直接降到接近零。模型分级也能省不少,因为大部分请求其实都是简单问题,用便宜模型完全够。
8.3 安全与边界
Agent的安全问题主要有两类:提示词注入和越权操作。提示词注入是用户在输入里藏指令,试图让Agent执行非预期操作。防御方法是把用户输入和系统指令严格隔离,并且对工具调用做权限校验。
越权操作是Agent调用了不该调用的工具,或者访问了不该访问的数据。防御方法是最小权限原则,每个Agent只给它完成当前任务必需的工具和权限,不多给。
提示:上线前一定要做一轮对抗测试,专门尝试用各种方式诱导Agent越权或泄露信息。这一步不能省。
8.4 持续迭代机制
Agent上线不是终点,而是起点。要建立用户反馈收集机制,把bad case定期整理进评测集,形成“发现问题、加入评测、优化、回归测试”的闭环。
我一般每周做一次bad case复盘,每月做一次全量评测。这样能保证Agent的能力随着真实使用不断进化,而不是上线即巅峰然后慢慢退化。
这套东西说起来不复杂,但真正做下来,每一个环节都有无数细节要抠。我自己的体会是,Agent开发最难的从来不是模型本身,而是把模型嵌进一个可靠的工程系统里。模型能力在快速进步,但工程能力得靠自己一点点攒。把上面这些环节都跑通一遍,你对Agent的理解会完全不一样。