文章指出大模型的两大进步点并非语言理解与知识背诵,而是行业开始意识到聊天交互模式不足以满足 AI 作为“同事”的需求。核心矛盾在于通用大模型的静态知识与特定场景动态需求之间的错位,模型被“关在上下文窗口里”,缺乏与现实世界交互的“手脚”。为解决这一痛点,文章详细介绍了 Anthropic 的 Model Context Protocol (MCP) 和 Skills,以及 Agentic AI Foundation (AAIF) 提出的 AGENTS.md,构建了一个三层(协议层、技能层、入口层)加一个可选层(仓库/项目层)的 Agent 系统解法地图。其中,MCP 旨在统一模型与外部工具的连接,解决“M x N”集成难题;Skills 则将专家经验和流程固化为可复用、可审计的工作包,实现从“提示词工程”到“上下文工程”的转变;而 IDE、CLI、AI 浏览器等入口层则争夺“默认上下文”的主导权,确保 Agent 在一个受控、可审计的环境中高效执行任务。文章还提供了详细的 Skills 编写指南和 OpenAI 的 Skills 实际案例。
MCP 先把接口统一,Skills 再把能力模块化,最后抢运行时与入口...

去年 11 月份 MCP 刚出现时,我就写过一篇《深度解析:Anthropic MCP 协议》,谈到它会像 IDE 中 LSP 协议一样普及。MCP 也确实大火了一年,将 Agent 推向新的高度。在今年 10 月份,Anthropic 又推出了 Skills 作为 MCP 的补充(Introducing Agent Skills[1],Equipping agents for the real world with Agent Skills[2]),我虽没有写文章,但也在持续关注。期间也看到一些介绍 Skills 的文章,总觉得缺少点什么。其实 Skills 很重要,但不将它放在一个更大的背景下去解释,普通人很难 get 到它的重大意义。
先说句不中听的:大模型这两年最大的进步,不是多会写段子、也不是能背多少知识点(Gemini、GPT 号称世界级知识模型,都挺能“背”的,尤其是 Gemini 在 Google 搜索引擎的加持下,犄角旮旯的知识也没少背),而是产品和工程开始逐渐意识到:聊天框不够用了。你让模型当“问答机”,它只需要说得像;你让模型当“同事”,它就得和系统打交道,读写文件、跑命令,再将结果写回,还得能复盘可验证。这时你会发现,模型再聪明也会卡在同一个地方——它没手没脚,还是被关在上下文窗口里。
于是行业开始补齐缺失的那一半:把模型接到现实世界。这就是 MCP、Skills、AGENTS.md[3]、以及 “AI 浏览器 / CLI / IDE 运行时”这一整串东西出现的原因。它们看起来分散,实际上在拼同一张图。
大家别急,该说的我都会涉及。尤其是 Skills,在这篇文章中也是要花大力气去介绍的。在正式开始前,需从大背景说起,串一串整个 AI Agent 发展脉络。如果读过我这几年写的文章,大家也基本可以感受到一些轮廓(很多概念都不是凭空产生的,千丝万缕的背后,最终都会指向一些更本质的东西,那才是事物的客观发展规律。我写文章也是如此,与其说是写信息,不如说是写关键事件节点,以帮助自己快速学习掌握其精髓):
- 深度思考:聊聊 AI 发展趋势
- 浅谈产品、流量、编程...
- 微信杂谈:AI 产品 & 品味
- Ilya Sutskever:AI 研究、泛化与未来之路
- 浅谈 Agent、MCP、OpenAI Responses API
- Google A2A:多智能体通信协议
- 浅谈 AI 浏览器
- ChatGPT Atlas 发布,AI 浏览器大乱斗...
- 全面解读:Gemini 3 & Antigravity IDE
- AI 编程生态:Anthropic 收购 Bun 意味着什么?
- AI 进阶:从 Vibe coding 到职场必备
- 深度理解:提示词工程
- LLM 高效沟通指南
- Prompts:ChatGPT 提示指南
- 关于 Nano Banana 的一些浅思
- 关于 2025 WAIC 的一些思考
- RL 局限与反思 & 细菌编程(如果你有了解过 skills 结构,就会发现它和细菌编程、组件原子化有异曲同工之处)
- ...
以上列举的文章可能不全,但大体方向已经有了,从 Prompt、到 IDE、浏览器、Vibe coding 基本都有涉及,文章基本都会包含我对事物的一些看法和思考。关于细菌编程,是个有趣的点,我想特别提及一下:Skills 的结构确实在工程上逼近‘细菌式模块’:靠极简索引触发、按需加载、低成本复制扩散;但它的可迁移性最终受宿主运行时与权限边界约束,越强的技能越像“基因 + 宿主生态”的组合体。
📌 原生知识 vs 联网搜索
昨天,遇到个编程问题本来想发朋友圈的,结果发现篇幅尴尬,在朋友圈略长,在公众号略短,就随手以文章卡片的形式发了公众号《Gemini 3 Pro 存货 vs GPT-5.2 联网》,没想到会炸出一堆评论。我重新整理补充了一些昨天缺少的背景信息,也是让人误会,引发讨论的点。
- gemini 是可以联网的, 因为 nano banana 的实时信息生成和 deep research 都需要在联网状态下进行(Nano Banana Pro:能排字、懂事实、守品牌...)。
- 很多人表示 gemini 不喜欢进入联网模式,就一口咬定 gemini 不会联网,要么就是节约搜索成本。此观点在我看来并不准确,不爱调用可能和触发机制有关,但不能因此说 gemini 不会联网,deep research 足以证明它有强大的搜索能力。
- 知识新鲜度也是大家比较关心的点,认为 gpt 勤于检索网页,可以做到实时信息的交叉验证,所以返回的内容更加可信。关于这点,我是比较认可的,因为联网本身就是为了解决大模型预训练之外的知识,但不能简单将勤于检索和更好的回答质量划等号,这是很主观的表达。在互联网上本就充斥着大量垃圾信息,单纯输出一大堆引用资源链接,并不能说明这些就是可靠的“真”知识(不知道有多少人是真正点过每一个资源链接的,我反正是点过一些,gpt 也经常会爬一些不知名人士发言,如果你的 gpt 被污染了,还可能出现一些奇怪的资源)。
- 在昨天的文章中,我更想表达的是原生知识量的差异(google 作为老牌搜索引擎,拥有全世界最大的知识数据库,可能已经把犄角旮旯的知识都作为数据集训练进模型了),但话题被引到联网,讨论的支点已经发生偏离。还有人用知识新鲜度作为讨论点,说前端技术日新月异,不联网,写出的代码根本不能用,所以 gpt 联网会靠谱很多。此观点看似合理,实则刻意混淆原生知识和外挂知识的区别。我举个简单例子,方便大家理解:一个三五岁小孩,和三五十岁成人,你认为哪一个在遇到问题时能更快更理性做出决策?这里牵扯到的东西其实有点复杂,因为经验这种东西本就是在大量试错中逐渐建立起来的,没有一个统一的标准来衡量(白活几十年,不会解决问题的人也不是没有)。以上例子简单对应到模型就是海量知识+犄角旮旯知识,或许会通过预训练成长为模型的原生经验,架构能力和对世界更深层次的理解,而非简单的一句它学习的知识都是过时的、api 都是错误的。这个世界的底层运行逻辑并没有太大变化,编程 api 也都是基于 0/1 这个二进制世界被人一步步抽象设计出来的。
- 其实我并不想拉 gemini、或踩 gpt。因为我两个都有在用(codex 更是我的主力编程工具),原因是:模型的预训练数据集不同,也就导致了模型侧重点不同,如果只单一使用某个模型,很容易被拉入偏见而不自知。
- 真知识和伪知识也是可以深入思考的点,在我看来挺难区别的,需要对信息做大量交叉验证(也可能信息本就是错误的,然后又被成千上万次复刻转发),对 llm 这种本就是概率输出的 ai 更是如此。transformer 架构特性也就决定了幻觉会很难彻底消除,只能靠检索、引用与工具校验把风险压到可控范围,所以在概率黑盒中讨论真知识本就是个伪命题。
先说这么多吧,本以为大家可以 get 到这些背景信息,但事实表明,一切都只是我的感觉...
AI Agent
从聊天到代理,是一次“工程问题”的爆发
在深入探讨具体技术前,我们必须先把问题搞清楚:促使 MCP 和 Skills 诞生的核心矛盾,不是“模型够不够聪明”,而是通用大模型的静态知识与特定场景下动态需求之间的错位。早期 LLM 应用(例如 ChatGPT 初版)更像一个封闭系统:它虽然“读过”互联网上的海量数据,但它无法访问用户刚才创建的 Excel 表格,无法读取公司内网的 API,也无法执行 Python 脚本来验证自己生成的代码。
这堵墙不打破,很多看似“能干活”的对话,最后都会卡在同一件事上:无法执行、无法验证、无法交付。
大背景:打破上下文围墙
“缸中之脑”的困境与早期尝试
这种隔离状态导致了严重的效率瓶颈。用户被迫充当“数据搬运工”,手动将外部信息复制粘贴到对话框中。随着上下文窗口(Context Window)的扩大(从 4k 到 200k 甚至更多),这种手动搬运变得不可持续且昂贵——窗口越大,并不代表更接近真实环境,很多时候只是“把更多杂讯塞进对话里”。
早期的解决方案是碎片化的。OpenAI 推出了 GPTs(OpenAI 开发者大会速览:GPTs 和模型 API),LangChain 推出了 Tools(langchain python/tools[4]),各个 IDE(如 Cursor, VS Code)也各自开发了连接器。这种局面造成了所谓的 "M x N" 难题:如果有 M 个模型(Claude、GPT-5、Gemini-3、Llama 3)和 N 个工具(Google Drive、GitHub、Slack、PostgreSQL),开发者需要编写 M x N 个特定的集成代码。这种生态系统的碎片化极大地阻碍了 AI 代理(Agents)的规模化应用。
到这里,问题已经很清楚:不是“工具不够多”,而是缺少统一的连接方式;不是“模型不会说”,而是它没法进到你的工作环境里“做”。
代理的基本形态:从“对话”到“循环”
代理的基本形态很朴素,其工作流就一句话:想一下 → 做一下 → 看一下 → 再想一下。聊天只需要“想一下”;代理必须能“做一下”。一旦进入循环,问题立刻从“提示词怎么写”变成更工程的东西:
- 工具怎么接?
- 工具一多怎么管理?
- SOP 怎么复用?
- 权限怎么控?
- 输出怎么验收?
- 出事怎么追责?
这些问题靠大上下文窗口解决不了,只能靠架构。也正是在这个意义上,MCP 和 Skills 并不是“新功能”,而是在为这种循环式工作流补齐底座:让模型从“缸中之脑”变成一个能挂载资源、能调用工具、能遵循流程、能交付结果的代理系统。
解法地图:三层系统结构
当代理进入“循环”,行业的解法就会自然收敛。MCP 解决互操作,Skills 解决复用与可控,入口层决定谁拥有用户。用更专业的术语说就是:协议层管连接,技能层管复用,入口层管分发与权限。再把所有名词剥掉,剩下一个很干净的三层:
- 协议层(MCP):把工具与数据源变成“可发现、可调用、可治理”的外设接口,解决 M×N 集成地狱。
- 技能层(Skills / SKILL.md):把“提示词”升级成“可复用的工作包”,让代理在复杂环境里少犯傻,并且能把专家流程固化下来。
- 入口层(IDE/CLI/Browser):把代理能力塞进你每天打开的那个壳里;谁控制入口,谁就能定义默认工作流(以及默认的权限边界)。
在入口层和技能层之间还可以加个可选层:仓库/项目层(AGENTS.md),用来统一指挥 AI 在这个项目里别乱搞——它像 README,但面向的是 agent:构建/测试命令、代码风格、安全注意事项、边界规则,全部写清楚,避免代理在项目里“自作聪明”。
这套分层之所以重要,是因为它解释了行业为什么会快速收敛:当约束一致(要可复用、要可控、要能跑流程),形态自然趋同。
标准化呼声下 MCP 诞生
正是在这种背景下,Anthropic 于 2024 年末推出了模型上下文协议 MCP(Model Context Protocol),并在之后将其捐赠给 Linux 基金会旗下的 Agentic AI Foundation[5],这一举动标志着行业标准化的开始(一同捐赠的还有 goose、AGENTS.md)。

