最近在逛技术社区时,发现一个叫 WikiSkill 的方向讨论度突然高了起来。起因是一篇关于“用 Wiki 层保存经验,显著提升 Skill 效果”的论文被不少开发者转发,结合当前 Claude Code Skill、Codex Skill、Agent Skill 这些概念持续升温,很多人开始重新思考一个问题:我们辛辛苦苦写的 Skill,为什么换一个场景就“失灵”了?
这篇文章不会去逐字翻译论文,而是站在工程落地角度,把 WikiSkill 的思路拆开来看。我们会先讲清楚 Skill 的现状痛点,再说明 Wiki 层要解决什么问题,然后给出一个简化版的可运行示例,最后总结实践中的选型参考和常见坑点。
如果你正在做 Agent 应用、正在写自己的 Skill 库,或者被“Skill 效果不稳定”“换个人用效果就不一样”这类问题困扰,这篇文章应该能给你一个不同的解题方向。
1. 背景与核心概念
在聊 WikiSkill 之前,先把 Skill 本身说清楚。
1.1 Skill 是什么:Agent 世界里的“肌肉记忆”
最近半年,Claude Code Skill、Codex Skill、OpenAI Codex Agent Skills 这些概念频繁出现在开发者视野里。所谓 Skill,简单理解就是一套可复用的提示词模板 + 执行规则 + 工具调用方式的集合,它把某一类任务的处理经验封装成一个单元。
举例来说,你要让 Agent 做日志分析,可以写一个log-analysis-skill,里面包含:
- 日志分析的步骤提示词;
- 需要关注的异常关键词;
- 输出报告的格式模板;
- 是否调用额外工具(比如 grep、jq)的规则。
这样一来,Agent 在遇到日志分析类任务时,不再从零开始理解用户需求,而是直接加载这个 Skill,按照里面沉淀的流程执行,输出质量自然更稳定。
从使用方式上看,Skill 可以看作是更结构化的 Prompt,是 Agent 能力复用的一个重要载体。
1.2 现有 Skill 方案的痛点
虽然 Skill 的概念很好,但真正动手用过后,很多人会碰到几个问题。
第一个问题是静态化。大多数 Skill 在写完之后就固定了,里面的提示词、规则、示例都是写死的。如果任务环境变了、用户习惯变了、或者项目技术栈变了,Skill 的效果会立刻下降。
第二个问题是经验难以沉淀。比如你在一个项目里发现:分析某类日志时,必须先把时间字段统一成 UTC 再统计;或者审查某类代码时,要先检查配置中心里的开关状态。这些“只有踩过坑才知道”的经验,很难自然写进一个通用的 Skill 模板里。
第三个问题是质量依赖个人水平。同一个任务,不同开发者写出来的 Skill 质量差别可能非常大。经验丰富的人会把边界情况、反模式、典型报错都写进去,新手可能只写了一个流程大纲。
换句话说,传统 Skill 解决的是“把方法固化成模板”的问题,但没有解决“经验从哪来、如何持续更新、如何按场景适配”的问题。
1.3 WikiSkill 的核心思路:先有经验库,再有 Skill
WikiSkill 论文的切入点就在这里。它的核心观点可以概括成一句话:不要指望把经验一次性写死在 Skill 里,而是把经验先沉淀到一个独立的知识层(Wiki 层),然后动态生成 Skill。
这个 Wiki 层本质上是一个结构化的“经验库”,里面存放着大量与任务相关的经验条目。这些条目可能有不同来源:
- 历史任务执行后的总结;
- 专家人工录入的经验;
- 从优秀 Skill 中抽取出来的可复用片段;
- 失败案例的反模式记录。
当 Agent 接到一个新任务时,它不是直接找现成 Skill,而是先去 Wiki 层检索相关经验,然后把检索到的经验与 Skill 模板进行组合,生成一个“带上下文”的 Skill 实例,再执行任务。
任务执行完后,如果有新的经验产生,再把它回写到 Wiki 层,形成闭环。
这样设计有一个明显好处:经验库和 Skill 模板解耦。Skill 模板可以保持精简和稳定,而变化的经验通过 Wiki 层动态注入。不同项目、不同团队可以共享同一套 Skill 模板,但各自的 Wiki 层保存着不同的领域经验,效果自然更有针对性。
2. 从静态 Skill 到 WikiSkill:方案对比
为了更直观理解 WikiSkill 的思路,我们把传统 Skill 构建方式和 WikiSkill 构建方式放在一起对比。
2.1 传统 Skill 的构建路径
传统方式通常是这样的:
- 开发者确定一个任务场景,例如“代码审查”。
- 根据自己的经验编写 Skill 文件,包括审查步骤、关注点、输出格式。
- 测试几个样例,效果差不多了就固定下来。
- 后续使用时,Agent 直接加载 Skill。
这个路径最大的问题是:Skill 的效果上限,取决于开发者写 Skill 那一刻的经验深度。一旦场景稍微偏离,Skill 就变得僵化。
举个例子,你写了一个代码审查 Skill,规定了“优先检查空指针、资源泄漏、并发安全”。但在某个团队里,他们更关心配置文件敏感信息泄露、依赖版本漏洞这类问题。通用 Skill 不会知道这些差异,除非你手动修改 Skill 文件。
2.2 WikiSkill 的构建路径
WikiSkill 的路径则是这样的:
- 维护一个 Wiki 经验层,里面按领域、任务类型组织经验条目。
- 收到任务时,先从 Wiki 层检索与当前任务相关的经验条目。
- 结合 Skill 模板与检索到的经验,拼装成最终执行方案。
- 任务完成后,从执行过程中提炼新经验,回写 Wiki 层。
这种方式下,Skill 模板可以保持“骨架”性质,真正影响效果的是 Wiki 层的经验质量。而且经验是动态累积的,用得越多,经验越丰富,Skill 效果理论上会持续提升。
2.3 一个对比表格
| 对比维度 | 传统 Skill | WikiSkill |
|---|---|---|
| 经验存储位置 | 写死在 Skill 文件里 | 独立 Wiki 经验层 |
| 更新方式 | 手动修改 Skill 文件 | 执行后自动或半自动沉淀 |
| 场景适配性 | 固定模板,换场景容易失效 | 按任务检索经验,动态适配 |
| 团队复用性 | 每个团队各自维护 Skill | 模板共享,Wiki 层按团队隔离 |
| 效果上限 | 取决于编写者经验 | 可随经验累积持续提升 |
| 维护成本 | 低,但僵化 | 略高,需要维护 Wiki 质量 |
这里要说明一点:WikiSkill 并不是要完全取代 Skill 文件,而是给 Skill 增加一个“经验供给层”。在设计上,两者是配合关系,不是替代关系。
3. Wiki 层设计:经验到底怎么存
理解 WikiSkill 的架构后,下一个关键问题就是:Wiki 层里到底存什么、怎么组织?
3.1 Wiki 层的最小结构
可以把 Wiki 层想象成一个 JSON 结构的知识库,每个经验条目至少包含以下几类信息:
- 任务领域:这条经验适用于什么类型的任务,如“日志分析”“代码审查”“SQL 优化”。
- 触发条件:什么情况下应该参考这条经验,如“日志中有 TIME_OUT 关键字”“代码中有 redis 连接操作”。
- 经验正文:具体的操作建议、注意事项、反模式。
- 可靠度或来源:经验的可信程度,来自人工录入还是历史任务沉淀。
- 版本与更新时间:便于追踪经验是否过期。
为什么要有触发条件?因为 Wiki 层经验多了之后,必须能快速判断“当前任务该不该用某条经验”。如果每条经验都塞进去,反而会引入噪音,降低输出质量。
3.2 为什么用 Wiki 而不是数据库
有人可能会问:这不就是个数据库表吗,为什么叫 Wiki 层?
从实现工具上看,确实可以用数据库、向量库或者纯 Markdown 文件来实现。但“Wiki”强调的是它的组织逻辑:
- 知识条目化:每条经验是一个相对独立的条目,而不是一张大表里的一个字段。
- 可协作编辑:不同角色可以维护不同领域的经验,类似 Wiki 的多人协作模式。
- 版本可追溯:经验修改后可以回溯历史版本,避免错误经验污染后续任务。
- 低侵入:团队可以用最朴素的文件方式起步,不一定需要引入重型系统。
所以 Wiki 层本质上是一种知识组织理念,具体技术选型可以非常灵活。
3.3 经验条目的描述示例
下面是一个最小化的经验条目示例:
{ "id": "exp-log-001", "domain": "日志分析", "trigger": "包含关键字 TIME_OUT 或 超时", "content": "分析超时日志时,先将所有时间字段统一为 UTC 时间,再按分钟粒度聚合统计。注意区分客户端超时与服务端超时。", "source": "team_expert", "reliability": "high", "updated_at": "2025-01-15" }这个条目的意思很明确:当 Agent 处理日志分析任务且日志中出现超时关键字时,就注入“先统一时间字段、按分钟聚合、区分客户端服务端超时”这条经验。
通过这样的条目组合,Wiki 层就能覆盖大量细分场景,而不再依赖一个大而全的 Skill 模板。
4. 完整实战:实现一个简化版 WikiSkill
下面我们用 Python 实现一个简化版的 WikiSkill 流程。示例重点演示“经验检索 + Skill 组装 + 经验回写”这三个环节,不依赖任何外部框架,方便你理解核心逻辑后迁移到自己的项目里。
4.1 项目结构
为了便于理解,我们建立一个简单的目录结构:
wikiskill-demo/ ├── main.py ├── skill_templates/ │ └── log_analysis.py ├── wiki_store/ │ ├── exp_log_001.json │ └── exp_log_002.json └── output/其中skill_templates/log_analysis.py保存基础 Skill 模板,wiki_store目录保存经验条目,main.py是主流程。
4.2 定义基础 Skill 模板
先看 Skill 模板。这里不写得过于复杂,关键是包含“分析步骤”和“输出格式”两个部分。
# 文件路径:skill_templates/log_analysis.py def build_skill_prompt(experience_items: list[str]) -> str: """ 根据经验条目组装日志分析任务的提示词。 """ base_prompt = """ 你是一个日志分析助手,请根据以下步骤分析日志: 1. 先定位日志中的错误级别,区分 FATAL、ERROR、WARN。 2. 统计错误分布,按模块或接口维度聚合。 3. 根据经验库中的提示输出针对性建议。 4. 最后生成结构化报告。 输出格式: - 错误汇总:xxx - 高频错误:xxx - 根因分析:xxx - 处理建议:xxx """ if not experience_items: return base_prompt exp_section = "\n".join([f"- {item}" for item in experience_items]) combined_prompt = base_prompt + "\n\n参考经验库中的以下经验:\n" + exp_section return combined_prompt这个函数做的事情很朴素:把基础提示词和经验条目拼接在一起,生成最终的 Prompt。实际项目中,你还可以使用变量模板、few-shot 示例等方式进一步丰富结构。
需要说明的是,这里的实现是一个简化演示。真实项目中,Skill 模板可能包含完整的前置条件、工具调用列表、输出校验规则等,但设计思想是相通的。
4.3 实现 Wiki 经验层:加载与检索
接下来是 Wiki 层。我们先用一个简单的加载函数读取wiki_store目录下的 JSON 文件,再实现关键词匹配检索。
# 文件路径:wiki_store/exp_log_001.json { "id": "exp-log-001", "domain": "日志分析", "trigger": ["TIME_OUT", "超时", "timeout"], "content": "分析超时日志时,先将所有时间字段统一为 UTC 时间,再按分钟粒度聚合统计。注意区分客户端超时与服务端超时。", "source": "team_expert", "reliability": "high" }# 文件路径:wiki_store/exp_log_002.json { "id": "exp-log-002", "domain": "日志分析", "trigger": ["NullPointer", "空指针", "NPE"], "content": "出现空指针异常时,优先检查配置初始化顺序,排查依赖注入是否完成,再检查缓存中是否可能加载半初始化数据。", "source": "historical_task", "reliability": "medium" }再看加载与检索逻辑:
# 文件路径:wiki_store/loader.py import json from pathlib import Path def load_wiki(wiki_dir: str) -> list[dict]: """ 加载 wiki_store 目录下的所有 JSON 经验条目。 """ items = [] wiki_path = Path(wiki_dir) for file_path in wiki_path.glob("*.json"): with open(file_path, "r", encoding="utf-8") as f: items.append(json.load(f)) return items def retrieve_experience(task_text: str, wiki_items: list[dict]) -> list[str]: """ 根据任务文本中的关键字,从经验库中检索匹配的经验正文。 这里使用最简单的子串匹配,实际项目可替换为 embedding 向量检索。 """ matched = [] for item in wiki_items: triggers = item.get("trigger", []) for keyword in triggers: if keyword in task_text: matched.append(item["content"]) break return matched这里有一点需要强调:示例中我用的是子串匹配,它简单、可解释,但召回效果有限。在生产环境中,更推荐把trigger和content做向量化,用 embedding 相似度检索,这样能覆盖近义表达。
4.4 组装 Skill 并执行
主流程中,我们把“加载经验→检索经验→组装 Prompt→交给 LLM”串起来。
# 文件路径:main.py from skill_templates.log_analysis import build_skill_prompt from wiki_store.loader import load_wiki, retrieve_experience def run_wikiskill(task_text: str) -> str: # 1. 加载 Wiki 经验层 wiki_items = load_wiki("wiki_store") # 2. 根据任务文本检索经验 experience_items = retrieve_experience(task_text, wiki_items) # 3. 组装 Skill Prompt prompt = build_skill_prompt(experience_items) # 4. 实际项目中,这里会调用 LLM: # response = llm.chat(prompt) # 本示例只返回 Prompt,便于观察组装结果 return prompt if __name__ == "__main__": task = "线上日志大量出现 timeout 超时,需要分析一下原因" final_prompt = run_wikiskill(task) print(final_prompt)4.5 运行与验证
在命令行运行:
python main.py预期输出会包含基础分析步骤,以及从经验库中匹配到的超时处理经验:
你是一个日志分析助手,请根据以下步骤分析日志: 1. 先定位日志中的错误级别,区分 FATAL、ERROR、WARN。 2. 统计错误分布,按模块或接口维度聚合。 3. 根据经验库中的提示输出针对性建议。 4. 最后生成结构化报告。 输出格式: - 错误汇总:xxx - 高频错误:xxx - 根因分析:xxx - 处理建议:xxx 参考经验库中的以下经验: - 分析超时日志时,先将所有时间字段统一为 UTC 时间,再按分钟粒度聚合统计。注意区分客户端超时与服务端超时。可以看到,同样的一个 Skill 模板,因为 Wiki 层检索到了超时相关经验,最终 Prompt 就变得更加有针对性。如果任务文本换成“出现了空指针异常”,检索到的经验会变成另一条。
这就实现了 WikiSkill 最核心的“经验动态注入”效果。
4.6 经验回写闭环
最后补充一下经验回写。任务执行完成后,如果发现新的规律,可以把它写回 Wiki 层。
# 文件路径:wiki_store/loader.py(追加函数) def add_experience(wiki_dir: str, new_item: dict) -> None: """ 将一条新经验写入 wiki_store 目录。 实际项目中建议先人工审核,避免错误经验污染知识库。 """ wiki_path = Path(wiki_dir) file_path = wiki_path / f"{new_item['id']}.json" with open(file_path, "w", encoding="utf-8") as f: json.dump(new_item, f, ensure_ascii=False, indent=2)这里需要提醒:自动回写不等于无脑回写。在真实系统中,最好设计一个“经验审核”环节。可以在任务执行后先标记为“候选经验”,再经过人工或自动化校验后进入正式 Wiki 层。否则,模型错误识别的结果也可能被当成经验沉淀下来,形成“垃圾进垃圾出”的循环。
5. 常见问题与排查思路
WikiSkill 的概念不复杂,但落地过程中会有不少细节问题。这里整理一些常见场景。
| 问题现象 | 常见原因 | 解决思路 |
|---|---|---|
| 检索到的经验与任务不相关 | 触发词太宽泛,或子串匹配误命中 | 细化 trigger 设计;改用向量检索;增加相关性阈值 |
| 经验条目越多,效果反而变差 | 没有做相关性排序,所有经验都塞进 Prompt | 只注入 top-k 条经验;按可靠度权重过滤 |
| 经验更新后效果无变化 | Prompt 缓存未刷新 | 检查缓存策略;为经验版本增加校验字段 |
| 自动沉淀了错误经验 | 缺少人工审核环节 | 增加候选池 + 审核发布流程 |
| Skill 模板修改后,历史经验不兼容 | 经验条目与模板结构强耦合 | 经验尽量写成“独立建议”,不要依赖模板特定字段 |
| 不同团队共享 Wiki 层导致串味 | 缺少领域隔离 | 为 Wiki 层增加命名空间或 team_id 字段 |
另外,在实现检索时,很多人只关注“匹配到经验”而忽略了“没有匹配到经验”的场景。当 Wiki 层没有可用经验时,可以降级为基础 Skill 模板,并记录 miss 日志,方便后续补充经验条目。
6. 工程实践建议
WikiSkill 听起来是一个论文概念,但它背后的工程思想完全可以落地到现有 Agent 项目中。下面是一些实践建议。
6.1 从“单个 Skill + 小经验库”起步
不建议一上来就搭建一个庞大的知识平台。可以先找一个高频重复的任务场景,比如日志分析、代码审查、SQL 优化,做一个 Skill 模板,配 5 到 10 条经验条目,跑通“检索→组装→执行→回写”的闭环。
跑通之后再逐步扩展经验库,观察效果变化。
6.2 经验条目要有质量门槛
Wiki 层是 WikiSkill 的灵魂,但前提是经验本身是准确、可执行的。建立质量门槛可以从几个方面入手:
- 每条经验必须有明确的触发条件;
- 经验正文应该是“建议”而不是“描述”,避免过于抽象;
- 来源和可靠度要有记录;
- 超过一定时间未使用的经验可以提醒复核。
6.3 检索策略先从简单开始
很多团队一上来就上向量数据库,但其实对于经验库规模较小的情况,简单的触发词匹配配合规则排序已经能解决大部分问题。
当经验条目超过几百条时,再考虑引入 embedding 检索,并做好短文本切分和相似度阈值调优。
6.4 回写流程要设计“人机协同”
前面提过,经验回写不能完全自动化。一个比较稳妥的流程是:
- 任务完成后,AI 先提炼出候选经验。
- 候选经验进入待审核池。
- 由领域专家或触发条件命中率高的人审核通过后,再写入正式 Wiki 层。
- 历史经验可以设置定期复核机制,防止过期经验影响新任务。
6.5 注意安全与权限边界
如果 Wiki 层被多个项目共享,就要考虑权限控制。不同团队应该只能访问自己关注的领域经验,避免无关内容干扰。
在涉及生产环境、安全敏感操作时,越是要严格把关 Wiki 层内容。一条要求 AI “绕过检查执行”的错误经验,很可能在实际任务中引发问题。因此,经验条目的写权限应该收敛到少数可信人员手中,并且保存操作审计日志。
7. 总结与落地思考
WikiSkill 给我们的最大启发,不是某个具体的检索算法,而是把“经验沉淀”和“Skill 执行”解耦开来的设计思想。从一个长期维护的 Wiki 经验层出发,按任务动态检索并组装 Skill,能够有效缓解传统 Skill 静态、僵化、依赖个人经验的问题。
如果你正在使用 Claude Code Skill、Codex Skill 或自研 Agent Skill,可以先尝试做一个最简单的验证:把你踩过坑的经验整理成 JSON 条目,再把现有 Skill 模板改成“基础模板 + 经验注入”的结构,跑几个真实任务对比一下效果。这个验证成本很低,但能帮你直观感受动态经验带来的差异。
当然,WikiSkill 也不是银弹。经验质量、检索精度、回写审核,这些环节都需要投入建设。但方向是对的:真正让 Agent 变强的,不只是更复杂的提示词,而是不断积累和复用的高质量经验。
下一步你可以围绕这几个方向深入研究:
- 向量检索与 RAG 在 Wiki 层中的应用;
- 多智能体环境下 Wiki 层如何共享与隔离;
- 如何通过失败案例自动挖掘新经验;
- 如何用 LangGraph 等编排框架把 WikiSkill 流程接入复杂 Agent 应用。
动手跑一个最小 Demo,比停留在概念讨论更有价值。别只收藏,找个你手头最头疼的重复性任务,试着给它加一个 Wiki 层。