
做Agent开发这两年我踩过最大的坑不是模型能力不够而是同一个错误反复犯、同一个经验反复教。项目日志倒是一天比一天厚但真正能沉淀下来的方法论其实少得可怜。最近看到微软那篇提示词优化的论文标题非常戳我把Agent的历史日志直接编译成下一版Skill。这个说法太妙了——日志是过程数据Skill是能力资产中间缺的正是编译器这个自动化工序。我花了两天时间把论文思路啃了一遍又拿自己手头的Agent项目试了试今天把这套想法掰开揉碎讲讲顺便聊聊我踩过的坑。1. 先聊清楚一个痛点Agent日志是最被低估的资产1.1 日志里的金子为什么一直没人挖先说说我最深的感受。现在做Agent项目几乎人人都在调prompt但调法普遍是手工作坊式的——跑几个case发现不对手动改指令措辞再跑再改。这个过程极其依赖个人经验而且每次调完只针对当前用例换个任务又得从头来。但你回头看Agent运行时的日志里面其实什么都有模型每一步的思考过程、工具调用参数、中途报错、重试策略、最终结果。以一次让Agent去读PDF并提炼要点的任务为例日志里会记录它怎么选择解析工具、怎么切分文档、怎么处理解析失败的兜底逻辑、最后怎么组织摘要。这些信息如果只用来debug那是大材小用——它们本质上是一份带结果的决策过程样本。问题在于日志是流水账不是知识。人要去读一大段几十步的轨迹再手动提炼成可复用的经验成本很高。尤其当任务类型一多、Agent一跑多轮日志体量会迅速膨胀到人工根本无法维护的程度。这也是为什么绝大多数团队的日志都躺在数据库里吃灰而调prompt的工作永远在靠少数几个懂行的人手工完成。1.2 论文的关键思想把日志当源代码来编译论文给了一个很漂亮的抽象如果把Agent每一次完整执行的历史日志比作源代码那么一个可复用的Skill就是这段源代码经过编译后生成的目标程序。传统编译是把人类可读的高级语言翻译成机器可执行的指令这里的编译是把LLM执行任务时留下的行为轨迹翻译成另一套LLM可以直接加载执行的提示词级指令。这个类比强在哪儿它把调prompt从一门手艺变成了一个流水线动作。你不需要再人工去总结这个任务应该分几步、每一步要注意什么而是让一个归纳模型也就是LLM自己去读足够多的日志样本自动抽出模式形成新的Skill。Skill可以直接再喂回Agent让下一轮任务跑得更好形成闭环。更关键的是编译这个词隐含了确定性和可重复性。源代码进了编译器输出是稳定的产物日志进了编译管线产出的Skill也应该是结构清晰、可版本化管理、可回滚的。这就跟传统手工写提示词那种玄学体验拉开了差距。1.3 和传统提示词优化有什么本质区别市面上常见的提示词优化手段大多是围绕单条prompt做文章调整措辞、补充few-shot示例、加一些约束规则本质是让这条指令变得更清晰。这套路有效但天花板很低——它优化的是一段话而不是一套能力。Skill的粒度要粗得多。一个Skill通常包含触发条件、适用范围、执行步骤、工具选择建议、注意事项、示例轨迹。它更像一份操作手册而不是一句嘱咐。论文把优化对象从prompt文本提升到Skill资产意味着优化的结果是可以复用的能力是会累加的。我跑过一次之后体感很明显用传统方式调prompt调完两个星期不用跟新的一样但编译出一个Skill它是能进仓库、能版本化、能让团队其他人直接消费的。这个区别决定了这套方法论的定位不是给随便调调玩的个人玩具而是给那些Agent任务类型稳定、日志积累充足、需要持续提升执行表现的工程化场景准备的。2. 拆解编译这个动作从原始轨迹到可复用Skill的完整管线2.1 输入侧什么样的日志才够格进源文件编译的第一步不是写编译器而是准备源文件。日志也不是拿来就能用的得先筛选。我理解论文里应该隐含了这么几层处理逻辑。第一按成功与失败分流。只有成功完成任务或者质量达标的轨迹才值得作为编译输入失败的轨迹是反面教材倒也可以单独用来提炼规避指南但绝不能和成功轨迹混在一起否则编译出来的Skill会精神分裂——既教你怎么做又教你怎么避坑模型会无所适从。第二按任务类型聚类。日志要按意图/目标维度做粗粒度分组。比如解析文档和调用API查天气就是两类任务强行混在一起编译什么都提炼不出来。聚类可以用embedding加相似度计算也可以直接用日志里的任务描述字段做关键词分桶工程上后者更稳。第三做轨迹采样与降噪。同一类任务可能跑了上千条日志不可能全塞进编译器。要抽样出有代表性的样本覆盖不同输入形态、不同工具组合、不同成功路径。每条轨迹本身也要做截取和清洗去掉那些无意义的重试循环、Agent来回摇摆的无效思考保留关键决策节点。注意日志采集时如果发现字段不齐宁可靠运行时补录也别在编译阶段硬凑。脏日志编译出的Skill比没有Skill更坑——它会用看起来很合理的步骤把Agent带偏。这里有个细节值得提醒日志质量直接决定Skill质量就像编译器不检查源代码逻辑是否正确一样源文件里有问题编译产物一定有问题。所以日志采集侧如果还没有结构化记录比如只留了原始文本得先补上记录层。我自己的做法是让Agent运行时统一输出JSONL每条记录包含role、content、tool_calls、observation、timestamp这样后续编译才有的可操作。2.2 编译核心让LLM做归纳工程师论文的编译器本质上是一段高度结构化的提示词流程它驱动一个或多个LLM调用完成从轨迹到Skill的翻译。我按自己的理解把这个编译器拆成三个环节。第一个环节是轨迹抽象。给LLM一批同一任务类型的成功日志要求它忽略具体输入里的偶发细节抽象出这类任务的通用执行骨架。这个环节的关键指令是归纳出从目标到完成的步骤顺序而不是复述某条日志的过程。比如面对五条不同的分析用户评论情感日志编译器应该提炼出加载数据→清洗文本→分段→逐段判断→汇总结论这样的骨架而不是记录某次用了哪个具体API。第二个环节是模式提炼。针对骨架里的每一步询问LLM这一步有哪些常见的执行模式出现过哪些坑用什么工具或提示词效果更好论文的思路类似在做行为层面的静态分析——不只看结果更看过程中的共性选择。比如它可能发现处理PDF解析失败时多数成功轨迹会切换为图片OCR再兜底文本提取这一条就能直接变成新Skill里的异常处理规则。第三个环节是结构化输出。让LLM按预定义schema生成Skill而不是自由散漫地写一段心得。schema一般包含name技能名、description何时用、trigger触发条件、workflow步骤序列、prompt_template每步的提示词模板、constraints约束与禁忌、few_shot一到两条精炼示例轨迹。这个环节最重要的是约束输出格式我一般要求JSON或YAML这样后续能直接落盘、校验、版本化。一个容易被忽略的细节编译器本身的prompt设计要区分归纳任务和生成任务。用LLM做归纳时给它看的是样本集问的是共性是什么做生成时给它的是骨架和模式问的是请产出一份完善的Skill文档。两件事混在一个prompt里输出质量会明显下降。这个坑我踩过后面细说。2.3 输出侧Skill应该长什么样、怎么挂回Agent编译产物是一份结构化的Skill文件。按业界现在流行的做法Skill通常是Markdown或YAML文件放在一个特定目录里Agent启动或遇到触发条件时按需加载。说句题外话最近Codex Skill、Cursor Skill这类方案在开发者圈子火起来本质都是同一件事把可复用的提示词经验封装成带元数据的文件让AI工具在合适的场景自动调用。book to skill这类社区项目也很多大家已经意识到把静态文档变成可执行技能是Agent落地的重要一步。微软这篇论文的意义在于它给出了Skill的自动化生产路径——不是人写文档再转成Skill而是从行为日志里直接长出来。Skill挂回Agent的方式取决于你的框架。最简单的是把编译出的workflow和prompt_template直接拼进System Prompt让模型自带技能进阶做法是参考Agent Skill机制做成外部文件按需加载甚至和工具注册表关联让Skill决定调用哪些工具。我目前的项目用的是后一种Skill文件里声明了所需工具ID加载器解析出来之后统一注册进工具列表这样Agent在对应场景下就会优先按Skill的路径走。版本化这一点很重要。Skill文件一旦生成就要进Git管理每次编译的结果都留痕。我试过直接覆盖旧文件结果新Skill在某些case上变差了想回退都找不到上一个版本只能凭记忆重写血泪教训。3. 这套思路放在真实Agent工程里能落地成什么样子3.1 从手动写Skill到半自动沉淀Skill如果论文的方案真能稳定跑起来Agent工程的工作方式会发生一个很有趣的转变从人教模型怎么做变成模型自己总结自己怎么做人来审。这不是说人的工作没了而是人的工作重心上移了。原来团队里最值钱的是那个会写prompt的老哥他凭直觉和经验维护着几十条提示词现在这个角色变成了Skill架构师——负责定义编译器的归纳口径、审核编译产出的Skill、决定哪些Skill入库哪些该淘汰。这个转变对中小团队极其友好因为不必请顶级prompt工程师也能让Agent能力持续增长。我在自己项目里做了一个粗糙版每天凌晨把前一天的Agent日志跑一遍编译job产出的Skill草案推到PR上我花十分钟review合进去之后第二天Agent就跑新技能。跑了两周感觉最大的变化是返工率明显下降——以前同样类型的任务偶尔会换个方式出错现在基本都沿着成熟路径走。当然这个效果不是纯论文思路的功劳因为我的编译prompt自己写的还很粗糙但方向确实是对的。3.2 日志编译和Agent框架、编排层怎么配合这里正好说一下Agent框架和编排的概念。很多朋友分不清Harness和Agent以及编排的关系我尽量用大白话讲Agent是那个做决策的大脑Harness是它跑起来所需要的运行时环境工具注册、上下文管理、循环控制编排则是决定多个Agent或一个Agent多个任务之间怎么衔接调度的外层逻辑。日志编译成Skill这件事位置非常明确它不在Agent内部跑而是跑在Agent之上、Harness之外的一层观测与反馈体系里。Agent在Harness里运行产生日志日志被采集和清洗编译管线把日志变成SkillSkill再通过编排层或配置系统注入回Harness让Agent下一轮任务用上。这形成了一个运行→观测→沉淀→反哺的环路。这也就解释了为什么论文思路是工程友好的——它对现有架构侵入性极小。你不需要改动Agent的推理逻辑只要在日志侧加采集、在外部加编译服务、在配置侧加Skill注入。如果你用的是比较成熟的Agent框架多半已经提供了日志钩子和工具注册机制接入成本更低。3.3 什么时候该用、什么时候别硬上任何方案都有边界论文思路也不例外。我根据自己的经验分了两类场景。适合用的场景有三个特征任务重复度高、有明确的质量判断标准、日志积累量足够。典型例子客服意图分类、文档摘要、数据清洗、代码仓库issue分类。这类任务跑得勤失败模式可枚举日志数据的信噪比比较高编译出来的Skill容易验证。另一个合适的场景是团队经验传承——资深成员总结的优质轨迹即使量不大也可以人工精选后喂给编译器快速生成一份团队级Skill新成员直接复用。不适合的场景我也踩过如果任务是高度探索性的比如研究一个全新领域的调研提纲或者需求每周都在变Skill的保鲜期就很短。我试着对一群研究助理Agent做过日志编译结果编译出三个Skill两周后需求一变全是废的。而且探索性任务里成功轨迹本身就很难定义——输出是开放式的你不知道哪条算好哪条算坏编译器也就失去优化目标。另一个雷区是日志噪声大于信号的情况比如Agent经常在几个工具之间左右徘徊最终靠运气成功这种轨迹编译出的Skill会带有明显的偶然性不可靠。遇到这种情况先别急着编译而是先修Agent的决策稳定性等日志干净了再说。4. 实操笔记我照着这个思路搭建的一个最小验证方案4.1 一个极简日志编译器的实现框架下面是我实际跑过的一套极简流程不一定跟论文的实现相同但思路是一致的。这套流程不需要复杂框架一个Python脚本加上LLM API就能跑通。第一步采集。Agent运行时统一输出JSONL日志关键字段包括task_id、timestamp、step、role、content、tool_calls、observation、final_result。这里注意设计日志结构时就要想到以后要拿来编译所以思考过程也要完整保留不能只记工具调用。第二步筛选。过滤出final_result标记为success的记录再按任务类型分组。分组用任务描述字段做聚类我用的是简单的embedding加KMeans先跑出一堆簇每个簇人工打一个标签。虽然有点糙但足够支撑原型。第三步采样。每个簇随机抽5到10条轨迹对超长的轨迹做压缩把连续的无效思考折叠成摘要保留工具调用和关键决策。这里强烈建议用LLM做轨迹摘要别手写规则因为规则太死容易把关键信息误删。第四步编译。构造编译器prompt要求LLM输出YAML格式的Skill文件。我的编译器prompt大概长这样你是Agent行为编译器。下面输入的是同一任务类型的成功执行日志样本集。 请完成以下三件事 1. 抽象出完成该任务的通用步骤骨架 2. 针对每个步骤提炼常见的执行模式、易错点和工具偏好 3. 按要求的YAML schema输出一份完整的Skill文件。 schema字段name, description, trigger, workflow, prompt_template, constraints, few_shot_examples。 注意你的输出必须能直接被另一个LLM加载执行不要出现模糊表述。第五步落盘与回归。Skill以YAML文件存入skills目录并进Git。我要求每个Skill必须配一个5到10条的回归测试集真实历史任务合入前跑一遍确认不劣化。这套流程跑通之后我再额外把失败轨迹单独编译成avoidance规则文件合并进Skill的constraints字段。效果比我预想的好Agent在编译后确实更少踩之前的坑了。4.2 我踩过的四个坑与对应解法坑一失败日志混入编译样本Skill输出精神分裂。我第一次做的时候筛选条件写得太宽把一些部分成功的轨迹也放了进去结果编译出的Skill一会儿教模型大胆重试一会儿又教它及时止损行为矛盾。解法很直接严格定义成功拿不准的轨迹直接丢弃。宁可样本量少不要数据脏。坑二Skill过度泛化或过度特化。编译器prompt里如果只说归纳共性LLM很容易给出一份放之四海而皆准的空话比如先分析需求再制定计划最后执行这种Skill毫无价值。反过来如果采样样本太少太偏Skill又会被一些偶然细节绑架。我的解法是在编译器prompt里明确要求每个步骤必须对应样本中至少两条例证并且让LLM在Skill里为每个模式附上证据轨迹ID。这样既逼它找共性又防止它编造虚无缥缈的原则。坑三编译阶段token开销大。一次编译吃进去5到10条轨迹每条轨迹几千token一次调用可能上万甚至几万token成本不低。我一开始用全量日志一次job烧掉几块钱还跑了很久。后来改成两级处理先用小模型做轨迹摘要再用大模型做归纳编译成本降到原来的四分之一效果基本没差。坑四Skill的验证闭环不好做。怎么判断新Skill真的比旧的好我一开始靠感觉结果被现实毒打——感觉变好了实际上回归测试里多个case劣化。后来我老老实实搭了一套最小回归每个Skill维护一个固定测试集用任务成功率关键步骤覆盖率两个指标对比编译前后效果。别嫌麻烦没有闭环编译管线就是在瞎编。4.3 一个可复现的小实验流程如果你也想验证这个思路不用急着搭完整系统可以先跑一个极小型实验。流程是挑一个你手上重复次数最多的Agent任务类型攒50条成功日志和50条失败日志。成功日志编译出一版Skill A失败日志整理成一版constraints。然后选20个新任务分成两组一组让Agent用原始prompt跑一组用原始prompt Skill A跑对比成功率、平均耗时、人工review质量分。我当初做这个实验用的是文章批量摘要任务。基线那组成功率大约73%加了编译Skill那组跑到89%而且摘要质量更稳人工打分方差更小。最惊喜的是Skill里提炼出的分块策略是原始prompt里完全没写过的——它在总结长文本时按章节切块再汇总比我最初让模型一次性读完的方式有效得多。这就是从日志里编译出来的真东西不是人能轻易想出来的。所以我的建议是别把这篇论文当纯学术paper看它可以是一套非常实际的Agent工程方法论。你要是手头有跑了一两个月的Agent、日志体量已经不小了真的可以动手做一次日志编译试试。就算不做完整的编译管线把根据成功日志沉淀Skill这件事加入日常开发流程都会有立竿见影的效果。我自己现在的习惯是每次解决完一个Agent的棘手case就把这条轨迹单独抽出来跑一次单一轨迹编译生成一条极简Skill入库。积少成多效果出乎意料地好。