📌 AAIF
Linux 基金会旗下的 AAIF(Agentic AI Foundation)首批“锚定项目”是 MCP、goose、AGENTS.md——严格说只有 MCP 是“协议”,另外两个更像“框架/约定”,但三者刚好覆盖了代理落地的三块底座:连接、执行、项目规范。
- MCP(Model Context Protocol):一个开放协议,用来把 LLM 应用和外部工具/数据源/应用以统一方式连接起来,避免每个模型×每个工具都单独集成。因其安全受控且易部署,目前已成为通用连接标准。
- goose[6]:Block 开源的本地优先(local-first)AI agent 框架。在本地运行,能接你选的模型,并通过 MCP 或 API 扩展工具能力,用来更结构化、可控地执行 agent 工作流(调试、部署等)。
- AGENTS.md:一个简单开放的 Markdown 约定。把“给 coding agent 的项目说明”放在固定文件名里(像 README,但写给 agent),包括构建/测试命令、代码风格、安全注意事项等,让不同工具在不同仓库里行为更可预测;已被大量开源项目采用,并由 AAIF 托管演进。
对于初学者而言,理解 MCP 的最佳类比是硬件领域的 USB-C 接口。在 USB-C 出现之前,连接鼠标、显示器、电源可能需要各种不同的线缆;而 MCP 为 AI 应用程序提供了一个标准化的“插口”。只要开发者编写一次 “Google Drive MCP Server”,无论是 Claude Desktop、Cursor 还是任何其他支持 MCP 的客户端,都可以即插即用,无需重新开发。

MCP 的核心意义在于它将“连接”这一动作从具体的应用逻辑中剥离出来,变成了一种通用的基础设施。这不仅降低了开发者的负担,更重要的是,它让 AI 模型能够像操作系统一样,动态地挂载(Mount)外部资源。

