news 2026/10/6 11:07:48

从Agent历史日志到Skill:提示词优化的工程化编译路径

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
从Agent历史日志到Skill:提示词优化的工程化编译路径

上周我还在为一个 Agent 的提示词折腾了大半天,改了七八版 prompt,结果换个输入场景立刻失灵。我相信不少做 Agent 开发的人都有这种体验——提示词优化这件事,本质上还停留在“手工艺”阶段,靠的是个人经验和试错。直到我看到微软那篇关于把 Agent 历史日志直接“编译”成下一版 Skill 的论文思路,突然有种豁然开朗的感觉:与其一遍遍人工打磨提示词,不如让 Agent 自己的执行轨迹成为优化的数据源,把日志当成“源码”,把 Skill 当成“编译产物”。这个思路我从最基本的原理到实际落地都完整走了一遍,今天把整个过程掰开揉碎讲清楚。

1. 为什么要把历史日志“编译”成 Skill

1.1 Agent 提示词优化的两个死胡同

先说说传统提示词优化为什么难。市面上主流的做法无非两种:第一种是人工调优,跑几个测试样本,看到输出不对就改几句描述,再加几个示例,循环往复。问题在于你永远不知道改动哪句话产生了影响,也不知道这套 prompt 换一批数据会不会失效。第二种是自动调优,用 LLM 批量生成候选 prompt,再用评测集打分筛选。这种方式比人工强,但它优化的是“说辞”,不是“行为”——Agent 在真实环境中是分多步行动的,中间有工具调用、有环境反馈、有分支决策,单轮 prompt 打分根本覆盖不了这些复杂情况。

更深层的问题在于,这两条路都没有真正利用 Agent 运行过程中产生的执行轨迹(trajectory)。日志里其实藏着大量信息:哪一步决策导致了成功、哪一步操作引发了报错、用户实际接受了什么样的输出格式、Agent 在什么条件下会绕弯路。这些信息比任何人工总结都更接近“真实经验”,却被大多数优化方案忽略了。

1.2 “编译”思维的引入

微软论文里最核心的观点,是把 Agent 的历史日志看作一份等待加工的“源码”。传统编程里,源码经过编译器的词法分析、语法分析、语义分析,最终生成可执行的产物。这里继承了同一个思路:历史日志经过清洗、解析、模式提取、结构化拼装,最后产出一份下一版可复用的 Skill 定义。所谓 Skill,就是一段结构化的指令包,包含触发条件、执行步骤、示例、边界约束,能在后续任务中被 Agent 直接装载和执行。

这个类比的价值在于,它把提示词优化从“修改一句自然语言”提升到了“构建一个可版本化、可测试、可回归的工程产物”的层面。Skill 不是一段 prompt,而是有字段、有校验逻辑、有版本记录的完整组件。用一个不恰当的比喻,手工调 prompt 就像在原石上反复打磨,而“编译”日志是在建立一条从矿脉到成品的流水线。

1.3 什么样的场景最需要它

不是所有 Agent 都需要这套流程。我的判断是,运行轨迹长(超过 10 步)、交互频率高、失败成本大的场景最值得投入,比如自动化客服工单处理、多工具调用的数据分析 Agent、自动写代码并执行测试的编程助手。这些场景有两个共同特征:日志量大,人工分析不过来;行为模式相对稳定,提炼出来的 Skill 有复用价值。反过来,如果 Agent 只是回答简单问答,日志就一句话,那还真没必要整这套编译流程。

2. 从日志到 Skill 的核心链路拆解

2.1 日志采集与清洗:记录什么决定了产出什么

整个流程的第一环也是最重要的一环,是日志本身的质量。我在实际操作中把日志分成三种类型,分别处理:

  • 环境日志:系统自动生成的运行记录,包括时间戳、模型调用耗时、token 消耗、异常堆栈。这类日志主要用来做性能分析,对 Skill 提炼的价值不大,早期可以直接过滤掉。
  • 决策轨迹日志:Agent 每一步的思考过程、选择的动作、工具调用的入参和出参、环境反馈。这是“编译”的主料,必须完整保留。
  • 结果反馈日志:任务是否成功、用户是否满意、最终输出的内容和格式。这类日志是提炼成败经验的对照依据。

