Agent Skill 自我进化:轨迹归纳与文本空间优化的完整指南

发布时间:2026/9/12 10:41:10
Agent Skill 自我进化:轨迹归纳与文本空间优化的完整指南 这两年只要聊 AI Agent几乎绕不开一个词Skill。从 Claude Code 的 skill 目录到 Codex 的 skill 插件再到各类 agent 框架里的 skill 模板大家都在折腾“怎么让模型更听话地完成复杂任务”。但你有没有想过一个问题——Skill 本身能不能自己变强它不是一段写死的提示词而是可以像人一样从干过的活里总结经验、优化自己的行为。这篇博文我想从轨迹归纳和文本空间优化这两个角度把 Skill 的进化路径拆开聊聊。先说清楚这篇文章是给谁看的你如果是刚开始接触 agent skill想知道 SKILL.md 到底是什么、怎么写出一个能用的技能包前面两节可以帮你建好基础认知如果你已经在写 skill但总感觉越用越不稳定、输出忽好忽坏那后面关于轨迹归纳、评测闭环和常见坑的部分应该能直接帮到你。我会结合我实际开发 skill 的经验把思路和踩过的坑一起讲透。1. Skill 是什么它凭什么能“进化”1.1 一个 Skill 的最小构成Skill 在概念上并不神秘它就是把“完成某类任务的一整套方法”封装成一个可复用的单元。一个标准的 skill 包通常包含 SKILL.md 作为入口文件里面写清楚这个技能解决什么问题、适用什么场景、调用时需要注意什么然后在同一目录下放若干辅助文件比如脚本、模板、示例数据、依赖声明。模型在运行时会把这些文件加载进上下文相当于给模型发了一份“岗位说明书”。有个容易忽视的点skill 并不只是“提示词”。提示词只是入口真正让 skill 变强的是整个目录文件组成的“知识包”。你可以把脚本放进去做计算可以把优秀案例放进去做 few-shot 参考可以把历史失败记录放进去做规避提醒。也就是说skill 的本质是一个“可挂载的局部知识库 行为规范”它不是一个字符串而是一个目录。1.2 为什么 Skill 能被迭代出“智能”传统提示词最大的问题是你每次想改行为都要手改提示词然后祈祷这次改动不会破坏别的地方。Skill 的设计天然更适合迭代因为它有文件结构、有版本、有依赖声明你可以像管理代码一样管理它。我自己在维护 skill 包时会把它放进 Git 仓库每次改完行为都会提交一次 commit。这样一来某个改动导致模型表现变差我可以直接用 git diff 看改了什么快速回滚模型表现变好我也知道是哪一次改动带来的提升后续可以继续往这个方向压。这种“可回滚、可对比、可复用”的属性是 skill 能持续变强的基础设施前提。1.3 Skill 和 Agent 的分工热词里经常把 skill 和 agent 放在一起比较大家很容易混淆。我的理解是agent 负责决策和执行比如读完用户的需求、拆分步骤、调用工具skill 负责提供“怎么把这一类事做好”的领域方法论。你可以把 agent 想成一个全能实习生skill 就是他在做某类项目前临时翻的专业手册。没有手册实习生也能干活但有了手册干活的套路会更稳、质量上限更高。因为分工如此skill 的进化路径也就清晰了agent 负责在真实任务里产生轨迹数据skill 负责从这些轨迹数据中提取“哪些做法有效、哪些做法无效”然后把有效做法固化下来。接下来的两个核心机制轨迹归纳和文本空间优化正好对应了这个过程的两端。2. 轨迹归纳Skill 的记忆从哪来2.1 轨道归纳入门把干过的活变成经验“轨迹归纳”这个词听起来玄乎拆开看就是一点把 agent 一次真实任务中的完整行为链——用户需求、中间思考、工具调用、输出结果——记录下来然后从中提炼出稳定的模式。比如你让 agent 用 skill 写一份数学建模论文它会经历“读题、查文献、搭模型、写代码、跑结果、排版”一系列动作。轨迹记录会把每一步的输入输出都存下来尤其是哪些操作成功了、哪些失败了。我常拿程序员带新人的场景来类比。老带新的时候不会一上来就讲架构而是先带着新人做几个需求做完一起复盘这个任务应该先看什么、遇到报错先查哪里、哪些坑是这类型项目独有的。轨迹归纳本质就是把这套“复盘”自动化把一次项目的操作过程变成可以被后续任务复用的经验。2.2 轨迹归纳的常见做法从日志到行为模板实现轨迹归纳有三种常见路线难度递增最简单的做法是日志回溯。直接解析 agent 运行日志把工具调用序列抽取出来找高频出现的操作组合。比如 20 次任务里有 15 次都用到了“先读取文件目录 → 再定位相关代码 → 最后写测试”这个顺序就可以把它做成一个推荐流程。进阶一点是行为聚类。把轨迹向量化然后用聚类算法把相似轨迹归成一组。每组代表一种“常见的干活姿势”再为每组生成一个代表性模板。这个方案比日志回溯更灵活能发现你没想到的模式。再进一步是规则抽取。把“条件-动作”对提取出来比如“当模型输出的 JSON 解析失败时下一步应该先检查是否包含 Markdown 代码块标记”。这种规则可以直接写进 SKILL.md 的规避清单里。我实际做的时候通常先用日志回溯快速出一版粗模板立刻改善当前任务的表现等积累了足够多数据再做行为聚类和规则抽取把 skill 打磨到更通用的状态。不要一上来就追求复杂算法先跑通闭环最重要。2.3 一个可落地的轨迹归纳 Demo我分享一下最简的实现思路。假设你的 agent 是 Python 写的项目日志里已经记录了每一次调用 LLM 的 prompt 和 response以及 tool_call 的参数。你可以写一个脚本把同一类任务的工具调用序列做统计from collections import Counter, defaultdict import json def extract_tool_sequences(log_path, task_typeNone): sequences defaultdict(list) with open(log_path, r, encodingutf-8) as f: for line in f: record json.loads(line) if task_type and record.get(task_type) ! task_type: continue ops tuple( step[tool_name] for step in record[steps] if step.get(tool_name) ) sequences[record[task_id]].append(ops) counter Counter() for ops_list in sequences.values(): for ops in ops_list: counter[ops] 1 return counter # 示例统计数学建模类任务里出现最多的工具调用组合 stats extract_tool_sequences(agent_logs.jsonl, task_typemath_modeling) for ops, count in stats.most_common(5): print(count, -, ops)拿到统计结果后你可以人工确认高频序列是否合理再把它加工成 SKILL.md 里的推荐步骤。比如“查文献 → 写代码 → 跑结果 → 写摘要”这条序列高频出现就把它写进 skill 的“建议执行顺序”小节。这一步其实就是“轨迹归纳”的 MVP不需要重型算法也能明显提升 skill 的稳定性。2.4 轨迹归纳的坑你归纳的不一定是金矿也可能是坏习惯轨迹归纳最需要警惕的是“把偶然的成功当成了必然”。agent 某次任务成功可能只是因为那次运气好、模型状态在最佳区间而不是操作序列本身有多优秀。如果你只收集成功轨迹很容易把没必要的复杂步骤也固化下来如果只收集失败轨迹又容易把模型搞成惊弓之鸟啥都不敢干。我见过一个例子某 skill 的轨迹日志显示凡是任务成功agent 都会在最后多调用一次“重新整理输出格式”。开发者以为是这个步骤提升了质量就把它写进了 skill 的强制流程。结果后续任务全都变成了“先干活再从头格式化一遍”浪费了大量 token输出质量并没有提升。原因很简单那次多调用一次格式化只是因为前一步输出被截断了跟成功率没有因果关系。归纳轨迹时最好带上“因果判断”至少多问一句这个步骤真的对结果有贡献还是只是伴随出现3. 文本空间优化Skill 变强的真正战场3.1 什么是文本空间优化如果说轨迹归纳是从“行为数据”中找模式那文本空间优化就是直接作用在“模型看得见的文字”上。大模型的一切行为都由输入文本决定所以 skill 变强的过程本质上就是不断调整输入文本的质量。这个“文本空间”包括你的 SKILL.md 措辞、示例排列顺序、few-shot 的选择、上下文的裁剪策略甚至包括系统提示和用户消息的组织方式。为什么说它是“空间”因为同一段信息用不同语言组织、放在不同位置、给不同模型看效果天差地别。同一个项目背景写在 SKILL.md 的最前面和最后面模型遵循的优先级都不一样。同一个示例放两个还是放五个效果也会出现边际递减。你需要在这个高维文本空间里找到当前任务当前模型下的“最优落点”。3.2 提示词层面的优化手段我把文本空间优化拆成三类手段措辞级优化。把模糊的描述改成具体可执行的指令。比如 SKILL.md 里写“注意代码质量”就是模糊的改成“每个函数必须包含 docstring且所有临时文件必须放在 output/ 目录下”就是可执行的。用指令式动词开头能显著提升模型的遵循率。结构级优化。调整 SKILL.md 的章节顺序、段落长度、标题层级。模型对“先定义目标再给步骤最后给规避清单”这种结构理解成本最低。把最核心的规则放在文档前三分之一处通常比埋在末尾效果好。上下文级优化。主要在运行时做比如动态裁剪 skill 里用不到的章节、把示例从三个压缩成一个、根据当前任务关键词只加载相关片段。这三种手段可以同时使用。我维护的测试用例生成 skill早期只有 3000 多字的描述效果一般后来我把描述拆成“核心必读”和“按需加载”两部分核心部分只有 800 字其余细节放辅助文件模型既不容易漏掉重点也不会被长文档冲淡注意力。3.3 如何用“评测驱动”让模型自己优化文本空间想实现 Skill 自动变强完全靠人肉调提示词是不够的你还需要建立一个反馈回路先定义一组评测用例和打分标准然后让 skill 在这些用例上跑出得分再把得分低的部分交给模型去反思和重写。这个思路和强化学习里的 reward modeling 类似但做起来可以很轻量。就拿我自己写的“代码评审 skill”举例。我准备了 10 个历史 commit 作为评测集每个 commit 都有一段已知的潜在缺陷。skill 的任务是找出这些缺陷并给出修复建议。我写了一个评分脚本用人工标注结果比对输出得到 F1 分数。每周跑一次评测把得分最低的 2 个用例连同错误输出喂回给模型让它对着 SKILL.md 提出修改建议我再人工审核后合入。持续三轮之后F1 从 0.52 涨到了 0.81。这里有个关键不要直接让模型“优化你自己”而是在小样本上给出具体的“错误输出-期望输出”对比让模型提出针对性的修改点。这样它改的不是泛泛的措辞而是真正和失败用例相关的规则。3.4 一个自动化优化脚本的设计参考如果你想做一个不完全依赖人工的闭环可以参考我下面的脚本骨架。核心流程是用旧 skill 跑评测集 → 收集低分输出 → 拼装反思 prompt → 调用大模型生成新 skill 版本 → 人工确认后再合入。import subprocess import json from openai import OpenAI client OpenAI() def evaluate_skill(skill_dir, cases): 跑一遍评测集返回每个 case 的得分和输出 results [] for case in cases: output run_agent_with_skill(skill_dir, case[input]) score grade(case, output) # 基于人工标注比对 results.append({case: case, output: output, score: score}) return results def propose_improvements(low_score_results, skill_content): prompt build_feedback_prompt(low_score_results, skill_content) resp client.chat.completions.create( modelgpt-4o, messages[{role: user, content: prompt}], temperature0.2, ) return resp.choices[0].message.content cases load_eval_cases(eval_cases.json) results evaluate_skill(skills/code_review, cases) failed [r for r in results if r[score] 0.5] if failed: proposal propose_improvements(failed, read_skill_file()) save_proposal(proposals/latest.md, proposal) print(已生成优化建议人工审核后合入) else: print(当前 skill 达到阈值不需要更新)注意这段代码里的run_agent_with_skill和grade都需要你自己实现前者是 agent 运行时后者是评测脚本。我强烈建议你在项目一开始就建立起这层评测脚本哪怕只是最简单的关键词匹配也比“凭感觉判断 skill 有没有变好”强得多。4. 实操从零构建一个能自我迭代的 Skill4.1 设计 Skill 的目录结构一个可迭代的 skill目录结构一定要清晰。我常用的模板是这样my-skill/ ├── SKILL.md ├── requirements.txt ├── scripts/ │ ├── preprocess.py │ └── report.py ├── templates/ │ └── report_template.md ├── examples/ │ ├── good_case_01.md │ ├── good_case_02.md │ └── bad_case_01.md └── tests/ └── eval_cases.jsonSKILL.md是入口scripts放可执行脚本templates放输出模板examples放 few-shot 素材tests放评测数据。很多人一开始只写一个 SKILL.md 就结束了后面想加东西发现全堆在一起文档越来越长模型越来越抓不住重点。目录结构不是形式主义它决定了你能不能在后续版本里快速增删规则。4.2 写一个高质量的 SKILL.mdSKILL.md 不需要写成论文但一定要让模型“扫两眼就知道怎么干活”。我总结的写作顺序是先一句话说明技能目标再列前置条件接着是完整步骤然后是质量标准和规避项最后放一个最简示例。我给大家一个通用模板参考# 技能名称测试用例生成 ## 目标 为给定函数生成覆盖正常路径、边界条件和异常路径的 pytest 用例。 ## 适用场景 - 输入是 Python 函数源代码 - 输出是可直接运行的 pytest 文件 ## 执行步骤 1. 分析函数签名识别所有输入参数和返回值。 2. 列出至少 3 个典型场景正常输入、空输入、非法类型。 3. 为每个场景编写独立 test 函数。 4. 运行 pytest -q 验证修复失败用例。 ## 质量标准 - 所有 test 函数必须以 test_ 开头。 - 不允许修改被测试函数本身的代码。 - 断言必须包含实际输出与期望输出的对比。 ## 规避项 - 不要在用例里使用 input() 等待用户输入。 - 不要只覆盖 happy path至少包含一个异常分支。 - 如果被测试函数依赖外部服务使用 mock 而非真实调用。 ## 示例 此处放一个输入源码和对应测试文件的短示例这个模板最关键的是“质量标准”和“规避项”两节它们是 skill 比普通提示词更可靠的核心原因。模型看到明确的“一定要”和“一定不要”执行起来才会有边界感。4.3 设计评测闭环让 Skill 的进化有据可依没有评测闭环skill 的“进化”就无从谈起。我建议哪怕是临时项目也至少要维护一个 20 条左右的评测集。每一条包含输入、期望输出、打分标准。打分标准不一定要用 LLM judge有时候就是几个关键词匹配比如输出里必须包含某个函数名、必须没有某个禁用词。我第一次给 skill 加评测时踩了一个大坑评测集全部来自开发时用过的用例结果 skill 在评测集上分数很高一到真实场景就打回原形。后来我学乖了评测集要定期补充“真实用户问题”尤其是那些导致过失败输出的问题。真正的进化不是把已知问题都修好而是把未知问题慢慢变少。4.4 版本管理进化的安全网Skill 的版本管理比很多人以为的更重要。你永远不知道哪一次改动会让模型“突然变笨”所以必须保证可以随时回到上一个可用版本。我现在每个 skill 目录都会用 Git 管理并且在每次评测分数达到新高时打一个 tag。发布前还会在另一个分支上跑一次完整评测确认分数没有回退。一个很实用的习惯每次改动都记录“实验笔记”写清楚这一版改了什么、评测分数变化如何、在哪些用例上变好、在哪些用例上变差。过几周再回来看你会发现这些笔记比代码本身更有价值。5. 常见问题与排查实录5.1 requirements.txt 缺失导致的依赖问题热词里出现了“缺少 requirements.txt 或依赖声明”这是 skill 开发里非常常见的问题。Skill 包只要用到额外 Python 库就必须在 requirements.txt 里声明否则换一台机器加载 skill 时脚本会直接跑崩。我遇到过最气人的一次本地跑得好好的打包发给同事后报了一个ModuleNotFoundError: numpy排查了半天才发现是依赖没带上。排查技巧在 CI 或者本地用一个干净的 venv 环境做一次全量加载测试确保 requirements.txt 能覆盖所有 import。另外尽量把第三方依赖控制在最小范围能用标准库解决的就别引包一方面降低安装失败概率另一方面也能减少 skill 的启动时间。5.2 轨迹归纳过拟合skill 变得只适合旧任务过拟合是 Skill 进化中最隐蔽的拦路虎。当你不断用同一批历史轨迹优化 skill它很可能会把某些旧项目的特殊习惯当成普适规则。比如某个项目里所有文件都放在 src/ 目录下skill 就可能默认“所有项目的源码都在 src/”遇到其他结构就懵了。我给的思路是归纳出的规则必须能够映射回通用场景至少要留一条“当项目结构不符合默认假设时先探查再行动”的兜底规则。同时每隔一段时间就要拿全新的任务类型去测试 skill如果新的任务类型完全无法执行说明它已经过拟合了需要做一次“反归纳”。5.3 上下文污染SKILL.md 越长效果反而越差很多人在 skill 不好用的时候第一反应是往 SKILL.md 里加内容。但模型对上下文的关注度是有限的文档越长关键内容的权重往往越低。我实测过一个技能包3500 字的时候评测分数最高改到 6000 字后分数反而掉了。原因是额外增加的注意事项分散了模型对核心步骤的注意力。解决方式有两个一是把长文档拆成“核心文件附录文件”核心文件只保留必读内容二是在运行时按需加载只有当前任务命中某个专题时才把对应的附录内容加入上下文。5.4 评测设计常见的三个误区只测成功路径。评测集里全是正常输入skill 当然表现好但真实世界的输入永远是千奇百怪的。至少要有 30% 的异常用例。打分标准过于主观。如果评分标准无法量化为“输出里是否包含某个结构”“是否命中禁用词”评测结果就没有可重复性。每次跑完分数忽高忽低很难判断改动是否有价值。忽略 token 成本。有些 skill 通过堆 prompt、多次调用模型来提升效果评测时只看准确率不看成本迭代方向会被带偏。我在评测脚本里会同时记录 token 消耗准确率提升幅度小于成本增长幅度时会优先考虑精简 prompt。最后分享一点我的实际体会Skill 能不能自己变强我现在可以给你一个肯定的答案能但不是靠“模型自动进化”这种玄学而是靠你把它当成一个真正的系统去设计。轨迹归纳负责从真实的执行历史中沉淀经验文本空间优化负责把这些经验变成模型愿意遵循的表达。两条腿缺一条skill 都会在原地打转。我最大的感受是不要一开始就想做一个一步到位的复杂进化系统。先用日志回溯做一个粗略的 skill 更新再搭一套最简单的评测脚本哪怕评分标准只是几个关键词匹配也好。跑通一轮“运行→收集→归纳→优化→评测”的闭环之后你自然知道下一步该往哪里用劲。踩过几次坑、迭代过几轮版本之后你会发现 skill 真的像活物一样会慢慢长出属于自己的“手感”那种体验挺上瘾的。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询