插上工具仍不够:领域专家如何复刻?
到这里我们其实只解决了一半问题。MCP 像 USB-C,把模型和外部世界连起来,让文件、数据库、Git、企业系统都能“挂载”进来。但插口统一 ≠ 事情会做:同一套工具,交给不同的人(或不同的模型会话),做出来的质量差异仍然巨大。真正决定代理能否稳定交付的,不是它能不能调用工具,而是它有没有一套可复用、可审计、可迭代的做事方法。
这就是 Skills 出现的语境:它不是“再写一段更长的 Prompt”,而是把专家的经验流程从对话里搬出来,变成一个可以被安装、被复用的“工作包”。你可以把它理解成从 Prompt Engineering(把话说清楚)走到 Context Engineering(把环境搭好):把该读的资料放好,把该跑的脚本备好,把步骤和验收标准写死,把权限边界收口,最后让模型只在需要时把这份方法加载进来执行。
在 Skills 之前,很多“领域专家”其实是靠重复劳动维持的:比如让模型处理发票,你会在对话里反复强调“提取日期、金额、供应商,输出 JSON,检查重复,金额异常要提示”。这套指令一旦换个会话、换个人、换个模型版本,就容易漏项、跑偏,最后变成提示词越写越长、上下文越塞越脏。
而 Skill 的做法更接近软件工程:它通常是一个文件夹,里面有一份核心说明(用极短的描述告诉模型“什么时候该用我”),再配上更详细的 SOP、示例、模板,必要时还会带脚本把关键步骤做成确定性执行——比如解析、校验、格式化、渲染、导出。这么做的结果是:同一件事不再依赖“模型当场发挥”,而是依赖一套可维护的流程资产;你不是在一次对话里“临时教会模型”,而是在为团队、为未来的无数次调用固化一套专家级肌肉记忆。
小结
所以这条主线可以很明确:
- MCP 负责把世界接进来(连接与挂载):解决规模化集成与互操作问题。
- Skills 负责把方法装进去(流程与边界):解决规模化交付与可靠性问题。
- 入口层(IDE/CLI/Browser)负责把能力塞进日常工作流:并定义默认权限容器与审计方式。
- 可选的 AGENTS.md 负责把项目规矩写给 agent:让它在真实仓库里别乱搞。
在进入 Skills 之前,我会再简短过一遍 MCP——因为没有可控的连接,后面的技能复用、工程治理与交付体验都将无从谈起。
绕不开的 MCP
在 MCP 之前,插件、工具、连接器到处都是:每个平台一套协议、每家 IDE 一套工具定义、每个模型一套调用方式。结果就是经典的 M×N:有 M 个模型/客户端、N 个工具/数据源,就要写 M×N 个胶水层。Anthropic 推 MCP 的思路很直白:让“工具怎么接入”这件事像 USB-C 一样变成通用接口,只要你写了一个服务端,多个客户端就能复用。
MCP 核心组件
MCP 的架构是一个典型的客户端-服务器模型,但引入了 "Host" 的概念,使其更加适应 AI 的应用场景:
- MCP Host (宿主程序):这是用户直接交互的应用程序,例如 Claude Desktop App 或 IDE(如 VS Code)。Host 负责运行 LLM,管理用户界面,并作为编排者决定何时调用外部能力。
- MCP Client (协议客户端):嵌入在 Host 内部的组件,负责与 Server 建立连接。它实现了 MCP 协议的细节,处理消息的序列化和反序列化。
- MCP Server (能力提供者):一个轻量级的进程,它封装了对特定资源的访问权限。例如,一个 "Git MCP Server" 知道如何执行 git pull 或 git commit,并将这些能力通过 MCP 协议暴露出来。
通信层面,MCP 用 JSON-RPC 2.0[7] 做消息格式,传输可以走本地 stdio(把 server 当子进程,stdin/stdout 通信),也可以走基于 HTTP 的方式(面向网络场景的传输选项)。这些选择并不多余,一切都是为了“跨语言、跨进程、易实现”。
MCP 核心能力
一个 MCP Server 可以向 LLM 暴露三种类型的能力,这也是后续理解 Skills 的基础:
- 资源 (Resources): 类似于文件的数据源,LLM 可以像读取文本一样读取资源。它们是可以被读取的静态内容,例如日志文件、API 返回的 JSON 配置、数据库中的一行记录。
- 工具 (Tools): 可执行的函数,这是 Agent 产生行动力的核心。它们会产生副作用或执行计算,例如“发送邮件”、“计算哈希值”、“生成图表”。
- 提示词 (Prompts): 预定义模板,降低用户使用门槛。Server 可以告诉 LLM:“对于这个工具,如果你想让用户使用它,可以使用这个预设的 Prompt 模板”。
这里有个很现实的点:当 tool 能“动手”以后,风险不在模型是否聪明,而在你暴露给它的动作集合是否足够可控。MCP 把这件事从“散落在各个插件里”收束成“协议层的能力暴露”,这就是它的价值。
Skills 强势崛起
MCP 解决连接,Skills 解决“连接后怎么干活”。Anthropic 的 Skills 机制之所以被很多工程师喜欢,是因为它非常“土”:一个技能就是一个文件夹,里面放 Markdown 指令、静态资料、脚本。没有花哨的专有格式,基本靠文件系统就能跑起来——这点很关键:它让技能从“对话里的临时提示词”变成可版本化、可 review、可分发的工程资产。

Skill 里最关键的往往不是正文步骤,而是那句 description:它决定模型什么时候会想起这个技能。Anthropic 在文档里把这套机制讲得很清楚:启动时先把技能的“名字 + 简介”注入系统上下文,真正的详细步骤等需要时再加载。

这就是所谓的“渐进式披露(progressive disclosure)”:不是把一堆 SOP 全塞进上下文,而是先让模型知道“我有这些工具箱”,用到哪个再打开哪个。
设计哲学
Skills 设计中最精妙的部分在于其对 Context(上下文窗口)的高效利用,即“渐进式披露”原则。
- 静默期 (Discovery):当 Claude 启动时,它不会把所有 Skills 的详细指令都读入内存(这会消耗大量 Token 且引入噪音)。它只读取每个 Skill 的 SKILL.md 文件头部的元数据 (Metadata),即名称和简短描述。
- 触发期 (Activation):当用户问“帮我分析这份财报”时,Claude 根据元数据判断出
financial-analyst这个 Skill 是相关的。 - 加载期 (Loading):此时,Claude 才会读取 SKILL.md 的详细内容,甚至根据指令去读取
resources/文件夹下的参考文档。 - 执行期 (Execution):Claude 按照 Skill 定义的步骤调用工具或运行脚本。
这种机制解决了“超级 Prompt”带来的上下文溢出问题,使得 Claude 可以同时拥有成百上千种技能,但只在需要时“唤醒”特定的能力。

官方定义也很朴素:Skill 是一个目录,核心是 SKILL.md,外加可选脚本/模板;关键点在于它是 model-invoked ——由模型根据请求与描述自行决定何时启用,而不是用户手动敲命令。

这句话背后藏着三个很硬的工程事实:
1. Skill = 一个“可被检索的能力单元”,描述就是索引
Skill 是否好用,80% 看 description 写得准不准。因为它扮演的是“能力路由表”的索引:模型先在脑子里做一次“我该不该把这件事交给某个 Skill”,再决定是否加载详细指令。官方文档把这点也说得很直:模型会基于请求语义与 Skill 描述自主触发。
你想要渐进式阅读/加载,其实就是两层“装配”:
- 先装配摘要(低 token,低噪声,用于召回/路由)
- 命中后再装配完整 SOP 与资源(高相关,高密度,用于执行)
这不是 UX 花活,是成本与稳定性:工具一多,什么都塞上下文只会慢、贵、还更容易乱。而 Skills 把“只在需要时加载”做成了默认机制。
2. Skill = 把“概率推理”与“确定执行”拆开
真正能落地的 Skill 一定会有一个倾向:把容易翻车的步骤(解析、计算、提取、格式化、校验)尽量下沉到脚本/工具里,把模型留在编排与判断上。
比如一个将 PDF 表单字段抽取出来的 Skill:让模型“凭感觉”去读 PDF、猜字段,一定会翻车;更稳的是像下面图里那样:
forms.md告诉模型先检查是否可填字段- 再跑
extract_fields.py输出 JSON - 模型读 JSON 再决定怎么填、怎么校验、怎么汇报
这类“LLM 编排 + 脚本确定性执行”的组合,才是 Skills 从“好用”走到“可交付”的关键。