采集的时候有个容易踩的坑:很多人习惯把全部日志塞进一个 JSON 文件里,既不分层也不带标识。我在项目里统一用的方案是给每步决策加上step_id、parent_step_id、intent、action、result字段,这样后续解析时才能还原出完整的决策树。如果原始日志没有这些结构化字段,就得先跑一遍解析脚本做转换。

清洗环节另一个重要任务是去噪。实际日志里充斥着大量“鸡肋”内容:重试机制造成的重复调用、模型自我纠正时产生的中间修正话术、与业务无关的系统提示词回显。我的经验是保留前两次重试记录就够了,超过两次的重试可以直接折叠成一条“多次重试后成功/失败”的摘要,既能保留失败模式,又不会让提炼过程被噪声淹没。

2.2 经验提取:从轨迹中找模式

日志清洗完之后,进入最核心的提炼环节。这里要解决的关键问题是:如何在几十上百条轨迹里找到稳定复现的“成功模式”和“失败模式”。

我实践下来最实用的方法,是对齐轨迹做“diff”。以客服工单处理为例,A 会话中 Agent 先查了用户历史订单、再查退换货政策、最后生成了退货链接,一气呵成;B 会话中 Agent 直接生成了退货链接,结果因为没核对订单状态导致失败。把两条轨迹对齐之后你会发现,关键差异在“查询订单状态”这一步。那么要提炼进 Skill 的规则就是:任何退货处理流程前,必须先调用订单状态查询接口。这种模式靠人工阅读日志也不是找不到,但当轨迹数量达到几百上千条时,人工根本看不过来,必须依赖自动化方式做 pattern 匹配。

具体实现上,我用的方案是先把轨迹转成动作序列(action sequence),比如[查订单 -> 查政策 -> 生成链接],然后用序列模式挖掘算法找出高频子序列。这里不一定要上多复杂的算法,简单的 n-gram 统计加置信度过滤就能解决大部分问题。核心参数是支持度(出现在多少条成功轨迹中)和置信度(出现在成功轨迹中的比例),我的经验阈值是支持度不低于 20%,置信度不低于 80%,低于这两个值基本可以判定为偶发行为。

2.3 边界条件识别:Skill 最容易被忽视的部分

很多人提炼 Skill 时只关注“该怎么做”,却忽视了“什么时候不适用、什么时候要停下”。我看过太多提炼失败的案例,问题恰恰出在边界条件缺失。

边界条件包含几类:前置条件(执行前必须满足什么状态)、终止条件(什么时候停止重试)、降级路径(主流程失败时怎么做)、限制项(哪些情况不处理)。这些信息在日志里是隐含的——成功轨迹里“为什么成功”可能看不出边界,但失败轨迹里“为什么失败”往往是边界最好的注解。比如某个 Agent 在用户 IP 归属地为海外时频繁调用国内支付接口失败,这就是一条典型的边界条件:地域属于海外时,跳过支付环节并提示用户使用国际支付。

提取边界条件时,我习惯把失败轨迹单独拎出来做根因分析。核心方法是二分定位:先找到第一个出现异常动作的 step,然后向前看是什么样的输入条件触发了这个动作,再向后看异常如何传导。定位到输入条件后,把它泛化——比如具体的一次“IP 是 212.64.x.x”可以泛化成“IP 归属地为非大陆地区”,这样 Skill 的边界才有普适性。

2.4 Skill 结构化输出:字段设计决定可用性

提炼到的经验最终要组装成结构化的 Skill 定义。我在实际项目里用的格式是 YAML,结构如下:

