ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Skill.md与llms.txt:AI工作流中两类Markdown文件的本质区别与落地配置

Skill.md与llms.txt:AI工作流中两类Markdown文件的本质区别与落地配置 不少人在搭建 AI 工作流、做个人知识库、给模型写“使用说明”的时候都会遇到两个很像的文件名Skill.md和llms.txt。它们都是 Markdown 文件都跟大模型有关名字也都短很容易被当成同一个东西。但实际上这两个文件解决的是完全不同的问题一个负责告诉模型“这个站点有哪些内容可以看”另一个负责告诉模型“你接下来可以执行哪些技能”。这篇文章先把两者的定位分开再讲落地时怎么选、怎么配、怎么验证。我更建议大家先别急着往项目里塞文件而是先搞清楚一件事你写的这份说明到底是给谁看的。给访客看和给执行器看写法和存放位置完全不一样。1. 先分清两件事你写给谁看对方拿它做什么1.1 llms.txt 是给访问者看的“站点索引”llms.txt 最早的设计思路很像一个“面向大模型的 robots.txt”。robots.txt 是告诉搜索引擎爬虫哪些页面可以访问而 llms.txt 是告诉大模型或者 AI 代理当前这个站点主要是什么主题、有哪些关键页面、每个页面大概讲了什么。常见的 llms.txt 结构并不复杂一般会包含几个部分站点名和一句话简介对站内资源的简要分类重要页面的 URL 列表每个 URL 后面带一句说明可选的补充说明比如内容更新频率、使用授权范围、是否有 API我用一个相对典型的例子来展示# Example Docs Example 团队的技术文档站点主要覆盖 SDK 接入、API 参考和最佳实践。 ## 入门 - [快速开始](https://example.com/docs/quickstart)5 分钟内完成 SDK 安装与初始化 - [鉴权方式](https://example.com/docs/auth)介绍 Token 和 API Key 两种鉴权方式 ## API 参考 - [REST API](https://example.com/docs/api)所有接口列表、参数说明和示例响应这个文件的核心作用是让一个第一次访问站点的 AI 代理不用靠全文扫描就能快速判断“这个站点是否包含我要找的信息”并且直接拿到相关链接。它保存的是一种发现信息不是操作指令。所以你在实际使用时会发现llms.txt 的内容基本是静态的。它跟着内容更新但它不决定模型怎么做事情。哪怕文件写得很华丽模型也只把它当成一个入口。1.2 skill.md 是给执行模型看的“技能说明书”Skill.md 的定位完全不同。它不是给外部访客看的东西而是给 AI 代理或助手内部使用的行为定义文件。它描述的是“你现在具备哪些技能、每个技能在什么条件下触发、触发之后按什么步骤执行、输入是什么、输出是什么”。不同框架对这类文件的叫法不完全一样。有些叫 skill有些叫 tool definition有些叫 plugin manifest还有些叫 knowledge。但本质一致让模型知道可以调用哪些能力以及调用时要遵循什么规则。一个典型的 skill.md 会比 llms.txt 更强调流程和边界# Skill: 代码仓库变更摘要 ## 描述 当用户要求“总结最近提交”“查看代码变更”“生成 changelog”时使用本技能。 ## 输入参数 - repo_path目标仓库路径 - since起始提交号或日期可选 - until结束提交号或日期可选 ## 执行步骤 1. 进入 repo_path 对应仓库 2. 执行 git log 获取 since 到 until 之间的提交记录 3. 按提交信息分类输出变更摘要 ## 输出格式 Markdown 列表包含提交号、提交时间、提交说明和变更类型。 ## 边界 - 不执行任何代码修改操作 - 不访问网络 - 仓库路径不存在时直接报错不要猜测路径看到区别了吗llms.txt 回答的是“这里有什么”skill.md 回答的是“你能做什么、怎么做”。1.3 两个文件最核心的差异如果只用一句话区分我会这样说llms.txt 是资源清单帮助模型找到内容。skill.md 是能力声明帮助模型执行操作。前者更像是图书馆门口的索引牌后者更像是一份操作手册。索引牌告诉你哪本书放在哪个架子操作手册告诉你怎么使用里面的工具。两者都重要但它们不是同一个层面的东西。这也解释了为什么很多人总搞混因为它们都可能叫“md”结尾的文件都可能放在项目根目录或知识库目录里。但如果写反了问题会很明显模型可能会把技能定义当成文档内容朗读出来或者把站点索引当成可执行的指令去“访问”一个并不存在的技能。2. llms.txt 落地时最容易踩空的几个位置2.1 文件位置、命名与按 UTF-8 保存先说最基础的。llms.txt 这个文件名是约定俗成的一般放在站点根目录或内容仓库的根目录。如果你放在子目录里或者改名叫 llm.txt、llms-info.txt很多读取程序默认情况下就找不到了。保存编码建议使用 UTF-8 无 BOM。这个细节很容易被忽略但有些解析器在遇到带有文件头标记的内容时会把第一个标签当作正文的一部分导致站点标题显示乱码。我一般会检查三件事文件名是否严格是 llms.txt路径是否为站点根目录文件是否 UTF-8 编码如果你用的是静态站点生成器比如 Hugo、VitePress 这类工具不要只在源目录里写一个 llms.txt要确认构建之后它是否被复制到了输出根目录。很多人的问题不是内容写错而是发布后根目录里根本没有这个文件。2.2 条目内容该写多细llms.txt 的链接列表不是简单的 URL 堆砌。模型读链接时需要知道这个链接背后是什么。所以在每一条链接后面写一个简短的用途说明比写一百个裸链接更有效。我的经验是一条链接的说明控制在 15 到 40 个字左右。太短比如只写“API 文档”模型仍然不知道怎么用太长比如把整篇文章摘要都塞进去又会让整个文件变得臃肿模型反而忽略后面的条目。可以按主题分组。分组标题用 Markdown 的二级或三级标题都可以关键是分类要让读取者一眼看清。比如分成“入门指南”“API 参考”“最佳实践”“常见错误”不同场景下模型会更快定位到自己需要的部分。另外链接地址尽量用完整 URL不要用相对路径。因为读取 llms.txt 的可能是外部代理它不一定知道你站点的域名是什么。如果用的是相对路径它可能拼接错。2.3 怎么确认模型真的读到了加入文件之后不是部署上去就结束了。你需要一种办法验证模型“是否识别”这个文件。常用的验证思路有几种让模型概括站点内容看它的描述是否来自你写在 llms.txt 里的站点简介让模型列举站点包含哪些资源看它是否只提到了文件里列出的链接查看代理日志里是否出现了对 llms.txt 的抓取记录我做测试时一般会先构建一个只有三到五个链接的小站点然后让支持该协议的代理直接访问问它“你在这个站点看到了哪些文档”。如果回答和文件内容一致说明解析正常如果回答混乱、提到文件里根本没有的页面或者直接说找不到内容那就要先排查文件能否被公开访问。一个容易被忽略的问题本地文件没问题但部署后通过域名访问 llms.txt 返回了 403 或 404。这就不是文件内容问题而是服务器配置问题。此时先 curl 一下这个地址看返回状态码。2.4 不是加了文件就等于被所有模型收录这里需要明确一点llms.txt 目前是一个社区实践不是所有大模型或所有搜索代理都一定读取它。你可以把这个文件理解为“给愿意支持它的读者准备的说明”而不是一个强制标准。我在实际推荐时通常会说如果你的站点是公开文档站、知识库或内容聚合站那么建立一个 llms.txt 是有价值的因为越来越多的代理工具会在访问站点时先寻找这个文件。但如果你是在内部系统里给模型喂文件那么它是否读取 llms.txt完全取决于你使用的工具链是否实现了这个逻辑。所以要验证而不是假设。先确认你用的模型或代理确实会读这个文件再决定要不要花力气维护。3. skill.md 的定义方式和执行边界3.1 同一个文件在不同框架里的角色Skill.md 没有一个全球统一的标准。不同产品对它的解析方式、目录位置、命名规则都不一样。有些框架会在固定目录下扫描所有skill.md文件只要文件名匹配就自动加载。有些框架要求每个技能一个独立目录目录里除了 skill.md 还需要一个可执行的配置或脚本。还有些框架会把 skill.md 直接嵌入系统提示词要求模型阅读后自行理解能力边界。所以不要在没确认框架文档之前直接照搬别人的目录结构。我在看项目时经常发现两个项目都叫 skill.md但一个放在.agent/skills/下一个放在prompts/skills/下。它们的加载逻辑完全不同。如果你使用的是通用 AI 编程助手或内容生成工具并且它支持自定义 skill那么官方文档里通常都会写明推荐放置路径。如果文档没写可以看日志里是否会输出“loaded skills”之类的提示。3.2 一个能正确触发的 skill 通常包含哪些字段尽管格式不统一但一个能稳定被模型识别的 skill 文件通常会包含以下几类字段技能名称简短避免和别的技能重名描述什么时候使用、触发条件是什么参数输入有哪些、类型是什么、是否必填执行步骤按顺序写清楚输出格式模型生成结果时要遵循的格式限制条件哪些操作不能做哪些情况要停止还有一点很重要描述里要写“什么时候不用”。比如一个技能只处理 Git 变更记录那我就会在描述里写明“不要用于代码生成不要用于文件打包”。因为模型在判断是否调用技能时看的主要就是这段描述。描述越模糊误触发率越高。3.3 “# 号后面是不是不执行”到底怎么理解这个困惑非常典型有不少人问“skill.md 里面 # 后面的内容是不是不执行”。我理解大家为什么会这么想因为很多配置文件、脚本文件里# 开头的行是注释注释不会被解释器执行。所以有人推断Markdown 里 # 后面的内容也不应该被加载。这个判断只在特定情况下成立。先看一个事实在标准 Markdown 语法里#是标题标记不是注释。它后面的文字是标题内容会被正常渲染和读取。也就是说如果你在一个普通 Markdown 文件里写# 技能名称这个名称是会被解析出来的。再看不同解析器的行为有些框架在读取 skill.md 时会先按 Markdown 分块把#一级标题识别为技能名称把##二级标题识别为字段区块。这种情况下#后面不是不执行而是被当成元信息使用。但还有一种情况某个框架里skill.md 会被拆成“正文部分”和“执行部分”。如果执行部分只用代码块或特定标记包裹那标题行可能不会被当作指令执行只是用于描述。这时如果有人误以为“# 后面是注释”可能就会把真正的关键指令放到标题段里结果模型没有执行。所以正确的做法不是记住“# 是不是注释”而是去查看你的执行器到底怎么解析 Markdown。更稳妥的写法是不要把关键的可执行逻辑藏在标题里而是放在明确的字段区比如“执行步骤”或“代码块”里。结构上让解析器不能忽略。如果实在不确定可以做一个最小实验写一个只有一个技能的 skill.md标题写“当用户说 hello 时回复 world”然后看模型是否真的按这个逻辑响应。如果响应了说明标题被读取如果没响应说明标题只是装饰。这个实验比翻文档更快。3.4 怎么测试 skill 会不会被模型调用测试 skill 时我建议遵循一个由小到大的顺序先写一个最简单的技能不涉及外部工具调用确认模型能识别这个技能并触发再加入参数、输出格式、边界条件最后再测试多技能共存时是否互相干扰不要一开始就把十个技能全塞进去。因为模型在长上下文里对技能描述的注意力会分散你可能分不清是技能没加载成功还是触发词写得不够准确。判断一个 skill 是否生效最直接的方法就是看模型输出是否符合你定义的输出格式。比如你要求技能输出 Markdown 表格如果模型输出的是纯文本段落那要么是描述没有读进去要么是模型没有按描述执行。这时候先检查“输出格式”这段描述是否太笼统。4. 什么时候两个文件需要同时存在4.1 典型组合内容站加 AI 助手一个最常见的组合是你有一个技术文档网站同时在这个网站旁边部署了一个 AI 助手助手需要调用一些技能来回答问题。这时候两个文件会同时出现llms.txt 放在站点根目录让外部代理或搜索型 AI 知道这个站点有哪些文档skill.md 放在助手技能目录让助手知道回答问题时可以调用哪些工具比如搜索站内文档、运行代码示例、生成代码摘要两者各管一段。llms.txt 负责“被找到”skill.md 负责“会操作”。如果缺了 llms.txtAI 助手仍然可以用技能但它对站点整体结构的理解会差很多尤其在回答“你这个网站的文档分布在哪些模块”这类问题时容易答得零散。如果缺了 skill.mdAI 助手能读到站内全部文章但它不知道怎么执行具体操作比如调用 API、批量处理文件、生成特定格式报告。4.2 纯工具项目只要 skill.md如果项目本身不是一个公开内容站而是一个本地工具、CLI 工具或内部服务那 llms.txt 基本没有用。因为它不是一个对外可访问的网页集合外部代理也不会通过域名来访问。这种场景里我只需要维护 skill.md让模型知道它有哪些能力。比如一个批量重命名工具模型只需要知道“rename_files”这个技能的触发条件、参数和步骤不需要通过 llms.txt 去了解站点结构。一个常见的误区是本地项目也塞一个 llms.txt然后发现模型根本不读于是怀疑工具坏了。其实只是文件类型不匹配。4.3 纯内容站点可能只要 llms.txt反过来如果一个站点只是内容展示没有交互没有模型需要执行的操作那只要 llms.txt 就够了。比如个人博客、文档站、产品帮助中心主要目标是让 AI 搜索代理能快速理解内容结构并引用正确链接。这种情况不需要写 skill.md因为模型访问这个站点时只需要“找内容”不需要“执行任务”。如果你给这种纯内容站强行加一个 skill.md可能出现一个奇怪的现象模型把文档内容误当成技能描述然后尝试“执行”文档里的教程步骤而不是回答用户问题。4.4 同时维护时目录结构怎么规划当两个文件都需要时我建议按用途明确分目录不要放在同一个地方。一个比较常见的结构是site/ ├── llms.txt # 站点根目录面向外部访问者 ├── content/ │ └── docs/... # 文档正文 ├── .agent/ │ └── skills/ │ ├── code-review/ │ │ └── skill.md │ └── summary/ │ └── skill.md └── config/ └── agent.yml # 技能加载配置这个结构的好处是llms.txt 对应公开内容保持稳定skill.md 对应行为逻辑便于单独调试。你更新技能时不需要改 llms.txt更新文档时也不会误伤技能配置。当然这只是我一直用的组织方式不等于所有工具链都认。具体框架如果有自己的约定就以它的约定为准。5. 从“能跑”到“稳定用”的检查清单5.1 上线前检查能读、能解析、能执行我在把这类文件交付给业务方之前都会做一些常规检查避免在最基础的地方翻车文件能否被正常访问命令解析、路径正确内容是否为纯文本且编码正确标题层级是否符合工具预期链接是否有效技能文件名、路径、触发描述是否与框架要求一致有没有测试数据或日志能证明文件被加载这些检查不复杂但能省掉后面大量排错时间。5.2 一条条验证而不是一批全开无论是 llms.txt 还是 skill.md都建议先做最小样例测试。对于 llms.txt只放三到五个链接然后让代理描述站点并引用链接。确认它能正确引用之后再补充更多链接。对于 skill.md只定义一个最简单的技能确认触发和输出正常然后再增加第二个、第三个。不要一次性加载十几个技能因为一旦出现问题你很难判断是某个技能内部写法问题还是多个技能之间的描述冲突。5.3 常见失败形态和排查顺序如果你发现模型没有按预期使用这些文件可以按这个顺序排查第一看输入格式是否匹配。模型是否真的把 llms.txt 或 skill.md 当成了对应的资源而不是当成普通文本。第二看路径和文件名。文件名是否完全正确是否被构建工具忽略了。第三看解析器版本。有些解析器只支持 Markdown 的某个子集不识别复杂表格或超长代码块。第四看描述是否明确。尤其是 skill.md 的触发条件是否包含足够的同义词和否定条件。第五看上下文覆盖。如果系统提示词里写了“不要调用任何工具”那 skill 写得多好都不会触发。第六看日志。大部分框架会输出加载了哪些 skill读取了哪个 llms 文件。日志比猜测可靠得多。5.4 什么时候该删减文件还有一点容易被忽略文件不是越多越好。llms.txt 里的链接如果太多模型会迷失重点skill.md 如果太多模型会面临巨大的选择负担触发错误反而增高。我建议在以下情况下做一次精简站点新增了大量页面但 llms.txt 还停在三个月前两个 skill 的功能有重叠比如一个负责“总结文章”另一个负责“生成摘要”模型频繁误触发某个与当前需求无关的技能精简时不必一次删完先停用一半测试效果再决定保留还是回退。这样不会因为一次性改动太多导致整体行为失效。写到最后我想把这个判断再强调一次llms.txt 是给来客看的地址簿skill.md 是给助手用的操作手册。两者名字相近角色不同。实际项目中不一定都要用但如果你的站点同时有内容、有交互、有可变操作那把它们分开维护比混在一个文件里更可控。真正落地时不要先急着写大而全的文件先确认你的工具链有没有解析逻辑再写最小样例验证最后慢慢扩展。这样才不会出现文件写了一大堆模型却什么都没用上的尴尬情况。
返回列表