3. Skill = 权限与责任的边界
只要代理能“行动”,安全就不是锦上添花,而是地基。Skill 的价值在于它天然适合做成“最小权限单元”:
- 一个 Skill 只允许调用某几类工具(读文件、跑测试、发消息、改配置)
- 每个 Skill 的输出格式、失败处理、边界条件都能写死
- 每次触发与工具调用都能记录下来(审计与复盘)
反过来,没有 Skill 这种“能力包 + 权限包”的结构,代理系统最终会变成一锅粥:什么都能做、出了事没人说得清是哪里失控。
进化方向
现在大家看到 Skill 结构都觉得亲切:目录 + Markdown + scripts,像极了小项目。但真正的行业拐点会发生在下面这三件事被做成“默认件”之后:
1. Skill 会出现“版本化与回归测试”,像 npm 包一样被养
你想象一下:一个“财报分析 Skill” 今天能用,不代表下周还能用。模型升级、工具升级、数据格式变化、目标系统改版,都会让 SOP 失效。Skill 必然会走向:
- 版本号(不然团队协作会疯掉)
- 回归样例(给几组输入,期望输出是什么)
- 自动验收(跑脚本、跑工具调用、检查输出 schema)
这一套做起来,Skill 才能从“个人秘方”变成“组织资产”。
2. Skill 会组成“能力图谱”,路由不再靠一句 description 硬猜
今天的触发机制主要靠语义相似度与描述命中。工具少时够用,Skill 多了就会出问题:描述写得再好,也会有歧义、冲突、重复、覆盖不全。
下一步很可能是两种收敛:
- 显式标签/领域/输入类型(例如:只处理 stack trace / 只处理 PDF / 只处理 git diff)
- 多阶段路由(先粗分域,再细分 Skill,再选择工具/脚本)
这会让“渐进式披露”从一个策略,变成一个可解释的调度系统。
3. Skill 的分发会牵出“签名与供应链安全”
当 Skill 开始携带脚本、模板、甚至可执行二进制,它就不再只是文本。你会立刻遇到软件供应链老问题:这个 Skill 谁写的?有没有被篡改?依赖从哪来?脚本能不能读我所有文件?
AAIF 把 MCP 与 AGENTS.md 放到中立治理下,本质上就是在为“未来的技能生态”打地基:让协议与约定先中立起来,后面的包管理与分发才有可能公共化。
AGENTS.md 与 Skills 的关系
它们一个管“项目现实”,一个管“做事套路”。不太清楚使用的人,很容易把它们搞混:
- AGENTS.md:告诉代理“在这个仓库里别乱来”,例如怎么装依赖、怎么跑测试、编码风格、危险区域;它就是给代理看的 README。
- Skills:告诉代理“遇到某类任务你就按这个 SOP 来”,更像可复用的作业包。
放进团队协作里,它们刚好对应两种现实需求:
- 新同事入职:先看项目手册(AGENTS.md)
- 接具体任务:调用某个成熟 SOP(Skills)
这也是为什么我更愿意把“技能层”当成代理系统的核心:它是把个人经验变成组织能力的那一层。
入口层之争
终端、IDE、AI 浏览器这三类入口,本质上不是 UI 之争,而是谁在控制上下文的切片方式——模型最后吃进去的东西长什么样,80% 由入口层决定。
在争什么?
争的是“默认上下文”的主导权。你把 MCP/Skills 看成“驱动 + SOP”,那入口层就是操作台:它决定用户意图怎么被采样、外部信息怎么被归档、工具怎么被调用、风险动作怎么被拦截、日志怎么被审计。入口层做得越像“事件系统”,代理就越稳定;入口层越像“把一切揉成一坨文本”,代理就越容易漂移、越容易被注入。所以绝对话语权很重要,它直接会影响到模型输出质量(比如 Anthropics 收购了 Bun,将其作为 claude code 分发的运行时)。
终端:从字符流变成“结构化事件流”
原本终端并不适合做代理的入口:输出是字符洪水、上下文是滚动条、状态靠人脑记。但 Warp[8] 这类新终端的思路很明确:把“历史”做成 Blocks(有边界、可引用、可复用),把常用动作做成可搜索的命令面板与工作流,再加上 Agent Mode 直接在终端里委派任务。

Warp 自己把定位写得很激进:代理能跑交互式命令、能进 CLI 应用、能用 MCP、能结合代码库 embeddings。这句其实点破了终端入口的关键价值:终端天然就是“动作执行器”。你在 IDE 里改代码,最后仍要跑测试、跑构建、跑部署;把代理放进终端,等于直接把它放进“行动回路”。
但终端入口也天然危险:它离生产太近。Skills 规则建议里说“低自由度走窄桥”,终端就是最典型的窄桥场景——高危命令必须护栏(固定 flags、禁止自动 sudo、破坏性操作强制确认、输出要审计)。不然终端会成为最快的生产力,也会成为最快的事故制造机。
AI IDE 混战
IDE 这块也是大厂必争之地。主要有两个派系:VS Code fork 系(代表:Cursor、Windsurf、Antigravity 等),和自研系(代表 Zed)。IDE 也正在从“写代码的地方”变成“代理的调度台”,核心变化不在 UI,而在它如何结构化上下文与执行。
更通用地讲,AI IDE 这两年收敛出 4 个共性:
- 从光标中心到任务中心:以前 IDE 的单位是“文件/光标/函数”;现在的单位变成“任务(Task)”:目标、约束、计划、变更集、验证结果都作为一等对象被保存和展示。聊天只是入口,真正重要的是任务的生命周期管理。
- 从一次生成到闭环迭代:IDE 不再把模型当“代码生成器”,而是把它放进 Think–Act–Observe 循环:生成 → 修改多文件 → 跑测试/构建 → 读日志 → 再修。IDE 的价值是把这些动作变成可复用的工作流,而不是一堆零散对话。
- 从自由发挥到可控执行:IDE 开始显式引入“护栏”:权限、范围、危险操作确认、只读模式、变更审阅、可回滚。原因很现实:代理离仓库太近,一次误操作就能毁掉分支或泄漏秘密,所以必须默认可审计、可撤销、可控。
- 从单体助手到多代理协作:复杂任务开始拆成多个并行子任务:规划/实现/验证/文档/重构分工,甚至隔离工作区避免冲突。IDE 的角色更像“编排器”,而不是“更聪明的补全”。
IDE 的未来或许不取决于模型多强,而取决于它能否把仓库、命令、测试、diff、审计这些“工程事实”结构化,然后用 Skills/工具把它们串成稳定流程。