name: order_return_handler description: 处理用户退货退款请求的统一流程 version: 2.3.0 trigger: intent: ["退货", "退款", "return", "refund"] slot_required: ["order_id"] preconditions: - verify_order_owner_before_return - check_return_window steps: - action: query_order_status params: need_fields: ["status", "pay_amount", "delivery_time"] - action: check_return_policy params: sku_source: "product_service_db" - action: generate_return_link on_failure: fallback_manual_service boundaries: - if: order.status in ["closed", "refunding"] then: reject_with_reason - if: user.region not in ["CN"] then: skip_online_payment_flow examples: - input: "我要退货" trace: ["query_order_status", "check_return_policy", "generate_return_link"] result: success - input: "订单没收到,申请退款" trace: ["query_order_status", "check_logistics", "manual_review"] result: success_with_human_handoff validation: success_rate_threshold: 0.85 max_steps: 6

这个设计里的几个字段我特别说明一下。trigger决定 Skill 什么时候被激活,steps是执行主体,但我最想强调的是boundaries和validation。前者能避免 Agent 在不适用的场景里硬套 Skill,后者用来做回归测试的量化标准。没有这两个字段的 Skill,本质上还是“增强版 prompt”,离工程化还差得远。

2.5 质量校验与回归测试

Skill 生成之后不能直接上线,必须跑一轮校验。我的标准流程是两层校验:第一层用历史日志回放,把 Skill 装载进 Agent 后重新跑一遍已标注成功/失败的轨迹,看成功率是否达标;第二层是影子测试,让新旧两版 Skill 并行跑线上真实请求(新版本输出只记录不生效),对比两者的成功率、步骤耗时、用户反馈。

这两层校验缺一不可。历史回放只能证明 Skill “记住了旧经验”,影子测试才能验证它在真实分布上的表现。我遇到过最典型的情况是:新 Skill 在历史轨迹回放中表现极好,但在影子测试中引入新行为导致在线率明显下跌,原因就是新 Skill 强化了某些偏向动作,碰上了训练分布中没有的新输入。

3. 实操过程:从一份历史日志到新版 Skill

3.1 数据准备与轨迹对齐

我先说一个具体案例。我这边有个自动生成周报的 Agent,它的任务是从项目管理系统拉取任务状态、关联 Git 提交记录、汇总成周报并发送到钉钉群。这个 Agent 跑了三个月,积累了大概 2000 多条执行日志,但成功率一直不稳,特别是遇到跨周任务、未提交代码的任务时经常出岔子。

第一步做数据准备。我先写脚本把日志按session_id分组,每个 session 还原成一条完整轨迹,并按任务是否成功打上标签。统计下来成功轨迹约 70%,失败轨迹 30%。接着做轨迹对齐,按意图分类后,把相同意图的轨迹放在一起:我按“发送周报”“查询进度”“处理异常任务”三个意图做了分组,每个组内部再做文本相似度聚类。

比较麻烦的是处理轨迹长度差异。有的 session 只有 3 步就完成了,有的绕了 15 步还没结束。我的处理方式是截断对齐:只保留从第一个业务动作到最后一个业务动作之间的步骤,去掉前后多余的检索动作。截断后大部分轨迹落在了 5-8 步的区间,模式提取就方便多了。

3.2 用 LLM 辅助提炼时的 Prompt 模板

在模式挖掘的基础上,我会用 LLM 做一轮辅助提炼,重点是把机器发现的高频模式转写成自然语言的执行原则。下面是我用的一套 Prompt 模板,配合历史日志片段使用:

以下是一组 Agent 执行日志,包含成功和失败案例。 <logs> {轨迹序列} </logs> 请完成以下任务: 1. 总结成功案例中的关键步骤,要求步骤顺序明确。 2. 找出失败案例的共同原因,判断属于哪类错误:信息缺失、步骤遗漏、条件误判还是工具调用失败。 3. 提炼适用于所有场景的执行规则,要求每条规则具备可操作性(包含动作、参数条件、判断标准)。 4. 明确指出不适用该流程的边界情况。 5. 输出 JSON 格式,包含 rules、edge_cases、common_pitfalls 三个字段。

