最近有个同事把 Agent 项目的日志目录翻出来几百个 JSON 文件躺在里面他盯着屏幕说“这里面全是答案但我们一条也读不完。”这句话一下子让我想起微软最近那篇提示词优化论文——它的核心主张你可能猜不到与其让大语言模型在那儿自我反思、反复改写提示词不如直接把 Agent 运行时的历史日志编译成下一版 Skill。没错就是“编译”这个词不是“参考”不是“启发式改写”而是像编译器把源码变成目标码那样把日志里沉淀下来的行为模式变成 Agent 可以加载的技能包。这篇论文的思路很适合三类人一是天天改提示词改到怀疑人生的 Agent 开发者二是手里积累了大量对话日志但不知道怎么复用的业务方三是正在搭公司内部“技能库”“提示词库”的工程团队。它解决的痛点是“日志是日志、技能是技能”的断层——运行日志明明记录了 Agent 在真实场景里怎么成功、怎么失败可下一代 Prompt 却还是靠手工写、靠模型猜。我读完论文后的第一反应是这不就是给 Agent 做“编译原理”吗解析轨迹、分析模式、生成指令、回归验证四个阶段一个不少。下面我把这套思路拆开来讲最后附上我自己徒手实现的一版“日志编译器”你可以直接抄作业。1. 提示词优化为什么要换引擎从“手动改”“反思改”到“编译”1.1 传统提示词优化的三种姿势和它们的天花板先说现在大家最常用的优化路径。第一种是纯手工微调你根据一两次线上翻车记录把 Prompt 里某个措辞改掉加一句“如果用户气急败坏就先道歉”。这种做法的天花板非常明显不可复现、不可量化而且改 A 场景经常会震到 B 场景我踩过好几次这种坑——客服 Agent 的退款话术改顺了结果保修期外的用户开始疯狂投诉。第二种是让模型自己做反思式重写就是给 GPT 级别的模型看一段失败日志让它分析原因、输出一段新的 Prompt。这个方向看着聪明但实际上是在“Prompt 空间”里做随机梯度下降而且下降方向还经常震荡。我实测下来一轮反思会把 Prompt 改得过于激进把偶发的极端案例当成主要矛盾结果成功路径的召回率掉得厉害。第三种是自动提示词优化器比如 APE、PromptBreeder、DSPy 那一类在候选 Prompt 空间里做搜索或贝叶斯优化。问题是计算开销高得吓人跑一轮可能要调用几千次模型而且搜出来的 Prompt 往往只有局部可解释性。你可以用它做学术实验但很难放到生产环境里天天跑。这三种姿势有一个共同缺陷把日志当成“debug 材料”而不是当成“生产资料”。日志里明明记录了 Agent 和用户之间的完整互动链成功是怎么成功的失败是在哪一步失败的这些信息却被浪费掉了。微软这篇论文改变的是底层视角——日志不是用来“看”的是用来“编译”的。1.2 日志其实是压缩前的 Skill你可以把 Agent 的历史日志想成一个程序的“运行时堆栈信息”而 Skill 是编译之后的“静态指令集”。运行时信息包含大量的环境变量、用户情绪、工具返回结果、模型中间推理而静态指令集只保留那些在多次执行中都稳定出现、且对最终结果有正贡献的步骤。一个特别好的类比是“从老代码里提炼 API 文档”。你接手一个屎山代码库最好的文档不是让架构师重新写一份设计稿也不是让 AI 帮你读一遍然后编个 README而是直接看那些线上稳定运行了两年的事务日志把高频出现的成功调用链抽出来沉淀成标准接口。日志编译成 Skill 也是这个逻辑多条成功轨迹里共同出现的步骤序列比任何一次单独的完美对话都更有说服力。我自己在项目里还发现日志里最被低估的是失败记录。成功的轨迹告诉你“该怎么做”失败的轨迹告诉你“千万别怎么做”。把这些负例信息也编进 Skill 的约束块里效果比在 Prompt 里写十遍“不要这样做”都强。后面我会专门讲负例编译的技巧。1.3 “编译”和“生成”的核心区别为什么论文要用“编译”这个词而不是“生成”或“合成”这背后是有讲究的。生成是模型对着日志自由发挥输出一段自然语言指令它的特点是“流畅但不可控”编译是确定的源到目标转换解析了什么输入、提取了什么模式、生成了什么模板、做了哪些验证每一步都是可审计的。工程上这非常重要。你看编译原理教科书里的经典流程词法分析、语法分析、语义分析、中间代码生成、代码优化、目标代码生成它是一套有明确阶段的流水线。日志编译成 Skill 完全可以对应词法分析是把原始日志切分成离散事件语法分析是识别事件之间的关系谁先谁后、谁嵌套谁语义分析是判断哪些步骤对结果是正向的代码生成是产出结构化的 Skill 文件最后还要做回归测试——这就是编译器的“链接”阶段。用生活化的比喻生成更像是让一位作家根据采访素材“自由创作”一篇特稿而编译是让生产线工人根据零件图纸“组装”一台标准机器。作品有文学价值但不可复现机器很无趣但每次装配出来都能跑。Agent 生产环境里我们需要的是后者。2. Skill 到底长什么样一个可编译目标的结构化拆解2.1 我们说的 Skill不是一个提示词而是一个包想了解日志编译得先明白编译的“目标格式”到底是什么。很多人以为 Skill 就是一段 Prompt其实那是最大的误解。一个真正可复用、可回滚、可测试的 Skill应该是一个结构化的包至少包含以下字段名称、适用场景描述、触发条件、必要上下文、执行步骤、约束条件、示例集合、版本号。我拿一个客服退款 Skill 来举例。它的触发条件可能是“用户明确表达退款诉求”且“订单在政策允许的时间窗口内”。它的执行步骤可能是先校验订单归属再判断商品类型接着计算可退金额最后生成包含到账时间的回复模板。约束条件可能是“数字商品一旦发货不允许退款”“同一订单只允许发起两次退款”。这些字段为什么必须结构化因为只有结构化了编译器才能对它做校验。比如触发条件里引用了“policy_window”那执行步骤里就必须有一个校验该变量的动作如果 Skill 里声明了“需要 order_id”那上游就必须在上下文里注入这个字段。这种“类型检查”是编译器才有的能力裸的 Prompt 做不到。2.2 拆掉“黑盒提示词”换成结构化 Schema我建议所有做 Agent 技能库的团队从第一天起就把 Skill 定义成 JSON 或 YAML 文件而不是一段 Markdown 提示词。原因很简单Markdown 是给人看的Schema 是给程序看的。人眼扫一遍 Prompt 只能判断“读起来通顺吗”而 Schema 可以被脚本拿去自动生成测试用例、自动检查依赖缺失、自动对比两个版本之间的差异。下面是一个简化版 Skill 的 YAML 结构你直观感受一下name: customer_refund_skill version: 1.3.0 description: 处理符合政策条件的退款请求维护用户信任感 trigger: intent: refund_request within: policy_window context_required: - order_id - purchase_timestamp - user_preference steps: - name: verify_order action: check_order_existence args: [order_id] - name: check_policy action: verify_within_policy_window args: [purchase_timestamp] - name: decide_refund action: approve_refund condition: digital_goods_shipped false - name: craft_reply action: generate_reply_with_eta args: [estimated_time] constraints: - avoid: 承诺超出政策的额外补偿 - avoid: 在验证订单前直接道歉 examples: - input: 我在你们家买的电子书完全打不开我要退款 steps: [verify_order, check_policy, decide_refund, craft_reply] - input: 耳机用了三天坏了能退吗 steps: [verify_order, check_policy, decide_refund, craft_reply] tags: [customer_service, refund, policy]这套结构现在看着多余等你积累到第 100 个 Skill 的时候就知道有多重要了。没有 Schema 的技能库最终都会变成一堆互相矛盾的 Prompt 碎片谁也不敢乱改因为不知道改完会影响到哪个下游流程。就像没有类型声明的 JavaScript 项目写着写着就到处都是隐式类型转换的 bug。2.3 生态里的 Skill 探索这两年各家的 Agent 框架都在往这个方向靠。OpenAI 那边的 Skill 概念、Claude 家的 Skills、还有 Cursor 里的 rules 文件本质上都是“把行为规范封装成可加载的包”。Cursor 的 .cursor/rules 为什么比直接在系统提示词里写规则好用因为它可以按目录生效、可以版本管理、可以针对不同代码模块启用不同规则这不就是 Skill 的雏形吗。我关注这些生态点是想说明日志编译成 Skill 不是孤立的技术而是整个 Agent 工程化浪潮里的一环。随着技能库从“一段话”升级成“结构化包”“谁来维护这些包”就成了绕不开的问题。靠手工维护 20 个 Skill 到极限了但靠日志编译自动维护 200 个 Skill是完全可行的。这也是为什么我觉得论文里的“编译”思路会变成标配。3. 日志编译成 Skill 的完整链路输入、变换、输出、验证3.1 输入侧历史日志先做结构化预处理日志编译的第一道工序是把杂乱无章的运行记录整理成可分析的轨迹。我这里说的“日志”不是你在终端里看到的那种打印字符串而是 Agent 运行过程中每一步的状态快照。至少应该包含四类事件用户消息、工具调用、中间观察结果、最终回复以及最后的整体结果标记成功或失败。几周前我帮一个团队看他们的 Agent 日志发现最大的问题不是没有日志而是日志格式极度混乱租户 A 用 JSON、租户 B 用 CSV、租户 C 直接在打印语句里塞中文。这种状态下根本没法谈编译。我后来给了他们一个强制策略所有 Agent 运行日志统一输出为 JSONL每行一个事件事件 schema 完全统一。下面是推荐的事件格式你在 Agent 的日志层直接按这个结构写{ event_id: a1b2c3, session_id: s-20250110-0012, timestamp: 2025-01-10T14:23:11Z, type: tool_call, agent_name: customer_service_v3, data: { tool_name: check_order, input: {order_id: ORD-2025-0001}, output: {status: valid, window: within} } }预处理阶段还要做三件事第一是脱敏把订单号、手机号、姓名这些 PII 字段替换成占位符第二是截断长文本和完整工具输出保留前 N 个字符避免编译过程中 token 爆炸第三是标记在会话末尾增加一个 outcome 字段明确标注 overall_success 还是 overall_failure。没有这个标记后面区分正例和负例就只能靠猜。3.2 变换侧从轨迹里提炼“稳定的步骤序列”预处理结束后进入编译器的核心环节——模式提取。这一步的目标是从几十条成功轨迹中找到那个“稳定结构”。我最先尝试的方法非常简单粗暴统计每个步骤在多条成功日志里出现的频率超过预设阈值的保留下来低于阈值的丢弃。比如你有 50 条退款成功的日志里面“check_order_existence”出现了 49 次“verify_within_policy_window”出现了 45 次“apologize_first_softly”只出现了 12 次那前两个步骤就有资格进入 Skill 的主体最后一个步骤大概率只是某些对话里的风格偏好不属于核心流程。这里要注意阈值不能设太高也不能设太低设成 90% 会漏掉低频但必要的分支步骤设成 30% 又会把噪声编进技能里。但光靠频率统计有一个明显盲区它只能发现“单点步骤”发现不了“步骤之间的顺序关系”。为了解决这个问题我加了一层简单的 n-gram 统计把连续出现的步骤对也纳入计数比如“check_order_existence - verify_within_policy_window”这对序列出现了 40 次那它就是一个强模式。这很像编译原理里的语法规则提取先找最高频的 token 序列再压缩成一条产生式。如果日志量特别大、步骤特别碎我建议第二阶段再用 LLM 辅助归纳。做法是把清洗后的成功轨迹丢给模型让它输出“抽象步骤列表”每条抽象步骤对应原始日志里的具体动作这样就能把“调用 check_order(query{id: 123})”抽象成“校验订单存在性”。LLM 在这里的角色是“智能提取器”不是“自由作家”抽象结果必须能映射回原始事件否则你没法验证它。3.3 输出侧生成版本化的 Skill 包模式提取完成后就进入“代码生成”阶段——把稳定的步骤序列填充进 Skill 模板并配上触发条件、约束和示例。这一阶段没有太多 AI 魔法更多是确定性的模板拼装。你只需要定义一个字段映射规则轨迹里的高频意图标签映射到 trigger高频动作序列映射到 steps负例日志里的公共失败原因映射到 constraints。我给自己的编译器写了不到两百行 Python核心逻辑就是接收一个 JSONL 日志文件输出一个 YAML Skill 文件。触发条件通过统计“开始事件”的意图标签频率来选定步骤通过频率过滤和 n-gram 排序来生成示例则直接从成功日志里采样三条保留最典型的输入输出对。整个流程里 LLM 只负责把工具调用名称翻译成人话。一个重要提醒生成的 Skill 文件必须带版本号和生成元数据。我在 YAML 里额外加了一个 provenance 字段记录“这个 Skill 是由哪些会话编译来的、使用了多少正例多少负例、模型在哪个环节参与了抽象”。这样以后万一 Skill 行为异常你可以一键回溯到源头看是不是某次编译吞入了一批脏数据。3.4 验证侧用日志回归集做单元测试编译器的最后一步是验证这一步很多人会忽略。你辛辛苦苦从日志里提炼出 Skill总不能在模型里跑一遍“感觉还行”就算完事。正确的做法是切出一部分保留日志作为回归集把编译出来的 Skill 当成新的 Prompt 前置逻辑跑一遍成功率和失败率指标。我的验证方法分两层。第一层是“正例命中率”回归集里的成功案例用新 Skill 后是否还能成功第二层是“负例拦截率”回归集里的失败案例用新 Skill 后是否会被约束条件挡下或者是否会触发人工升级。这两层都过了才敢把 Skill 发布到生产环境。你可以把验证过程理解为编译器的“链接阶段”和“集成测试”。编译器不仅要把源文件编译成目标文件还要检查符号是否解析、依赖是否存在日志编译器则要检查 Skill 引用的上下文字段在日志中是否真实存在、触发条件是否可以由输入事件满足。这两类检查都是机械性的不需要 LLM 参与。4. 徒手实现一个“日志编译器”一个能跑的落地姿势4.1 先别写代码先设计日志格式我踩过的最大的坑就是直接上手写日志挖掘脚本结果花在清洗脏数据上的时间比写算法还多三倍。所以我把话放在最前面如果你想做日志编译第一件事是定日志格式第二件事还是定日志格式。我在前面给过一个 JSONL 事件 schema这里补充两个细节。第一每个事件都要带 session_id同一个会话的所有事件要用 ID 串联起来。没有这个字段你根本无法还原一条完整的轨迹。第二会话结束时必须写一个 summary 事件里面包含 outcome 和 error_type 字段。outcome 标记成功失败error_type 在失败时填上“政策校验失败”“模型拒绝回答”这类粗粒度原因方便编译负例规则。我在实际项目里见过太多团队日志里什么数据都有就是没有 session 关联和结果标记。这意味着他们的日志只能用来复盘单个请求没法做轨迹级分析。你得把日志当成数据库表来设计而不是当成“打印出来给人看的东西”。4.2 一个 Python 脚本从 JSONL 日志到 Skill YAML下面这个脚本是我从项目里抽出来的简化版本逻辑很直白但足够跑通“日志编译”的主流程。它不依赖任何重型框架只要有 Python 3.9 以上环境就能跑。import json import re from collections import Counter, defaultdict from typing import Dict, List, Tuple def load_logs(path: str) - List[Dict]: sessions defaultdict(list) with open(path, encodingutf-8) as f: for line in f: evt json.loads(line) sessions[evt[session_id]].append(evt) return list(sessions.values()) def extract_steps(session: List[Dict]) - List[str]: steps [] for evt in session: if evt[type] tool_call: tool evt[data][tool_name] action evt[data].get(input, {}).get(action, ) steps.append(f{tool}:{action}) elif evt[type] summary: # 把成功标记记录在最后 steps.append(__outcome__: evt[data][outcome]) return steps def compile_skill(logs: List[List[Dict]], threshold_rate: float 0.6): success_sessions [s for s in logs if extract_steps(s)[-1].endswith(success)] if len(success_sessions) 3: return None # 样本太少不适合编译 freq: Counter Counter() ngram: Counter Counter() for sess in success_sessions: steps extract_steps(sess)[:-1] # 去掉 outcome 标记 freq.update(steps) for i in range(len(steps) - 1): ngram[f{steps[i]} - {steps[i1]}] 1 threshold max(1, int(len(success_sessions) * threshold_rate)) core_steps [] for step, count in freq.items(): if count threshold: core_steps.append(step) # 按日志中的自然顺序排序 ordered_steps sorted( core_steps, keylambda s: min( extract_steps(sess).index(s) for sess in success_sessions if s in extract_steps(sess) ) ) pattern_steps [pair.split( - )[0] - pair.split( - )[1] for pair, count in ngram.items() if count threshold * 0.8] skill { name: auto_compiled_skill, version: 0.1.0, trigger: {intent: auto_detected}, steps: ordered_steps, stability_patterns: pattern_steps, generated_from: {positive_sessions: len(success_sessions)}, status: draft } return skill if __name__ __main__: sessions load_logs(agent_logs.jsonl) skill compile_skill(sessions) if skill: with open(skill.yaml, w, encodingutf-8) as f: import yaml yaml.safe_dump(skill, f, allow_unicodeTrue, sort_keysFalse)这个脚本里有两个通用参数值得你根据实际情况调整。一个是 threshold_rate默认 0.6 表示“一个步骤至少要出现在 60% 的成功轨迹里”业务数据特别规整时可以调到 0.5特别散乱时建议调到 0.7 以上宁可漏步骤也不要把噪声编进去。另一个是 ngram 的稳定性阈值 0.8控制顺序模式提取的松紧度。这段代码没有用到 LLM它是一条纯统计管线。在实际使用中我会在这个统计结果之上再用一次 LLM 把步骤名称翻译成更抽象的自然语言比如把“check_order:verify - policy:within”翻译成“先确认订单存在再判断是否在政策时限内”。这个翻译过程是可选的但可以让 Skill 的可读性提高不少。4.3 一个小案例电子书客服 Agent 的退款 Skill 编译过程我在自己的一个电子书客服 Agent 项目里完整跑过一遍这套流程。那个 Agent 每天要处理大量退款请求用户不满意的主要原因是“电子书打不开”“误购想退款”“体验与描述不符”这三类。之前维护提示词基本靠我手动改每次发布新的退款政策都要焦虑三天因为不知道哪个规则会影响老用户。我先花了一个下午把日志格式统一成 JSONL schema跑了两天真实流量积累了 120 条完整会话。用我上面的脚本一跑发现成功退款轨迹里出现频率最高的步骤序列是check_order_existence - verify_policy_window - verify_digital_goods_shipped - approve_refund_or_escalate - generate_reply_with_eta。这五个步骤构成了一个稳定的“退款主链”。而失败轨迹里最高频的错误节点出现在 verify_policy_window 之前——很多 Agent 会直接忽略政策时限贸然承诺全额退款。我把这个模式提取成 Skill 的一条 constraint“在确认订单购买时间在政策窗口内之前禁止做出任何退款承诺”。编进去之后退款问题的首轮解决率从 61% 涨到了 78%最关键的是那些“乱承诺被二次投诉”的数量降到了原来的三分之一。这个案例说明什么说明日志编译不是帮你“发明”新的优秀话术而是把被你忽略了的一致行为固化下来。Agent 在几十次成功会话里早就学会了正确流程只是没有形成静态的、可复用的 Skill你的业务流程一变提示词一改这些能力就丢了。日志编译给 Agent 装上了“肌肉记忆”。5. 常见问题排查与避坑实录5.1 日志脏、噪声大先清洗再编译日志编译最常见的失败原因就是输入太脏。我见过有人直接拿生产日志跑脚本结果编译出了一个包含“调用搜索工具 - 调用搜索工具 - 调用搜索工具”的 Skill因为他的 Agent 在重试时连续调了三次同一个工具每次返回空结果。这种重复是重试机制产生的噪声不是核心路径。清洗手段其实不复杂第一步去重同一个会话里连续相同的事件只保留第一条第二步归一化把工具调用参数里的具体 ID 全部替换成占位符避免模式提取被个别长 ID 带偏第三步剔除异常状态码为超时的、上下文长度爆掉的、被用户手动终止的会话直接排除。我建议把这些清洗规则写成一个独立的 preprocess.py每次编译前强制跑一遍顺序不能乱。还有一个容易被忽略的点采样偏差。如果你的 120 条成功日志里 100 条来自上午 9 点到 11 点的流量这个时间段的用户大概率都是着急回购的老用户编译出来的 Skill 会对“平静用户”特别有效但面对深夜暴躁用户时往往失灵。有条件的话日志样本要在时间段、用户类型、Agent 版本三个维度上做分层采样。5.2 编译出的 Skill 过拟合样本不足时锁定为 draft另一个高频问题是过拟合。用 5 条日志编译出来的 Skill大概率只能在这 5 条日志里跑得通换个输入就废。我在项目里定了一个硬性约定正例样本少于 20 条的编译结果只能标记为 draft禁止直接进入生产环境少于 5 条的直接不编译返回“样本不足”的提示。过拟合还有一个变体叫“场景耦合”。比如你的日志里 Agent 总是先查询订单再查询库存但其实这两个查询没有因果关系只是当时的业务流程恰好把它们排在了一起。这时编译出的 Skill 就带上了多余步骤。解决方法是看步骤之间是否存在数据依赖如果第二步的输入里有第一步的输出字段那这个顺序是强依赖要保留如果完全没有依赖只是时间上先后出现那这个顺序就是弱关联应该降权。我建议你在编译成功后做一次“减法测试”把 Skill 里每个步骤分别移除跑一遍回归集如果某个步骤移除后成功率反而上升那它就不是必要步骤应该删掉。这个测试很费时间但能有效避免技能膨胀。5.3 负例路径也要编译把失败日志做成“禁忌清单”我在第三节提过负例的重要性这里展开讲。我自己一开始只编译正例结果 Skill 非常“胆大”遇到政策窗口外的订单也敢直接承诺退款因为正例里根本没见过这种事。后来我把失败日志也纳入编译做法是提取失败轨迹中 Agent 最后一次执行的动作然后把“在某种上下文下不要执行该动作”写成约束。比如失败日志集中在“用户询问已发货商品能否退款”这个场景Agent 的最后一步往往是直接调用了 approve_refund我就生成一条 constraint“当 shipment_status shipped 时禁止调用 approve_refund改为调用 condition_escalation”。这条负例规则的效果立竿见影比你在 Prompt 里写一百遍“要遵守政策”管用得多。因为负例规则的来源是真实失败案例它有明确的上下文条件不会像手工写的“不要犯错”那样空泛。我甚至建议把负例约束单独抽到一个文件里比如 constraints.yaml和正向步骤分开管理。这样你可以单独审计“哪些禁忌是从失败中学来的”心里更有底。5.4 Skill 版本升级后的回归测试建立 mini 回归集Skill 发布之后不是一劳永逸的。日志在变、用户在变、业务政策在变今天编译出来的 Skill 下个月可能就不对劲了。我吃过一次大亏新编译的 Skill 版本把流程缩短了一道步骤导致一批本应转人工的疑难工单被系统直接自动回复用户满意度雪崩。从那以后我建了一个 mini 回归集大概 30 条经过脱敏的真实日志覆盖典型成功路径、政策边界、异常输入三类情况。每次编译新 Skill 或者更新 Skill先跑这个回归集对比旧版本的成功率和失败率差异超过 5 个百分点就自动阻断发布。这套流程本质上就是给 Skill 做的 CI/CD代码有回归测试技能为什么不能有回归集还有个额外好处它能防止你过度依赖最新编译结果。有时候日志数据一换编译出的 Skill 版本号升到 2.0但回归集告诉你它比 1.3 还差这时候你就有据可依地驳回它而不是凭直觉说“感觉不对劲”。5.5 安全与可解释性给编译流程装一道人工闸门日志编译属于半自动化流程我强烈建议你在发布链路里保留一道人工审批。全自动编译、全自动发布看起来很酷但生产环境不是你练手的地方。日志编译中最危险的场景是某次采样偏差把异常行为当成了主流行为编译出一个“看起来很有逻辑但实际在闯祸”的 Skill而且因为它是从日志里学来的你还很难发现哪里出了问题。我目前的流程是脚本生成候选 Skill 后先由规则引擎自动检查有没有明显破坏性约束比如“承诺超政策补偿”“直接调用支付接口”这类危险动作检查通过后再由人工审核一眼触发条件和约束列表确认没有诡异逻辑最后合并到生产版本。整个流程只要花我十分钟但能省掉无数次线上事故的善后时间。可解释性方面我坚持在 Skill 的 YAML 里保留 provenance 字段记录每一个步骤是由哪些具体会话支撑的。这样任何一步出了问题我都能定位到“哦这个步骤是从这三条日志里学来的而这三条日志的母体是同一个用户”然后决定是删步骤还是补日志。最后分享一个小技巧别急着一次性编译大型 Skill。我一开始想直接编译一个“完整客服 Skill”结果输出长得吓人根本没法审查。后来改成按意图拆解一次编译一个退款 Skill再编译一个换货 Skill每个都小而专效果反而好得多。日志编译的本质不是追求一次性完美的答案而是把 Agent 的能力沉淀成可以持续迭代的小模块——每积累一段时间的日志就重新编译一次让 Skill 跟着业务一起进化。这种“持续编译”的思路我认为比手写一套完美提示词更值得投入。