AI 浏览器:最通用的入口,也是最系统性的安全噩梦
浏览器入口的诱惑太大:网页是信息源,也是账号入口,还是表单与工作流本体。但问题也最硬:网页内容是“不可信输入”,而浏览器往往握着你的已登录会话。
Brave 对 Perplexity Comet 的研究把“间接提示词注入”讲得很直白:网页里藏的指令会混进模型输入,代理可能把网页当成“用户指令”,从而在你登录态里执行危险动作(Agentic Browser Security: Indirect Prompt Injection in Perplexity Comet[9])。
同类风险也可以拿来讨论 OpenAI Atlas 等 AI 浏览器:一旦“自动导航/代操作”可用,注入就从学术概念变成现实威胁。所以一个“通用 AI 浏览器”真正该长什么样?核心不是“更会点按钮”,而是把边界做成产品默认值:
- 明确的 agentic 模式:不能让用户在随便逛网页时“误入代操作模式”。
- 会话隔离:代理浏览和日常浏览分 Cookie jar / profile,减少“已登录全网”的爆炸半径。
- 最小权限 + 动作门禁:读邮件、发邮件、转账、授权、下载执行这类动作必须分级授权与二次确认。
- 输入分层:用户指令、网页内容、工具返回必须强分离(能追踪来源),否则注入永远防不住。 -** 可审计与可回放**:每一步点了什么、读了什么、提交了什么,都要能复盘;否则你很难在团队/企业里落地。
前面提到的“真核骨架 + 细菌模块”放到浏览器里也成立:浏览器必须是“真核骨架”(权限与隔离极强),上面再挂“细菌模块”(小技能、小工具、小 UI),否则复杂系统一定出大洞。
Skills 编写指南
上面扯了那么多,有些朋友可能已经云里雾里了,我们来点实际的,如何编写 Skills。
最小可行形态
Skill 之所以像个“小项目”,不像“提示词”,是因为它要同时服务三件事:召回、执行、审计。
Anthropic 仓库给的最小模板已经把重点写明白:一个 SKILL.md,前面是 name/description,后面才是说明和例子。官方文档也直接把“去看仓库例子”当作推荐路径(anthropics/skills[10])。
可以把它拆成三层理解:
- 召回层(retrieval / routing):Skill 的 description 不是装饰品,它是索引键。模型在“要不要启用某个 Skill”时,靠的不是你后面写的长篇步骤,而是这几行短文本能不能被语义命中。写得像 README 的那种 description,基本等于废技能。
- 执行层(procedure / orchestration):正文的步骤才是 SOP:怎么做、先后顺序、失败怎么回退、输出格式是什么。这里最重要的是减少歧义,让模型少自由发挥。
- 审计层(security / governance):技能是要被分享、安装、企业内分发的。那就一定要能回答:它会不会乱读文件?会不会外发数据?会不会越权调用工具?
这三层合在一起,Skill 才像一个“可上架的模块”,而不是一次性的 prompt。
skill-creator 脚手架
Anthropic 仓库里明确有一个 skill-creator[11],用于“指导你创建有效的 skills”。
社区教程也普遍把它当作入门路径:让 Claude Code 先按规范搭骨架,再由人做收敛和安全边界。你可以把它理解成:把“如何写出能被召回、能执行、能审计的 SKILL.md” 这件事本身,做成一个 Skill。
这很符合“工具链自举”的思路:先把生产流程标准化,然后再谈规模化分发。

Skill 编写规则
把 Skill 当成“长 prompt 存档”是最常见的死法;更靠谱的心智模型是:它是一份产品级 SOP(说明书)+ 风险控制(护栏)+ 确定性锚点(脚本/工具)。目标不是写得“全”,而是让它好触发、好执行、好验收、好回滚、可复盘。
先赢在“能被选中”
description 是索引键,不是文案。
Skill 是否会被触发,八成都取决于 description。它不是宣传语,而是模型检索与路由的索引键,写法要像“检索广告牌”:一句话说清楚做什么 / 何时用 / 何时不用 / 输出是什么,并尽量包含可观测的触发信号(例如“用户提供 stack trace、diff、CSV、PDF、报表链接、日志片段”等)。description必须第三人称,因为它会进入系统侧的技能索引与选择环节,视角写错会影响发现与选择。避免宽泛词(“帮你写代码”、“提高效率”、“万能助手”),这种描述要么导致误触发,要么根本触发不了;宁可窄一点,也不要虚。
控制上下文成本
正文不是越长越强,越长越像噪声。
技能正文越长越像在给模型喂安眠药:看起来全,实际上亏——Token 被吃光、相关性被稀释、模型在噪声里误触发、误执行、输出漂移。经验上 SKILL.md 正文建议控制在 500 行以内,接近就拆。把 SKILL.md 当成“目录 + 关键规则”的入口页,只放最重要的 20%:触发条件、核心步骤、关键护栏、输出模板。其余细节拆到 REFERENCE.md / EXAMPLES.md / EDGE_CASES.md / CHECKLIST.md 等文件,通过“目录式导航”让模型按需再读。这就是渐进式披露:不是一次把所有东西塞进上下文,而是先读到够用为止,需要更多再精确加载,降低噪声也降低成本。
把正文写成可执行 SOP
步骤、检查点、回滚、验收。
Skill 正文不要写散文,要写“可执行流程”。最稳的结构是:先给一个总览,再给步骤。每一步明确输入输出、顺序和条件分支(if/else),不要让模型现场发明流程。写流程时必须包含四件事:步骤(Steps)、检查点(Checks)、失败回滚(Rollback)、输出格式(Output Format)。检查点是为了把漂移压下去:每完成一步就验证输入/输出是否符合预期,不符合就停。回滚是为了让 Skill 不会“越做越错”:失败时撤销什么、如何恢复现场、如何留下可复盘记录。输出格式尽量结构化(JSON/表格/固定字段),最好给一个模板,让模型照着填,避免格式漂移。再加一个容易被忽略但非常关键的段落:停止条件与升级策略(Stop Conditions / Escalation)——当权限不足、输入缺失、风险动作将发生、结果不确定时,必须停下来问用户,而不是硬编继续跑。
把“不可赌的部分”交给确定性工具
脚本是技能的锚。
LLM 是概率系统,最擅长的是编排与判断,不擅长的是“绝对正确”。凡是不可赌的部分——解析、提取、计算、对账、格式化、渲染、批量改写、生成报表——都应尽量交给脚本/确定性工具,尤其在财务、法务、运维这些容错率极低的场景,否则迟早被坑。正确姿势是:模型负责选择路径、调用工具、解释结果、组织交付物;脚本负责产出确定结果。脚本最好做成 CLI 风格(入参明确、输出稳定:stdout 或写文件),这样方便被 Host 调用,也方便做回归测试与复现。你写 Skill 的时候要明确告诉模型:什么时候必须先跑脚本、脚本输出在哪、要读哪个文件再继续、如果脚本失败怎么处理。
自由度是可靠性的旋钮
失败往往不是能力不够,而是自由度给错了。
很多代理系统看似“模型不行”,其实是自由度给错了。同样让模型做事,你要决定它走“开阔草地”还是走“悬崖窄桥”。流程脆弱、容易出事故、顺序固定的任务应该低自由度:精确命令、少参数、固定 flags、明确禁止项(不得跳步、不得改配置、不得联网、不得写外部系统)、每步有检查点与验收。开放式判断、需要权衡、需要探索的任务可以高自由度:给目标、给边界、给评估标准,允许多方案但必须输出对比与选择理由,同时仍要有停止条件和风险动作确认。更实用的做法是“分段自由度”:先低自由度拿到确定事实(提取/校验/对账),再高自由度做判断(总结/建议/方案选择)。这样最稳:先把地基钉死,再允许发散。
边界要可执行
把风控写进技能,而不是写进“提醒语气”。
风险控制不能靠“请谨慎”、“注意安全”这种语气,它必须变成可执行规则。Skill 若涉及敏感数据或高风险动作,建议在正文里明确写出:权限边界(能读哪些路径、能用哪些工具、是否允许联网)、数据外发规则(哪些字段必须脱敏、哪些内容绝不外发)、二次确认点(删除、提交、支付、授权、发信等必须显式确认)、审计输出要求(必须输出做了什么、用了哪些输入、生成了哪些文件、改了哪些地方)。这不仅是安全,也是工程可维护性:出了问题能复盘、能定位、能修复。
写成“可维护资产”
版本、示例、回归、变更记录。
技能一旦开始被复用,它就不再是 prompt,而是资产。资产就要可维护:给出版本号或变更记录、提供最小可复现示例(几组典型输入与期望输出)、用 checklist 固化验收点、把边界案例单独列出来。现实里最容易坏的是“输入漂移”:数据格式变了、系统界面改了、日志结构变了、字段命名变了。你提前准备好示例和回归点,Skill 才能在迭代中不退化。
最实在的标准
它能不能被别人“顺手牵羊”并立刻见效。
一个 Skill 写得好不好,可以用非常朴素的标准测试:另一个开发者能否在几分钟内把它拿走(复制文件夹)、不引入一堆依赖、不需要大量上下文,就能跑起来并获得收益?能做到这一点,说明你的索引写对了、流程写清楚了、依赖收敛了、边界立住了、交付可验收了。做不到,通常不是因为你写得不够多,而是写得不够“可执行”。
小结
以上这些规则合在一起,其实就一句话:Skill 不是“你对模型说的话”,而是“你为模型搭的环境与规矩”。只要你始终围绕“触发稳定、执行确定、风险可控、结果可验收”去写,技能自然会从小白可用走向资深可维护。
OpenAI Skill
OpenAI 在 ChatGPT 内部已使用 Skill,也包括在 Codex(github codex/skills[12])。
你可以在 ChatGPT 中发送 Create a zip file of /home/oai/skills 打包下载 skills(防止失效,我已在 github 中备份,需要的朋友自取 oai-skills[13])。