这套模板的核心是强制 LLM 输出结构化字段,避免它写一堆“需要仔细分析”“要注意各种情况”的空话。我加了温度设为 0.2 的生成参数,保证多次生成结果稳定。需要提示的是,这一步的 LLM 并不是在做创造性的工作,而是做“转译”——把已有模式变成自然语言规则,所以不需要给它太多自由发挥的空间。

如果完全没有现成的日志挖掘算法,也可以直接让 LLM 批量阅读全部日志然后输出规则,但那样既费 token 又容易忽略低频但关键的边界条件。我建议至少做一次简单的频率统计,把高频动作序列作为先验信息喂给 LLM,效果会明显好过让它从零阅读。

3.3 生成 Skill 并进行两轮验证

规则提炼完之后,我按照上文提到的 YAML 结构生成 Skill 初版。这里有一个细节:初版 Skill 的steps不要写得太满,给 Agent 留一点自主决策的空间。我在初版里只写清了必做动作、必查字段和顺序依赖,具体如何查询、如何拼接输出结构留给模型自行发挥。

第一轮历史回放的结果让我挺意外:新 Skill 在训练集上的成功率达到 92%,比旧版的 70% 提升了二十分钟——这说明日志中确实存在稳定的“经验模式”,只是之前没有以结构化方式固化下来。但进一步看明细,我发现它在“跨周任务”这个场景的表现不佳。回放日志发现,跨周任务的提交记录分散在两个迭代周期里,新 Skill 的“先查任务再查提交”的步骤顺序,会导致查询结果不完整。

于是我在第二轮迭代中增加了一条规则:当任务周期跨周时,需要合并两个周期的提交记录再去重。改进后,跨周场景成功率从 61% 上升到 84%。这个案例也印证了一个原则——Skill 的编译不是一次性工作,而是一个持续迭代机制。

3.4 将 Skill 挂载回 Agent 框架

验证通过的 Skill 要真正发挥作用,还得能挂载进 Agent 框架的执行链路。这里不同框架的实现方式有差异,我自己的做法是维护一个 Skill 注册表,按name+version存储,Agent 启动时加载全部可用 Skill 的描述索引,然后在每轮决策时按trigger做匹配,匹配命中后载入对应 Skill 的完整指令。

值得一提的是,Skill 描述索引的设计对触发准确率影响很大。trigger字段里不仅要有意图关键词,最好还要带上槽位约束,比如“当用户意图是退货且已提供订单号时触发”。我见过很多 Skill 触发不准的问题,根因是 trigger 写得过于宽泛——只要听到“退”字就激活,结果在用户问“退货运费谁出”时也触发了退货流程。这种情况下,加一个slot_required检查就能过滤掉大量误触发。

4. 落地过程中的常见坑与排查实录

4.1 日志噪声过滤:不是所有日志都值得“编译”

第一个高频问题是日志台账混乱。常见的日志记录方式是在每个工具调用前后分别打印一条日志,比如“开始调用查询接口”“查询接口返回成功”,但这两条日志并不是同一个数据结构,有的还夹杂着 Debug 输出,直接作为编译输入会导致提炼出的规则全是噪声。

我的解决办法是在日志入口做统一拦截,把每个交互轮次的结构规范化。对每一条决策轨迹,都要保证能回答三个问题:看到了什么、决定做什么、做完之后结果如何。任何不能回答这三个问题的日志条目,在预处理阶段就会被丢弃。这个规则虽然简单,但真的能过滤掉一半以上无效日志。

4.2 过拟合:Skill 记住了太多“长相”

第二个坑是过拟合。曾经遇到过一个提炼得非常详细的 Skill,几乎每个细微分支都有对应规则,看起来无比专业,但实际上线后效果反而变差。原因在于它过度拟合了训练日志中的偶发特征——比如某条日志里用户习惯用“麻烦帮我”开头,Skill 就把这个句式写成了触发条件,导致真正遇到从句式但表达方式不同的请求时直接不触发。

