
最近这一周我基本是在跟 token 账单、模型版本、还有几个“不太听话”的 agent 来回拉扯中度过的。圈子里也都在聊同一个趋势更少的 token 消耗、更强的模型能力、以及越来越难被管控的 agent。这三个点放在一起看其实正好就是当下 AI 工程最真实的写照——大家都在一边想方设法省成本一边又忍不住把更复杂的任务交给模型最后还得跟上 agent 这匹野马的缰绳。写这篇东西是想把这周的观察和实操梳理一下。我自己是做 AI 应用落地的平时会同时接好几个项目有偏文本生成的、有做流程自动化的、也有刚把 agent 系统推到线上的。如果你也在做类似的事情或者正准备把模型接入业务、让 agent 干点正事那这篇内容应该能给你些参考。多说一句这不是什么理论科普是那种踩坑之后、想记录下来的真实工作手记。1. 整体设计与思路拆解为什么一周之内大家突然都在聊这三个词先说我对这周整体风向的判断。你可以把“更少 token、更强模型、更难管的 agent”理解成一个三角关系token 是成本模型能力是上限agent 是复杂度来源。几乎所有项目的问题最后都能归结到这三个坐标的拉扯上。1.1 从工程视角重新定义“更少 token”很多人看 token第一反应是省钱。这没错但只对了一半。我在实际项目里会发现token 的消耗直接影响的不只是账单还有延迟、错误率、以及整个系统能不能在业务高峰撑住。举个例子上周我维护的一个文档解析服务prompt 写得比较贪心每一篇长文都要让模型重新读一遍全文再总结。结果单次请求最多能烧掉一万多 token这还只是输入部分。用户那边数据量一大光是支撑并发测试一个月就多花了差不多四成的预算。后来把输入做了预处理用滑动窗口把长文本切成语义块再让模型分段总结单位成本直接砍掉一多半。所以“更少 token”背后其实是一次信息架构的重新设计。它要求你在进入模型之前就完成大部分工作——比如抽取关键段落、把结构化字段填好、把历史会话压缩成摘要。模型只干最擅长的那一部分判断和生成其他脏活累活尽量不做。这个概念我觉得才是这一周大家真正在讨论的核心不是简单地写一句“尽量少用点 prompt”而是要重构整条数据流。1.2 更强模型并不意味着无脑升级这一周各家模型都有动作新版本一个接一个参数评测分数看着也确实漂亮。但工程上换模型不是“下载新权重”那么简单它牵涉到全套回归测试。像我自己维护的那套 NLU 意图识别服务每次模型升级我都会准备 500 条典型样本逐条对比新旧输出。有些模型在复杂推理上更强但会在原来很简单的指令上改变口吻甚至把原有输出格式弄坏。举个例子有个同事负责的问答机器人之前用的是旧版模型输出 JSON 一直很稳定。升级之后某些边界场景突然开始混入 Markdown 代码块直接把下游解析干崩了。最后排查了半天发现是模型在不同系统提示词下的格式化偏好变了。这种情况其实挺常见的能力强是一个综合指标但落到你特定的业务形态上好与坏需要重新定义。所以我对“更强模型”的态度是可以追新但必须有一个可靠的对齐机制。不要因为榜单分数高就直接切生产至少先跑一轮核心场景回归再对比一下 token 单耗和响应延迟的变化。毕竟模型变强通常也意味着它更“啰嗦”你的成本曲线可能也会跟着变。1.3 agent 正在成为系统复杂度最大的来源如果说 token 和模型还属于“可预见”的工程变量那 agent 基本就是“黑天鹅”孵化器。原因是 agent 引入了连招它先自主规划步骤再调用一长串工具最后还可能根据中间结果修正下一次决策。这听起来很智能但在工程上意味着系统的状态空间急剧膨胀你很难像调试普通函数一样去定位问题。这周我在测试一个自研 agent 框架让它处理一个“跨多表查询并生成汇总报告”的任务。它确实完成了过程也没报错。但最后我查看执行日志时发现它跑来跑去两次调用了同一个外部数据库接口多花了额外时间还拿了一个其实不该重复获取的字段。这种行为在单次执行里看不出毛病一旦放开到几十个并发场景、接几十个工具就会累积成可怕的资源浪费和隐藏的副作用。因此我更倾向于把 agent 看成一种“需要监督的分布式系统”而不是一个独立的函数。它的每一个决策点都值得记录每一步工具调用都应当有 trace每一个输出都应当和预期做比对。这三个观察点其实也正好构成了我接下来要展开的主线。2. 核心细节解析与实操要点token 压缩、模型对齐、agent 可观测的落地方法理论归理论落地还是要靠细节。这一部分我想拆开来讲每个方向都放一些我实际用过、验证过的方法和对错经验。2.1 token 压缩的几条实战路径从提示词精简到上下文再规划先说 token 压缩。这块我目前实践下来最有效的有四条路按性价比排序大概是上下文结构优化、输出约束、摘要替代、模型间的分级调度。上下文结构优化指的是把大段自然语言 prompt 变成结构化内容。比如给模型传业务数据的时候与其写“下面是一条订单记录请你提取其中的金额和收货地址”不如直接用一个 JSON 片段把关键字段摆好。模型不需要解码冗余表达理解更快也更稳定。我实际测过这种改写能稳定削减 15% 到 30% 的 token。输出约束方面我一般会用三种办法设置最大输出长度、强制 JSON 格式、用 logit 级别的白名单限制某些字段。最狠的是第三种它能直接从词汇表里屏蔽掉无意义的填词。在商品标题生成这个场景里我把输出长度限制在了 40 个 token并约束结尾必须是标点符号效果比之前自由输出还要好。至少不会再出现一篇 800 字但核心卖点被淹没的问题。摘要替代这个思路则是针对多轮对话类应用。当会话历史超过 N 轮时我会先让模型把前面的对话浓缩成一个结构化摘要。比如“用户已提供邮箱当前处于价格咨询阶段偏好是性价比优先”这样比把每一轮原文都放进去省太多 token而且模型的上下文更聚焦。需要注意的是摘要一定要简洁否则摘要本身又会吃掉大量 token我通常会限制在 100 token 以内。最后是模型分级调度。这是一个被忽略的省钱点。不是所有请求都需要调用最强的旗舰模型。比如意图分类、实体抽取、关键词提取这类基础任务我实测用轻量模型就够用只有到了方案生成、代码编写、复杂推理才动用到旗舰级模型。这样组合下来成本曲线能平滑不少。不过也要注意“分级”不代表“降级”你需要建立每个任务的准确率基线至少保证降级后不差于原方案的 10%。2.2 模型升级对齐清单一份可以直接复用的回归流程新模型上线光有测试集还不够需要把对齐流程固化成一套可以反复执行的清单。我自己的标准做法大概分五步。第一步先确认输入输出的契约没有变化。也就是旧模型能接受的 prompt 格式、输出格式、枚举值在新模型上是否同样适用。很多模型升级后会在输出格式上“更灵活”灵活在这类场景里就是麻烦。第二步跑一遍核心用例集。用例不应该只是正确的输入还要包含易错输入、对抗样本和罕见写法。我通常准备 200-500 条不等按业务场景比例分配。第三步对比输出差异。这里不只看“对不对”还要看“风格是否一致”。像我前面提到的 Markdown 污染问题就是风格变化造成的事故。所以对比时我会用脚本自动检查输出内容里是否混入了不符合 schema 的额外字符另外人工抽取 5% 的样本做更细的观感比对。第四步压测 token 消耗与响应时间。把一批真实请求日志回放到新模型上看平均输入输出 token 有没有异常膨胀。如果涨了 20% 以上就需要考虑加提示词约束或切换压缩策略。第五步灰度发布与线上回流。我只放 5% 流量到新模型同时持续记录线上输出和用户反馈至少观察 24 小时再决定是否继续扩大。很多时候离线评测全过线上还是会出幺蛾子这一道回流是必须的。2.3 agent 可观测性的三个关键抓手日志轨迹、工具权限、目标护栏agent 难管核心问题其实就一个你不知道它下一步要干什么。我在实践中慢慢总结出要管住 agent得从三个地方同时入手。实时日志骨架。这个骨架不是简单记一句“agent 调用了工具 A”而是要记录完整的决策轨迹包括当前任务目标、上一步的输出、模型推理摘要、候选动作列表、选择了哪个动作、动作参数是什么、工具返回了什么、下一步打算怎么调整。只有这些信息齐全了你才能在一个 agent 跑偏时快速回放它到底是在哪一步判断失误。我现在都是把每一步结构化成事件流存到日志系统里支持按任务 ID 聚合查询。排查问题时效率提升不止一倍。工具权限边界。我见过太多 agent 项目工具列表里挂着十几个 API每个 API 都有修改和删除的权限这基本等于把系统的钥匙全交给了模型。我的做法是对每个工具做三级分类只读类、写操作类、危险操作类。只读类可以放开让 agent 自主调用写操作类需要二次确认危险操作类直接不提供给 agent。不要让 agent 有“想办法绕过确认”的动机直接在权限层就给它焊死。目标护栏。这个在实践中更容易被忽略。agent 的“任务目标”和“系统约束”两回事。你可以告诉 agent “帮用户把报销单填好”但系统还需要知道“不要调用付款接口”“不要读取无关文件”。这些约束要作为独立字段传给 agent而不是藏在自然语言描述里。我会在每次 agent 执行前先把它燃尽的目标和禁止事项列出来再让它开始干活。实测这个动作能少出很多幺蛾子。3. 实操过程与核心环节实现一个跨表查询 agent 的设计与迭代追坑记录理论讲太多还是要拿一个真实过程来演示。这周我正好把一个“跨表查询并生成汇总报告”的 agent 从设计推到上线这个过程里几乎踩遍了刚才提到的坑很适合拆开来讲。3.1 需求场景与初始方案设计为什么会用到 agent业务方给的需求很直接企业内部有多张业务表分散在不同库里业务人员希望在对话里直接提问比如“上个月华东区销售额排名前五的客户是谁他们的复购率怎么样”这种问题不是一条 SQL 能查出来的要跨库取数、做关联可能还要算额外指标。如果不用 agent你就只能针对每个固定的问题模式写专用接口这显然不现实问题组合几乎是无限的。所以我最终决定上 agent让模型先理解用户问题再把它拆分成多个查询步骤调用不同的数据查询工具最后汇总结果。方案听起来很顺但实际写代码时麻烦从第一个版本就开始了。3.2 第一版核心实现与工具集定义第一版我给 agent 准备了三个工具query_customer_table、query_order_table、query_product_table每个工具接收关键字参数返回一个 JSON 数组。agent 的核心循环是“推理-调用工具-观察结果-继续”循环最多执行 8 步。这里有个基础但重要的细节工具描述一定要写得让模型能“直白地理解”不要写含糊的说明。我最初写的一个工具描述是“查询客户表支持筛选条件”模型经常传错参数因为它不知道表里到底有哪些字段。后来我把每个工具描述改成“查询客户表返回客户 ID、客户名称、所在地区、首次购买时间支持传入地区名称进行精确匹配”模型的工具调用准确率立马上了一个台阶。再提一个容易忽略的事即便工具参数填错了agent 也不应该直接报错退出。你应该让工具返回一个“参数错误 正确的参数模板”让 agent 有机会自己修正。我在第一版里就直接抛异常结果 agent 经常卡死。3.3 实际运行观察从混乱到收敛的三轮优化第一次真实跑通时agent 完成了一个“跨表统计销售额”的任务。日志显示它先调用了客户表然后调用订单表最后自己做了加总。从结果上看功能是完成了但过程却有明显的冗余它其实重启了一次查询因为第一次没有过滤时间范围返回了全量数据。它后来补了时间条件但这多出来的那一整轮查询就白白消耗了时间和额外的 token。第二轮优化我把工具函数改成了支持必填参数校验。在模型传参缺失时工具会返回可读的错误信息并附上示例参数。同时我在 agent 的提示词里明确加了一句“优先使用最近一次查询结果不要重复做相同过滤条件的查询”。这之后重复调用明显减少。第三轮优化则来自一个更隐蔽的问题。某次任务里agent 得到了一个异常值年份字段是一个五位数。它竟然把那个异常值直接写进了汇总报告没有任何质疑。这给了我一个启发只靠模型自己很难对数据质量有判断必须在外部做校验。于是我在查询结果返回之前先做了一层简单的数据清洗过滤掉字段类型不匹配的脏数据。agent 的任务就回归到了“查询与汇总”本身而不是去处理数据质量。经过这三轮迭代模型的执行步骤从平均 7 步降到了 4 步左右token 消耗减少了约 45%而且任务成功率从 70% 提到了 95%。整个过程让我体会到agent 的能力上限固然取决于模型但下限完全靠工程兜底。3.4 如何评估这个 agent 的表现指标设定与行为观测很多人做 agent只看“最后任务成没成”。但在我看来这远远不够。除了任务成功率还要看几个过程指标平均调用工具次数、无效调用占比、token 消耗、单任务耗时。我给自己定了一套参考阈值单任务工具调用不超过 6 次无效调用重复查询、错误参数导致的重试不超过 1 次token 消耗波动控制在平均值的 30% 以内超过这些指标就要回头翻日志看是不是 promnight、工具描述或模型版本出了问题。这个做法让我这周发现了一个非常有意思的现象同一套 agent 配置换了一个更强的模型版本之后成功率虽然上升了但工具调用次数也变多了。新模型更喜欢“多验证一步”不少情况下它会在拿到正确答案后再次调工具确认一遍。这说明强模型未必等于成本最优它只是更谨慎。这种观察如果只盯着成功率是永远发现不了的。4. 常见问题与排查技巧实录多数人会在 agent 项目里被卡住的几个点这周跟同行交流时也听到了不少同款困惑。我整理一下大家集中遇到的问题和我的排查思路希望能帮看到的读者少走弯路。4.1 工具调用格式“偶尔失灵”但重试几百次又能成功这是最典型的一类 agent 问题表面看像是随机故障实际大多跟 prompt 模板一致性有关。排查方法很简单把失败样本的输入输出完整打印出来看模型在哪个步骤开始偏离了工具调用格式。常见的原因有三个一是系统提示词里给的工具示例太少或太少样二是模型被前几个工具返回的长文本带偏学到了错误的格式三是新模型版本对 JSON 输出的标签敏感度不一样。我一般会做的调整是在工具描述的末尾加上一个“调用示例”让模型照着学同时在输出解析层做一个容错解析器兼容“JSON 前面有一段解释”“字段顺序错乱”等常见偏离。容错解析能解决大约八成格式问题剩下两成要靠提示词调优。4.2 agent 总是“自作聪明”做出额外操作autonomy 是个好东西但过度自主会把你气死。最常见的行为是用户只问“销售额是多少”agent 却额外做了一个排序和排名甚至生成了一张趋势图。我解决这个问题的方式是对 agent 的行为空间做显式限制。在工具调用层之外加一个“只做用户明确请求的动作”的指令。如果你用的是结构化工具你还可以给每个工具赋予“只读”或“执行”标签在调度层直接过滤掉不该在某个场景触发的工具。简单说你越是在架构上限制它它就越安稳你越是依赖模型自我约束就越容易收到惊吓。4.3 token 突然暴涨但业务逻辑没有任何改动这种情况通常不是你的代码变了而是模型服务商侧在升级。有一次我们的 token 用量一夜之间涨了 35%排查时发现代码完全没变后来去对照模型版本 hash发现服务商已经在后台悄悄升级了对应版本模型输出变长了。对策有两个一是利用 API 返回的模型版本字段在日志里记录每次请求的模型标识二是设定一个每日 token 用量基线一旦偏差超过 20%自动告警。有了告警你才能第一时间知道是外部变化还是内部 bug而不是等月底账单吓一跳。4.4 agent 系统上线后下游开始频繁报错原因却不在 agent这是最隐蔽的一个坑。agent 调用工具返回数据后它会把处理好的数据直接交给下游系统。如果它返回的数据格式和下游预期不完全一致下游就会报错。比如 agent 在字段缺失时选择传一个 null而不是按约定传一个空字符串或者它把整数字段变成了浮点数。这些差异在单个请求里看不出来但下游系统往往对这些格式非常敏感。我的整改方式是在 agent 与下游系统之间加一个输出协议校验层。所有从 agent 出去的数据都需要经过一组 schema 校验如果发现字段缺失或类型不符就自动补默认值或者要求 agent 重新生成。协议校验层看起来额外多了一道工序但它能兜底住 agent 的随机性让下游系统不会变成“受害者”。5. 收获、反思与下一步准备做的事这一周的工程实践让我对 AI 应用的理解发生了一些变化。过去我可能更多把精力放在“如何把模型训得更强”“如何把提示词写得更妙”上但现在我会花同样多的时间去思考怎么让系统在模型本身不够稳定的情况下依然能稳定运行。这其实是一种工程思维的转换。你不再把模型当成一个可靠的函数而是把它当成一个能力很强但需要监督的协作者。协作者偶尔会出错、会多想一步、会误传参数。我们做系统的责任就是尽可能把它的自由度限制在可控的范围内然后在这个范围内充分发挥它的能力。接下来我打算做几件事一是继续完善 agent 的日志回放能力争取做到“一步操作一个回放点”让任何一次任务都能像视频一样逐帧还原二是在工具权限层加入更细粒度的动态授权让 agent 在执行业务中临时申请权限而不是默认拥有全部权限三是探索更省 token 的多步推理压缩方法——很多 agent 任务会在中间过程中反复揶揄同一类信息里面应该有更大的优化空间。最后再给你一个小技巧也是我这周最受用的一条经验当你在调试 agent 时别只盯着最终结果要学会“观察过程”。把每一步的工具调用、模型推理、预期的候选动作都打开你才能真正看清它是在按你希望的方式思考还是在走一条你以为它不会走的弯路。很多时候问题的答案就藏在过程里而不是结果里。