Skill 部分说明
在 ChatGPT 中的这份 Skills 中,共包含 28 个文件,我选了两个比较典型的文件,来简单分析下。
oai-skills
|-- docs
| |-- render_docx.py
| `-- skill.md
|-- pdfs
| `-- skill.md
`-- spreadsheets
|-- artifact_tool_spreadsheet_formulas.md
|-- artifact_tool_spreadsheets_api.md
|-- examples
| |-- create_basic_spreadsheet.py
| |-- create_spreadsheet_with_styling.py
| |-- features
| | |-- change_existing_charts.py
| | |-- cite_cells.py
| | |-- create_area_chart.py
| | |-- create_bar_chart.py
| | |-- create_doughnut_chart.py
| | |-- create_line_chart.py
| | |-- create_pie_chart.py
| | |-- create_tables.py
| | |-- set_cell_borders.py
| | |-- set_cell_fills.py
| | |-- set_cell_width_height.py
| | |-- set_conditional_formatting.py
| | |-- set_font_styles.py
| | |-- set_merge_cells.py
| | |-- set_number_formats.py
| | |-- set_text_alignment.py
| | `-- set_wrap_text_styles.py
| |-- read_existing_spreadsheet.py
| `-- styling_spreadsheet.py
|-- skill.md
`-- spreadsheet.md
6 directories, 28 files
pdfs/skill.md
这份 skill 的核心是在规定一套“以渲染结果为准”的 PDF 工作流:不把 PDF 当文本,而把它当“需要肉眼验收的版面输出”,用图像渲染 → 逐页检查 → 修正 → 再渲染的闭环来保证质量。
关键要点总结:
- 读 PDF 的首选路径:先用
pdftoppm -png把 PDF 渲染成 PNG,再读图片内容;pdfplumber只能当补充。Python 的纯文本提取是最后手段,因为会丢图表/版式/表格等关键信息。 - 生成 PDF 的首选工具:优先用
reportlab程序化生成;其他库可用但可能要额外安装。 - 核心质量机制:每次“有意义的修改”后都要
pdftoppm渲染成 PNG 并逐页检查;任何版式问题都必须回到源文件修复,直到 PNG 里“干净无缺陷”才算过关。 - 质量标准(偏排版审美+可读性):统一字体/间距/边距/配色/分隔;不能有裁切、重叠、黑块、破表、乱码;图表清晰且标签可读;文本避免堆砌与密集无结构列表,靠留白组织信息。
- 硬性禁忌与交付规范:不要用 U+2011 等特殊破折号(会渲染异常),用 ASCII
-;引用/脚注必须是人能读的正式格式,严禁把工具内部 token(如 ``)塞进最终 PDF。 - 最终验收:在“最新一次 PNG 检查确认零缺陷”前不允许交付;同时检查页码、页眉页脚、章节过渡,并把中间产物命名/清理到审阅者好导航的程度。
# PDF reading, creation, and review guidance
## Reading PDFs
- Use `pdftoppm -png $OUTDIR/$BASENAME.pdf $OUTDIR/$BASENAME` to convert PDFs to PNGs.
- Then open the PNGs and read the images.
-`pdfplumber` is also installed and can be used to read PDFs. It can be used as a complementary tool to `pdftoppm` but not replacing it.
- Only do python printing as a last resort because you will miss important details with text extraction (e.g. figures, tables, diagrams).
## Primary tooling for creating PDFs
- Generate PDFs programmatically with `reportlab` as the primary tool. In most cases, you should use `reportlab` to create PDFs.
- If there are other packages you think are necessary for the task (eg. `pypdf`, `pyMuPDF`), you can use them but you may need topip install them first.
- After **each meaningful update**—content additions, layout adjustments, or style changes—render the PDF to images to check layout fidelity:
-`pdftoppm -png $INPUT_PDF $OUTPUT_PREFIX`
- Inspect every exported PNG before continuing work. If anything looks off, fix the source and re-run the render → inspect loop until the pages are clean.
## Quality expectations
- Maintain a polished, intentional visual design: consistent typography, spacing, margins, color palette, and clear section breaks across all pages.
- Avoid major rendering issues—no clipped text, overlapping elements, black squares, broken tables, or unreadable glyphs. The rendered pages should look like a curated document, not raw template output.
- Charts, tables, diagrams, and images must be sharp, well-aligned, and properly labeled in the PNGs. Legends and axes should be readable without excessive zoom.
- Text must be readable at normal viewing size; avoid walls of filler text or dense, unstructured bullet lists. Use whitespace to separate ideas.
- Never use the U+2011 non-breaking hyphen or other unicode dashes as they will not be rendered correctly. Use ASCII hyphens instead.
- Citations, references, and footnotes must be human-readable and professional. No tool-internal tokens (e.g., `[145036110387964†L158-L160]`), malformed URLs, or placeholder text should be present in the document.
- You must convert all citations into a human-readable format in the document with standard scholarly citation format. No `【【turn1541736113682297662view0†L11-L19】` notations are allowed in the document as the reader cannot interpret them (such citations will be severely penalized).
- Correct every formatting defect you see in the PNGs, including but not limited to: overlapping text or shapes, clipped text or shapes that are cut off, black squares, broken tables, unreadable characters, etc.
## Final checks
- Do not ship the PDF until the latest PNG inspection shows zero visual or formatting defects. Confirm page numbering, headers/footers, and section transitions look polished.
- You must resolve any issues you spot (typos, spacing, alignment, color contrast) and re-render for a final verification pass before submitting.
- Keep intermediate PNGs/PDFs clearly labeled or cleaned up so reviewers can navigate the outputs easily.
spreadsheets/skill.md
这份 Spreadsheet Skill 的核心,是把“做表”当成一条可验证、可复现、可交付的工程流程,而不是随手改几格。它强调三件事:工具链选择、公式可靠性、样式与审计。
1) 适用范围:做表不是只写数据,而是“创建/改造/分析/可视化/重算”
触发场景很广:新建工作簿、读数据做聚合/透视/指标、在不破坏既有公式引用的前提下改表、做图表与排版、以及修改后必须确保计算结果更新。
2) 工具策略:编辑用 openpyxl,验收用“可重算 + 可渲染”的内部工具
- 可以用 openpyxl 或 artifact_tool 来创建/编辑。
- 但核心要求是:交付前必须重算公式并缓存结果(cached values),并尽量把每个 sheet 渲染成图片逐页检查排版与正确性。
- 重要限制:artifact_tool 是内部环境用来重算/渲染/验收的,不应对用户暴露;最终给用户的代码示例只能用 openpyxl / pandas。
一句话:你可以用 openpyxl 改,但必须用“能重算+能渲染”的手段验收,确保交付文件在用户 Excel 里打开就是对的。
3) 公式是硬约束:派生值必须用公式,且要“可维护、可复制、可重算”
- 所有派生值必须用公式,不能硬编码。
- 明确禁用一类功能:动态数组函数(如 FILTER / XLOOKUP / SORT / SEQUENCE),因为兼容性与工具支持存在风险,可能导致用户端不可用。
- 公式写法强调“工程可维护性”:拆中间项、避免易炸的易失函数(INDIRECT/OFFSET)、正确使用绝对/相对引用、不要魔法数(用输入单元格引用)、处理以
=开头但需要当文本的情况(加')。 - 交付前要保证:没有公式错误(#REF!/DIV0!/VALUE!/N/A/NAME?)、没有意外循环引用、并用边界输入做 sanity check。
特别关键的一条:openpyxl 保存的公式默认没有缓存计算结果,所以必须通过重算把结果写进文件,否则用户打开时可能看到旧值/空值/未更新结果。
4) 质量检查:不是“我觉得对”,而是“重算+渲染后看起来也对”
它要求把“检查”流程制度化:
- 重算并处理警告/异常单元格
- 渲染每个 sheet 的 PNG 检查:样式、对齐、溢出、可读性、是否有误格式
- 先重算再渲染(否则渲染出的结果可能不是真实最终值)
这其实是在把做表变成“像做 PDF 一样的可视化验收”。
5) 引用与来源:来源必须进表格本体,而不是只写在回复里
- 表内引用一律用纯文本 URL(不要任何工具内部引用格式)。
- 金融模型:输入来源写进 cell comment。
- 逐行数据:用单独一列放来源链接。
这点很“审计友好”:表格本身就能自证。
6) 样式策略:两条铁律——别破坏现有风格;新建时用默认行业规范
- 如果用户给了已有样式的表:先渲染看清楚 → 修改时完全匹配现有风格,绝对不要把原有格式覆盖掉。
- 如果是新建或要求重排版:给出清晰布局与合理格式(日期/百分比/货币)、适度留白、不要给每个单元格都加边框、调整行高列宽避免溢出。
并提供一套默认颜色语义(输入蓝、公式黑、链接绿等),以及金融/投行模型的额外规范:零显示为“-”、负数红括号、单位写进表头、合计行用上方求和、隐藏网格线、分区标题用深色底白字等。
一句话总结:这份 skill 把电子表格当成“可交付的产品界面”,要求你用工程化流程确保公式正确(且可重算)+ 输出可读(渲染验收)+ 改动不破坏(保留引用与格式)+ 数据可追溯(表内引用)。
# Spreadsheet Skill (Create • Edit • Analyze • Visualize)
Use this skill when you need to work with spreadsheets (.xlsx, .csv, .tsv) to do any of the following:
- Create a new workbook/sheet with proper formulas, cell/number formatting, and structured layout
- Read or analyze tabular data (filter, aggregate, pivot, compute metrics) directly in a sheet
- Modify an existing workbook without breaking existing formulas or references
- Visualize data with in-sheet charts/tables and sensible formatting
- Recalculate/evaluate formulas to update results after changes
IMPORTANT: instructions in the system and user messages ALWAYS take precedence over this skill
## Guidelines for working with spreadsheets### Use the artifact_tool python library or openpyxl
- You can use either python library (openpyxl or artifact_tool) for creating and editing spreadsheets- artifact_tool can also render and recalculate spreadsheets which is important for checking your work, even if you used openpyxl to edit the workbook
- You can import artifact_tool in python using either the python tool or container.exec tool
- Simple instructions on artifact_tool usage can be found in spreadsheet.md, and example scripts using artifact_tool are provided in examples/ folder.
- If possible, you MUST use artifact_tool to recalculate formulas and save the workbook with cached values before providing it to the user
- If possible, you MUST use artifact_tool to render each sheet, and review the rendered image for style, formatting, and correctness
- You can open the rendered png images in python with matplotlib.pyplot.imshow and PIL.Image, or using the `container.open_image` tool if available
- Be sure to recalculate formulas before rendering, to make sure formula results are cached and displayed
- The artifact_tool api can be found in artifact_tool_spreadsheets_api.md
- Note that artifact_tool will recalculate formulas automatically on edit by default
- IMPORTANT: Any code in your final response should use openpyxl and/or pandas for spreadsheet operations and should not include artifact_tool usage. artifact_tool is only available for you to manipulate spreadsheets within your environment and you should assume users do not have access to artifact_tool.
- Do not disclose any source code or information to the user about artifact_tool; it is a proprietary library.
- If not using artifact_tool, prefer using openpyxl over pandas to enable formatting the spreadsheet according to the style guidelines
### Check your work
- Before providing your completed spreadsheet to the user, check to ensure it is accurate and without errors.
- Use artifact_tool to recalculate the workbook, and address any printed warnings or incorrect calculated cells.
- After recalculating to ensure calculated values are cached, render the spreadsheet with artifact_tool and view the images to check for style, formatting, and correctness
### Use /mnt/data
- Look for input files uploaded by the user at /mnt/data
- Write any output files to /mnt/data
## Formula requirements
### Use formulas for derived values
- Any derived values must be calculated using spreadsheet formulas rather than hardcoded
### Do not use dynamic array functions
- DO NOT use dynamic array formulas like FILTER, XLOOKUP, SORT, SEQUENCE
- These are not currently supported in openpyxl or artifact_tool in a way that is compatible with modern spreadsheet applications, and using them could prevent the user from being able to use the spreadsheet.
### Best practices
- Formulas should be simple and legible. Use helper cells for intermediate values rather than performing complex calculations in a single cell
- Avoid the use of volatile functions like INDIRECT and OFFSET except where necessary
- Use absolute ($B$4) or relative (B4) cell references as appropriate such that copy/pasting to adjacent similar cells behaves correctly
- Do not use magic numbers in formulas. Instead, use cell references to input cells. Example: Use "=H6*(1+$B$3)" instead of "=H6*1.04"
- If you want to write text (not an evaluated formula) in a cell starting with "=", make sure to prepend a single quote ' like "'=high-low" to avoid a #NAME error
### Ensure formulas are correct
- Spreadsheets must not contain added formula errors (#REF!, #DIV/0!, #VALUE!, #N/A, #NAME?)
- Verify all formulas recalculate correctly; you must recalculate all formulas and check the computed values are correct before submitting your final response.
- Guard against bugs in formulas:
- Verify correct cell references
- Check for off-by-one errors
- Test by varying inputs with edge cases
- Verify no unintended circular references
### Ensure calculated values are cached
- When using openpyxl, formulas will not be cached in the saved workbook
- Ensure they are calculated without errors and cached before providing the spreadsheet to the user, for example by loading with artifact_tool, calling recalculate(), and overwriting the xlsx file
## Citation requirements
### Cite sources within the spreadsheet
- Always cite your sources using plain text URLs. Do not use any special citation formats within spreadsheets, only in your final response.
- For financial models, cite sources of model inputs in the cell comment
- For tabular data researched from the web or other sources where each row represents one item, cite sources in a separate column
## Formatting requirements when provided a formatted spreadsheet as part of the task
### Preserve existing formatting and style
- Always render a provided spreadsheet before modifying it to see what it looks like
- Carefully examine and EXACTLY match the existing formatting and style when modifying spreadsheets
- When modifying cells in a provided spreadsheet that were previously blank and unformatted, determine how to format them to match the style of the provided spreadsheet
- Never overwrite formatting for spreadsheets with established formats
## Formatting requirements when not provided a formatted spreadsheet or when explicitly asked to reformat without any formatting guidelines
### Choose appropriate number and date formats
- Dates should have an appropriate date format and should not be numbers ("2028", not "2,028")
- Percentages should default to one decimal point (0.0%) unless it does not make sense for the scale and precision of the data
- Currencies should always have an appropriate currency format ($1,234)
- Other numbers should have an appropriate number of digits and decimal places
### Use a visually clear layout
- Headers should be formatted differently from data and derived cells to distinguish them with a consistent visual styel
- Use fill colors, borders, and merged cells judiciously to give the spreadsheet a professional visual style with a clear layout without overdoing it
- Set appropriate row heights and column widths to give a clean visual appearance; contents of cells should be readable within the cell, without excessive buffer space
- Do not apply borders around every filled cell
- Group similar values and calculations together, and aim to make totals a simple sum of the cells above them.
- Add strategic whitespace to separate sections
- Ensure cell text does not spill out to other cells by using appropriate cell dimensions and fonts
For example, in an income statement with revenue, cost of sales, and gross profit across 3 verticals where each column is a different calendar year, below the header row should be the income for each vertical, followed by the total (label in bold), followed by a blank row, and then similar for cost of sales and gross profit.
### Avoid unsupported features
- Do not attempt to create a data table, it is not supported
- Do not use `=TABLE`
### Use standard color conventions for text colors:
If the user does not provide color specifications and the user does not provide a styled workbook
- Blue: User input
- Black: Formula / derived
- Green: Linked / imported
- Gray: Static constants
- Orange: Review / caution
- Light red: Error / flag
- Purple: Control / logic
- Teal: Visualization anchors; highlight key KPI or chart driver
### Additional requirements for financial models
- Make all zeros formatted as "-"
- Negative numbers should be red and in parentheses; (500), not -500. In Excel this might be "$#,##0.00_);[Red]($#,##0.00)"
- For multiples, format as 5.2x
- Always specify units in headers; "Gross Income ($mm)"
- All added raw inputs should have their sources cited in the appropriate cell comment
#### Finance-specific color conventions:
When building new financial models where no user-provided spreadsheet or formatting instructions override these conventions, use:
- **Blue text (RGB: 0,0,255)**: Hardcoded inputs, and numbers users will change for scenarios
- **Black text (RGB: 0,0,0)**: ALL formulas and calculations
- **Green text (RGB: 0,128,0)**: Links pulling from other worksheets within same workbook
- **Red text (RGB: 255,0,0)**: External links to other files
- **Yellow background (RGB: 255,255,0)**: Key assumptions needing attention or cells that need to be updated
### Additional requirements for investment banking
If the spreadsheet is related to investment banking (LBO, DCF, 3-statement, valuation model, or similar):
- Total calculations should sum a range of cells directly above them.
- Hide gridlines. Add horizontal borders above total calculations, spanning the full range of relevant columns including any label column(s).
- Section headers applying to multiple columns and rows should be left-justified, filled black or dark blue with white text, and should be a merged cell spanning the horizontal range of cells to which the header applies.
- Column labels (such as dates) for numeric data should be right-aligned, as should be the data.
- Row labels associated with numeric data or calculations (for example, "Fintech and Business Cost of Sales") should be left-justified. Labels for submetrics immediately below (for example, "% growth") should be left-aligned but indented.
题外话
从 ChatGPT 下载 skills 的技巧是在 Simon blog 中发现的(OpenAI are quietly adopting skills, now available in ChatGPT and Codex CLI[14])。他本人 blog 有很多有价值的内容,比如 HTML Tools[15]。
我之前的文章也有过类似描述,但他直接把 HTML tools 进行了落地:它不是新框架,而是一种极低摩擦的交付形态——把 HTML + JS + CSS 塞进一个文件里,随手复制粘贴就能跑,他自己两年做了 150+ 个,几乎都由 LLM 写出的(github simonw/tools[16])。
我大概提炼了他的一些有价值观点:
- 单文件 + 无构建步骤:越少依赖越好,最好别碰 React/JSX 那套,因为一旦引入 build step,传播和复用的成本会暴涨。
- 依赖用 CDN 直接拉:能省就省,但真要用库就从 cdnjs/jsdelivr 之类加载固定版本,换取“拷贝即用”。
- 工具要小:几百行最舒服——LLM 读得完、你也改得动,甚至重写都很快,维护成本被压到最低。
- 别把它们关在 LLM 平台的沙盒里:平台内置 artifacts 往往受限(外链、加载资源、跳转),还不稳定;静态托管(GitHub Pages 等)更可靠、更像“真正工具”。
- 把“复制/粘贴”当成一等交互:输入从剪贴板来、输出回剪贴板去,甚至利用富剪贴板格式(不仅是 text/plain)来做更强的转换工作流。
- 状态存 URL / localStorage:URL 适合书签化与分享;localStorage 适合更大状态或不想落到服务器日志里的秘密(例如 API key)。
- CORS API 是金矿:能跨域直接 fetch 的公开 API 特别适合做这种小工具;甚至可以直接从浏览器调用主流 LLM 的 JSON API(同样受 API key 暴露问题约束)。
- “打开文件/导出文件”是标配能力:别害怕做本地文件导入,也可以直接生成可下载文件,把工具变成“轻量处理站”。
- Pyodide / WebAssembly 打开上限:浏览器里能跑 Python、能跑一堆 WASM 封装库,意味着“离线、单文件、但能力很硬”的工具是可行的。
- 复用旧工具(remix)比从零写更稳:已有工具的源码本身就是“可执行文档”,把一两个同类工具塞进上下文,LLM 更容易产出可工作的新工具。
- 记录 prompt 与 transcript:他强调把构建过程留痕(链接到源码、提交记录、对话记录),这会让“工具资产”可追溯、可复刻、可迭代。
如果把它塞回到前面那套 MCP/Skills 叙事里,HTML tools 的启示其实很直接:Skills 解决“怎么做”,HTML tools 提供“怎么交付/怎么呈现”——尤其适合把分析结果变成一个可点可验的微型界面(而不是一坨解释文本),这或许就是“从回答到交付物”的那一步吧...
References
[1]
Introducing Agent Skills:https://claude.com/blog/skills
[2]
Equipping agents for the real world with Agent Skills:https://www.anthropic.com/engineering/equipping-agents-for-the-real-world-with-agent-skills
[3]
AGENTS.md:https://agents.md
[4]
langchain python/tools:https://docs.langchain.com/oss/python/langchain/tools
[5]
Agentic AI Foundation:https://www.linuxfoundation.org/press/linux-foundation-announces-the-formation-of-the-agentic-ai-foundation
[6]
goose:https://github.com/block/goose
[7]
JSON-RPC 2.0:https://www.jsonrpc.org/specification
[8]
Warp:https://www.warp.dev
[9]
Agentic Browser Security: Indirect Prompt Injection in Perplexity Comet:https://brave.com/blog/comet-prompt-injection
[10]
anthropics/skills:https://github.com/anthropics/skills
[11]
skill-creator:https://github.com/anthropics/skills/tree/main/skills/skill-creator
[12]
github codex/skills:https://github.com/openai/codex/blob/main/docs/skills.md
[13]
oai-skills:https://github.com/lencx/ai/tree/main/oai-skills
[14]
OpenAI are quietly adopting skills, now available in ChatGPT and Codex CLI:https://simonwillison.net/2025/Dec/12/openai-skills
[15]
HTML Tools:https://simonwillison.net/2025/Dec/10/html-tools
[16]
github simonw/tools:https://github.com/simonw/tools