解决过拟合最有效的办法是给提炼过程加“复杂度预算”。我在最终配置里限制了一条规则最多包含一个条件分支,一组 Skill 的规则总数控制在 10 条以内,超过预算就必须合并或者丢弃低频规则。虽然看着粗暴,但效果稳定。

4.3 回归测试缺失:Skill 迭代翻车现场

第三个坑是迭代时不做回归。有一次我优化了一个客服 Agent 的 Skill,针对性提升了订单查询的成功率,结果上线后发现整体流程成功率不升反降。复盘时发现,新 Skill 强化了“先查订单”的步骤,但有一部分用户的诉求其实不涉及订单,比如改发票、查物流,它们也被“查订单”拦截住了。

这件事之后我把回归测试定为强制环节。每次 Skill 更新必须跑三组测试集:针对性测试集(验证新功能的修复)、历史回归集(验证旧场景没坏)、边界情况集(验证边界条件确实生效)。其中历史回归集是最容易漏掉的,但恰恰是它能拦住大部分的迭代翻车。

4.4 一个比较隐蔽的问题:日志中的人类反馈信号

有时候 Agent 其实已经成功生成了输出,但用户不满意,中途打断了 Agent 的流程,这在日志里是一个“任务取消”的标记。如果把这种轨迹直接标记为失败,会误导提炼——Agent 本身的行为没有问题,问题在需求理解阶段。

我的处理方式是在日志标注上引入“用户中断原因分类”:如果中断发生在 Agent 生成最终结果之前,标记为需求误解;如果发生在生成之后,标记为输出不满足。两类问题在提炼时需要完全不同的处理方式——前者要优化trigger和preconditions,后者要优化examples和输出格式约束。如果不区分就直接丢进提炼器,得到的 Skill 往往两头不讨好。

5. 结合现有框架的一些落地建议

5.1 借助现有 Agent 框架的 Skill 体系

如果你用的 Agent 框架本身支持 Skill 概念,那这套“日志编译”思路可以直接嫁接进去。现在很多主流 Agent 框架都内置了技能注册和动态装载能力,核心差别主要在 Skill 的字段结构和触发机制上。我建议你在实践前先摸清框架的加载逻辑:有些框架按关键词匹配触发,有些框架把 Skill 描述塞进上下文交给模型判断。前者需要你把trigger字段写得更“死”,后者需要你让trigger描述更充分。

我的经验是,无论框架提供什么字段,你都要保证提炼出的 Skill 具备三个要素:明确的触发条件、带顺序的执行步骤、可判断的边界条件。框架字段可以映射,但这三个要素缺一个,Skill 的复用价值都会大打折扣。

5.2 给 Skill 加版本管理与上线审批

既然把它当工程产物管理,版本管理必须跟上。我用的方案是给每条 Skill 加语义化版本号,记录它的来源日志范围、提炼时间和校验结果。每次新版本上线前,必须经过一个简单的“同行评审”——本质上就是找另一个工程师看一遍 Skill 里的规则和边界,重点检查有没有含糊不清的描述或者过度泛化的条件。

这一步看起来增加负担,实际上能减少返工。LLM 提炼出的规则经常带有“幻觉”,比如凭空写出一条“用户情绪激动时应该先安抚再处理”这种无法程序化实现的伪规则。人工评审存在的价值,就是把这种伪规则拦截下来。

5.3 与现有评测体系打通

技能优化和评测体系应该形成一个闭环。我在实践里加了一个自动化统计:每个 Skill 在被触发后,实时记录成功率和平均执行步数,并回流成日志。下轮“编译”时,优先使用成功率低于阈值的 Skill 关联日志作为输入,形成了一个“发现薄弱点-针对性提炼-上线验证-继续采集日志”的循环。这样做的好处是,编译的输入永远来自当前最需要优化的场景,而不是随机抽样所有历史日志。

