ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

llms.txt与Skill.md:一文搞懂Agent内容入口与技能说明的区别

llms.txt与Skill.md:一文搞懂Agent内容入口与技能说明的区别 最近在整理 Agent 技能目录和站点文档导入流程时我一直被一个问题绕住了同一个项目里既要让大模型快速找到整站文档的入口又希望 Agent 能按固定流程执行具体任务那到底该维护一个 llms.txt还是写若干个 Skill.md网上资料往往各讲各的一个偏站点索引一个偏 Agent 能力读完之后还是搞不清两者是什么关系。这篇文章就把 llms.txt 和 Skill.md 拆开讲清楚。文章会从文件格式、适用场景、编写步骤、自动生成脚本、常见坑点几个方面展开最后给出一套“什么时候用哪个、什么时候两个都要”的判断标准。如果你正在做 RAG 知识库接入、给 Agent 配置技能包或者想优化自己站点的 LLM 检索效果这篇文章会比较适合你。读完你能明白llms.txt 解决的是“模型怎么找到内容入口”Skill.md 解决的是“模型拿到任务后按什么步骤执行”。两者可以独立使用也可以在同一条链路里配合使用。1. 背景模型不该靠“猜”来读取你的内容1.1 从 robots.txt 到 llms.txt在传统网站生态里爬虫进入站点之前会先看一个叫robots.txt的文件。它告诉搜索引擎爬虫哪些路径可以抓哪些路径不能抓sitemap 在哪里。这个机制的核心价值是“降低爬虫的探索成本”。到了大模型时代问题变得更加微妙。搜索引擎爬虫抓取网页是为了建立关键词索引而大模型读取网页是为了理解语义、抽取信息、回答问题。网页里大量存在的导航栏、广告位、JS 动态渲染内容对搜索引擎也许还能容忍但对大模型来说可能是噪音会直接干扰信息抽取效果。llms.txt这个文件就是在这种背景下出现的。它是一份放在站点根目录下的纯文本索引目标是给大模型提供一个“友好版站点地图”。当一个 AI 应用准备抓取某网站的文档时可以先去读llms.txt从而快速确定该抓哪些页面而不是从首页开始层层遍历浪费 Token 和时间。1.2 从 Prompt 模板到 Skill.md另一方面随着 Agent 应用变得复杂开发者发现一个问题单纯靠系统提示词已经很难承载复杂技能。比如“生成周报”这件事可能涉及输入格式校验、数据分类、模板渲染、结果输出等多个步骤。如果把所有这些步骤都塞进一个超长系统提示里不仅维护困难而且每次对话都要消耗大量上下文。于是很多 Agent 平台开始采用“技能包”的组织方式。一个技能对应一个目录目录里放一个 Markdown 主文件描述这个技能的用途、触发条件、执行步骤和输出格式。这个主文件常见命名就是skill.md或SKILL.md我们这里统一用题目里的Skill.md来指代这类文件。Skill.md的价值在于它把“某个具体能力”从全局 Prompt 中剥离出来让 Agent 按需加载。用户用到对应能力时相关模型层才读取这个文件既能节省上下文也能让技能独立维护、独立复用。1.3 为什么会同时出现两个文件llms.txt和Skill.md看似都围绕大模型读取文件但服务对象完全不同。一个是给“检索器”看的文档索引一个是给“执行器”看的行为规范。很多项目中检索器负责找到外部资料执行器负责根据资料完成任务。如果执行器需要某个站点的资料它可能先借助llms.txt获取入口再借助Skill.md决定怎么处理资料。因此两个文件完全可能出现在同一条链路中。2. Skill.md 与 Llms.txt 分别解决了什么问题2.1 Llms.txt给检索者看的站点地图llms.txt解决的核心问题是“目录发现”。传统搜索引擎有成熟的爬虫系统可以自动发现站内页面但大模型应用往往没有耐心也不适合对整站做全量抓取。站点维护者如果手动提供一个精简索引模型就能更高效地完成后续操作。典型场景包括站点公开了大量技术文档希望被 AI 应用准确引用。企业内部知识库需要提供给内部 Agent 使用。做 RAG 应用时希望通过一个文件快速确认高质量文档 URL 列表。llms.txt的核心思想是“少而精”。它不需要列出所有页面只需要列出高质量、值得 AI 阅读的入口页面。后续无论是抓取正文还是由模型判断相关性和进入哪个子页面效率都会更高。2.2 Skill.md给执行者看的操作手册Skill.md解决的核心问题是“行为约束”。当 Agent 接收到一个任务时它需要知道该调用什么工具、按什么步骤操作、输出什么格式。这些信息不应该是隐式的而应该写成一份清晰的操作手册由 Agent 在需要时加载。典型场景包括Agent 需要按照固定流程生成日报、周报。Agent 需要从数据库查询信息并按指定模板输出。Agent 需要接入外部 API通过技能文件描述 API 的调用参数和错误处理方式。多 Agent 系统中不同角色通过各自技能文件保持行为一致。简单说llms.txt回答“用户可以去哪里找答案”Skill.md回答“Agent 该如何完成任务”。2.3 核心区别站点级入口 vs 能力级说明把两者放在一起对比最核心的区别可以概括为一句话llms.txt是站点级的“内容目录”Skill.md是能力级的“操作说明书”。在文件粒度上一个站点通常只有一个llms.txt但可能会有多个Skill.md每个技能一个文件。在服务对象上llms.txt服务于检索型应用比如 RAG 管道Skill.md服务于 Agent 型应用比如自动执行任务的智能体。在使用方式上llms.txt的内容往往直接注入到检索流程中用于选择 URLSkill.md的内容则会按需注入到 Prompt 中指导模型行为。3. 文件格式与语法拆解3.1 llms.txt 文件格式llms.txt的格式非常轻量基于 Markdown 的子集。文件第一行使用一级标题#写站点名称后续每一行基于文件列表安排。一个最简单的示例# Example Developer Documentation ## https://example.com/ ## https://example.com/getting-started/ ## https://example.com/api/reference/ ## https://example.com/guides/从结构上看一级标题是站点名字二级标题行直接写页面 URL。这样的写法很克制方便解析器逐行处理。解析器通常只需要识别#开头的站点名以及##开头的 URL 行就能得到一个干净的入口列表。有些站点会在llms.txt中加入分组标题和链接列表比如# Example Developer Documentation ## Quick Start - [Installation Guide](https://example.com/install) - [Configuration Guide](https://example.com/config) ## API Reference - [REST API](https://example.com/api)这种写法更易读也符合 Markdown 习惯。需要注意社区规范对“哪些 Markdown 语法可用”是有边界的设计初心是尽量保持简洁、减少解析歧义。实际落地时建议以官方规范页面为准并在生成后做一次自动解析验证。3.2 Skill.md 文件格式Skill.md的结构通常分成两块头部元数据和正文说明。头部元数据一般使用 YAML frontmatter也就是被三条短横线---包裹的区域。这块区域用于存放机器可读的字段比如技能名称、用途描述、版本号、作者、触发关键词等。正文部分是自然语言说明供模型理解具体执行流程。一个常见的Skill.md结构如下--- name: weekly-report description: 根据用户提供的本周工作内容生成结构化周报 Markdown 文件。 version: 0.1.0 license: MIT metadata: author: dev-team trigger_words: - 周报 - 周总结 - weekly report --- # 周报生成技能 ## 目标 生成一份结构清晰、信息准确的周报文件。 ## 使用条件 - 用户提供了本周任务列表或关键进展 - 如果用户只描述了模糊目标应先追问细节再开始生成。 ## 执行步骤 1. 汇总用户输入的原始内容 2. 将内容按“目标 / 进展 / 风险 / 下周计划”归类 3. 生成 Markdown 周报文件 4. 输出后请用户确认是否补充遗漏事项。 ## 输出模板 markdown # 周报 ## 本周目标 ## 本周进展 ## 风险与问题 ## 下周计划 这部分内容看似简单但对 Agent 的行为影响很大。frontmatter 中的name是技能唯一标识description用于技能匹配正文的“执行步骤”则决定了模型生成结果的质量。3.3 很多人问Skill.md 里面 # 后面的内容是不是不执行这个疑问其实暴露了 Markdown 和代码执行的混淆。要回答清楚需要区分两个位置frontmatter 区域内和正文区域。在 frontmatter 区域中#是 YAML 注释的开始符号。例如--- name: weekly-report # 这是一行 YAML 注释解析器会忽略它 description: 生成周报 ---这里的注释在解析阶段会被忽略不会成为字段值。也就是说“#后面不生效”在 YAML 注释场景下基本成立。但在正文区域中#是 Markdown 标题语法。比如# 周报生成技能是一个一级标题模型读取文件时会把这段话当作文档结构的一部分用于理解后续内容。它不会被当作命令“执行”也不会被整体跳过。模型读取的是完整文本并把每个标题当成语义信息。所以更准确的说法是Skill.md中的 Markdown 内容不是可执行代码不存在“执行”或“不执行”的区别但 frontmatter 中的 YAML 注释会被解析器忽略正文中的 Markdown 标题会参与模型语义理解。如果你有内部备注不想让模型看到不应写在正文里而应放在 frontmatter 注释中或者干脆放在技能目录外的独立文件里。4. 实战为你的站点生成 llms.txt4.1 准备工作与环境生成llms.txt不需要太复杂的环境。你需要一个文本编辑器用于查看和修改最终文件。命令行工具推荐使用curl验证文件是否可访问。如果希望自动生成需要安装 Python 3.8 以上版本。本文示例以常见环境为主版本需要根据你的项目实际情况调整重点演示配置思路。4.2 手动编写一份 llms.txt假设你的站点是https://docs.example.com/主要文档分成“快速开始”“API 参考”“最佳实践”三个模块。那么一份手写的llms.txt可以是# Example Docs ## https://docs.example.com/ ## https://docs.example.com/getting-started ## https://docs.example.com/api-reference ## https://docs.example.com/best-practices生成后把文件保存为llms.txt并放到站点根目录下。上线前用curl验证地址是否能正常返回curl https://docs.example.com/llms.txt如果返回的是文件内容而不是 404说明部署位置正确。要注意的是文件名必须是llms.txt不要写成LLMS.txt或llms.txt/服务器路径大小写敏感时容易踩坑。4.3 用 Python 脚本自动抓取生成手动维护虽然简单但站点页面一多就容易遗漏。这里提供一个轻量级 Python 脚本思路从站点根页面抓取所有同域名链接然后输出成llms.txt的骨架。# 文件路径generate_llmstxt.py import argparse import re from urllib.parse import urljoin, urlparse from urllib.request import urlopen def get_links(base_url, html): links [] for href in re.findall(rhref[\]([^\])[\], html, re.I): absolute urljoin(base_url, href) links.append(absolute) return links def same_domain(url, base): return urlparse(url).netloc urlparse(base).netloc def main(): parser argparse.ArgumentParser(descriptionGenerate llms.txt skeleton) parser.add_argument(--root, requiredTrue, helpSite root URL) args parser.parse_args() root args.root.rstrip(/) with urlopen(root) as resp: html resp.read().decode(utf-8, errorsignore) seen [] for link in get_links(root, html): if same_domain(link, root) and link not in seen: seen.append(link) print(f# {root}) print() for link in seen: print(f## {link}) if __name__ __main__: main()运行方式python generate_llmstxt.py --root https://docs.example.com这个脚本只是提取同域名链接输出结果可能包含登录页、分页、动态路由等不需要的内容。它更适合作为初稿生成后一定要人工清理只保留高质量的文档入口。4.4 验证文件是否可被有效读取生成并部署后可以从两个层面验证。第一层是可访问性。确认 URL 能直接返回内容不依赖 JS 渲染没有强制跳转。大模型应用抓取时不会执行复杂脚本所以llms.txt必须是静态文本。第二层是解析符合预期。可以写一段简单脚本读取llms.txt提取所有##开头的 URLurls [] with open(llms.txt, r, encodingutf-8) as f: for line in f: line line.strip() if line.startswith(## ): urls.append(line[3:].strip()) print(urls)如果输出的 URL 列表符合预期说明解析器可以正常拿到入口。建议把这一步纳入站点发布流程避免文件更新后结构被误改。5. 实战编写一个可用的 Skill.md5.1 技能目录规划编写Skill.md之前先想清楚技能边界。一个技能最好只做一件事。比如“生成周报”是一个技能“获取天气并生成早安推送”是另一个技能不要混在一起。常见目录结构如下skills/ weekly-report/ skill.md templates/ weekly_report_template.md scripts/ format_report.py这个结构把技能说明、模板、脚本分层存放。skill.md负责告诉模型“该怎么做”templates放输出模板scripts放真正需要执行的代码。5.2 编写 frontmatterfrontmatter 中最关键的字段是description。很多 Agent 平台会通过这个字段判断“用户请求是否匹配当前技能”。它写得太泛会导致误触发写得太窄又会导致技能无法被唤醒。以一个“客户周报生成”技能为例--- name: customer-weekly-report description: 当用户需要基于客户沟通记录生成周报时使用。适用于销售、客户成功、项目经理等角色。 version: 1.0.0 license: MIT metadata: author: example-team trigger_words: - 客户周报 - 客户进度 - 客户沟通总结 ---这里trigger_words用于提示模型哪些请求可能和本技能相关。它不是硬编码的触发条件而是辅助路由的语义线索。5.3 编写正文工作流正文是技能的核心承担着“指导模型执行”的职责。正文应该尽量结构化让模型能按步骤执行而不是给一段含糊的长文本。# 客户周报生成技能 ## 适用场景 用户需要输出某个客户的本周沟通总结或项目进度周报。 ## 输入信息 - 客户名称 - 本周沟通记录或关键事件 - 如果缺少上述信息先向用户确认不要自行编造。 ## 处理步骤 1. 提取客户名称和时间范围 2. 从沟通记录中归纳关键进展 3. 标注风险项和待办事项 4. 按模板输出周报。 ## 输出格式 markdown # 客户周报{客户名称} - 时间范围{起始日期} 至 {结束日期} - 本周进展... - 风险项... - 待办事项... 这段正文的价值在于它把模型的行为约束在一个明确范围内。比如“不要自行编造”就是非常关键的一条能有效避免模型完成任务时虚构客户信息。5.4 部署到 Agent 环境不同 Agent 平台加载技能的方式不同。有的平台要求把技能目录放到特定目录下有的平台要求通过管理界面导入。部署时务必关注三点第一文件名大小写。部分平台约定为skill.md部分平台约定为SKILL.md还有平台允许两者。落地前先查一次平台文档别因为文件名字母大小写导致技能加载失败。第二目录相对位置。技能主文件通常放在该技能目录的根目录但具体路径受平台约束。例如有些平台要求技能目录放在skills/{skill-name}/下有些则放在~/.claude/skills/下。需要按官方说明安排。第三依赖文件路径。如果skill.md中引用了模板或脚本尽量使用相对路径并在部署后测试一次完整调用。5.5 验证与迭代部署完成后用一组测试请求验证技能效果。可以先准备 3 类输入明确触发词、模糊意图、完全不相关内容。观察模型是否正确唤醒技能以及输出质量是否符合预期。如果技能没有被唤醒优先检查description是否覆盖了用户常用说法。如果技能被错误唤醒说明description和trigger_words写得太宽需要收紧。如果技能唤醒后输出格式不对重点检查正文中的“输出格式”部分是否足够具体。6. 二选一还是都要判断标准与最佳实践6.1 什么时候只需要 llms.txt如果你的目的只是让大模型能准确找到站点内容而不是让 Agent 执行复杂任务那么只需要llms.txt。典型情况包括公开文档站点、开源项目主页、企业对外 API 文档。这类场景里模型只需要“读什么”不需要“做什么”。引入Skill.md反而增加维护成本。6.2 什么时候需要 Skill.md如果你正在构建 Agent 应用且 Agent 需要执行固定流程的任务那么Skill.md是更合适的选择。例如内部运营机器人需要根据数据自动生成日报、客服助手需要按固定话术回复常见问题、研发助手需要按照既定流程创建 Issue。这些场景的关键不是“找到内容”而是“按规范完成动作”。6.3 什么时候两者同时维护两者同时维护的场景并不罕见。一个知识型 Agent 产品既需要llms.txt让模型快速抓取外部资料又需要Skill.md让模型按照统一流程整理资料、输出报告。还有一种常见的协同方式是在Skill.md的执行步骤中引用某个站点的llms.txt要求模型先读取该文件确定资料入口再抓取细节。这样llms.txt提供信息供给Skill.md提供行为约束各自发挥优势。6.4 工程建议无论维护哪个文件都建议遵循以下几条原则保持精简。llms.txt不是全站链接备份Skill.md不是长篇大论文件内容越聚焦模型使用效果越好。纳入版本管理。llms.txt和Skill.md都应该存放在 Git 仓库中方便追踪变更历史。加入自动化校验。可以写脚本检查llms.txt中的 URL 是否可访问也可以写脚本校验Skill.md的 frontmatter 字段是否完整。敏感信息隔离。不要在Skill.md中写入 API Key、数据库密码、内部凭据应通过环境变量或密钥管理服务注入。最小权限意识。给 Agent 配置技能文件时只授予完成任务所需的最小权限。例如能只读就不要写能限定目录就不要开放全盘访问。7. 常见问题与排查思路下面列举几个实际使用中容易遇到的问题。问题现象常见原因解决思路模型总是找不到llms.txt文件没有放在站点根目录或文件名大小写不对确认 URL 为https://domain/llms.txt并检查服务器静态文件配置llms.txt中 URL 太多模型理解困难把全站链接都塞进去了只保留高质量入口合并同类页面控制文件在少量链接量级Skill.md部署后技能没有被唤醒description写得太窄或太泛和用户表达不匹配重写description覆盖常见相似表达并加入trigger_words技能被错误唤醒技能描述中关键词覆盖范围过大增加使用条件限制在正文中要求模型先确认输入是否匹配frontmatter 中的#注释被当成了字段对 YAML 注释语法不熟练明确注释只写在 frontmatter 区域正文中的#请当作 Markdown 标题处理生成周报时模型编造了数据Skill.md正文没有明确“禁止编造”约束在执行步骤中加入“缺少信息先询问、不要自行编造”的描述修改Skill.md后行为没有变化Agent 平台缓存了旧技能文件重启相关服务或等待缓存过期必要时查看平台加载日志如果你遇到“技能目录文件加载失败”类问题可以按以下顺序排查检查文件名是否完全符合平台约定。检查文件是否保存为 UTF-8 编码。检查 frontmatter 是否使用三条短横线闭合字段是否缩进规范。检查是否有特殊符号导致 YAML 解析失败。查看 Agent 平台日志确认技能加载错误信息。8. 总结llms.txt和Skill.md并不冲突它们服务的是大模型应用的不同环节。llms.txt更像“图书馆索引”告诉模型该去看哪几本书Skill.md更像“实验手册”告诉模型该按哪个步骤完成操作。一个偏内容发现一个偏行为控制。实际项目中先问自己一个问题这个文件是给谁看的解决什么问题如果是为了让模型更快找到站点内容优先维护llms.txt如果是为了让 Agent 稳定完成特定工作流优先维护Skill.md如果两者都存在就把它们放到各自合适的位置让llms.txt提供素材、Skill.md提供流程。两个文件都不复杂真正考验人的是边界意识。下次新建一个技能目录或站点索引文件时先想清楚它是“入口”还是“操作手册”写出来的内容自然会清晰很多。如果你在项目中也遇到过相关踩坑欢迎在评论区分享当时的处理思路。
返回列表