这个思路对应了标题里“下一版”这个词的核心含义——不是一次性把日志变成 Skill 就结束了,而是每个版本都是一次增量编译。旧的 Skill 可能被推翻,新规则可能被加入,整个过程是持续演进的。

在我自己把这条流程完整跑通之前,确实觉得“日志编译成 Skill”这个概念有点玄,更像一个学术愿景。但现在我倾向认为,它在实际操作层面是完全可以落地的。核心不在于自动化程度有多高,而在于把提示词优化从一个经验驱动的模糊过程,变成一个数据驱动的工程流程。当你面对几百条执行日志,全部读一遍会崩溃,完全靠人工提炼又不可复制,这时的唯一出路就是把日志变成规则,把规则变成可验证的 Skill,再让 Skill 去指导下一轮执行——这个闭环一旦跑通,Agent 的迭代速度就不是手工调 prompt 能比的。后续我还在尝试把多步决策的中间状态(比如 Agent 的中间思考摘要)也纳入日志采集范围,让“编译”的源材料更丰富,这是目前我认为最有潜力的扩展方向。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/6 11:07:23

基于PyTorch与BioBERT的电子病历实体关系抽取实战

简介&#xff1a;这份PDF面向医疗NLP方向的学习者与开发者&#xff0c;聚焦电子病历实体关系抽取这一具体任务&#xff0c;讲解如何借助PyTorch框架与BioBERT预训练模型完成迁移学习落地。内容从电子病历分析价值、实体关系抽取任务定义切入&#xff0c;梳理传统规则与机器学习…

作者头像 李华
网站建设 2026/10/6 11:06:57

Winform DataGridView 图片显示优化:从卡顿到流畅的实战指南

简介&#xff1a;本资源面向使用 Winform 进行桌面应用开发的 .NET 程序员&#xff0c;聚焦 DataGridView 控件中图片列的显示问题。内容围绕 DataGridViewImageColumn 的创建、CellFormatting 事件的动态加载逻辑以及 GetImage 方法读取本地图片路径展开&#xff0c;并说明 Im…

作者头像 李华
网站建设 2026/10/6 11:06:50

Winform DataGridView图片列实战:路径绑定、CellFormatting与性能优化

简介&#xff1a;这份PDF资料面向使用Winform进行桌面开发的.NET程序员&#xff0c;聚焦DataGridView控件中图片列的显示问题。内容围绕DataGridViewImageColumn的创建、CellFormatting事件的动态加载逻辑以及GetImage方法读取文件流展开&#xff0c;并说明ImageLayout属性对图…

作者头像 李华
网站建设 2026/10/6 11:04:43

金融智能体实战:小模型可审计链路如何超越千亿级系统?

1. 这个项目到底在解决什么问题1.1 为什么金融场景对大模型的要求不一样前两个月我把一套代号 Mint-Agent 的金融智能体跑通了&#xff0c;核心是用 9B 和 27B 的小参数模型&#xff0c;去完成行研公告解读、财报指标抽取、对账推理和监管口径校验这类任务。一开始团队内部是有…

作者头像 李华
网站建设 2026/10/6 11:04:01

AI Agent生产落地:可靠性优先的工程实践指南

1. 这不是“调用一个API”&#xff0c;而是重新设计人与工具的协作关系 最近三个月&#xff0c;我亲手落地了6个不同形态的AI Agent项目——从给本地咖啡馆做自动库存预警的轻量级调度器&#xff0c;到为某医疗器械公司搭建的跨系统临床文档协同体&#xff1b;从用Rust写的高吞…

作者头像 李华
网站建设 2026/10/6 11:03:35

数据库Java课程设计完整版:学生成绩管理系统源码与文档

简介&#xff1a;这份文档资料面向高校计算机相关专业学生与Java初学者&#xff0c;提供一份完整的学生成绩管理数据库课程设计报告&#xff0c;帮助读者理解从需求分析到系统落地的全过程。资源共1个doc文件&#xff0c;压缩包约269KB&#xff0c;内容涵盖课程设计目的与意义、…

作者头像 李华