
goose-doc-guide 内置 Skill 解析goose 如何把官方文档变成回答技术问题的唯一事实依据【免费下载链接】goosean open source, extensible AI agent that goes beyond code suggestions - install, execute, edit, and test with any LLM项目地址: https://gitcode.com/GitHub_Trending/goose3/goosegoose 内置了一个名为goose-doc-guide的 Skill它是 Agent 回答任何 goose 特有问题recipes、extensions、sessions、providers 等前强制执行的“文档查证工作流”。本文以该 Skill 的源文件 goose_doc_guide.md 为主体完整拆解其触发条件、文档根解析机制与五步工作流并结合 skills 模块源码 与 配置读取实现 说明它如何被编译进二进制、如何注册、以及如何在离线环境中通过GOOSE_DOCS_ROOT指向本地文档镜像。一、Skill 定位何时启用、何时禁用goose-doc-guide采用标准 SKILL.md 结构YAML frontmatter 声明name与description正文是写给 Agent 的操作性指令。其 frontmatter 中的 description 明确了两条硬约束回答 goose 特有问题前必须先读取相关 goose 官方文档You MUST read the relevant docs before answering对任何 goose 特有的字段、取值、名称、语法或命令禁止依赖训练数据或假设You MUST NOT rely on training data or assumptions。正文首先界定了适用场景与非适用场景这是典型的“Skill 触发边界”写法应当使用本 Skill 的 goose 特有任务创建或编辑 recipes配置 extensions 或 providers解释 goose 各功能的工作机制任何 goose 的配置或搭建任务。不应使用本 Skill 的场景与 goose 无关的普通编码任务运行已有 recipes直接运行即可无需查文档。这套“正反清单”与 goose 官方文档中 Agent Skills 的通用设计一致——Skill 是教会 goose 执行特定任务的复用指令集详见 Agent Skills 指南。与web-search等不同goose-doc-guide属于内置 Skill无需安装、随二进制始终可用其注册机制见本文第四节。二、{{GOOSE_DOCS_ROOT}}文档根占位符的解析规则Skill 正文的关键变量是文档根docs root本会话的文档根是{{GOOSE_DOCS_ROOT}}。它可能是本地文件系统路径也可能是 HTTP(S) URL。若为本地路径用 shell/文件工具读取文件若未设置或是 HTTP(S) URL则从规范站点 https://goose-docs.ai 获取。下文中该文档根统一记作docs-root。占位符不是由 LLM 自己填充的而是由 Rust 代码在加载 Skill 时做确定性替换。在 crates/goose/src/skills/mod.rs 中const DEFAULT_GOOSE_DOCS_ROOT: str https://goose-docs.ai; const GOOSE_DOCS_ROOT_PLACEHOLDER: str {{GOOSE_DOCS_ROOT}}; fn resolve_docs_root_placeholder(skill: SourceEntry, content: str, docs_root: str) - String { if skill.name ! goose-doc-guide || skill.source_type ! SourceType::BuiltinSkill { return content.to_string(); } content.replace(GOOSE_DOCS_ROOT_PLACEHOLDER, docs_root) }从源码结构看替换有三个约束条件只针对goose-doc-guide这一个 Skill且其source_type必须为BuiltinSkill——同名但来自文件系统的用户 Skill 不会被替换对应测试resolve_docs_root_placeholder_ignores_non_builtin_goose_doc_guide_skills替换值来自Config::global().get_goose_docs_root()未设置时回退到DEFAULT_GOOSE_DOCS_ROOT该配置项的读取逻辑在 crates/goose/src/config/base.rs 的get_goose_docs_root()按GOOSE_DOCS_ROOT参数取值trim 后为空字符串视为未设置返回None走默认值。对应单元测试覆盖了配置项、环境变量、未设置、空白值四种情形。优先级来源说明1GOOSE_DOCS_ROOTconfig.yaml 或环境变量本地路径或 HTTP(S) URLtrim 后为空则忽略2默认值https://goose-docs.ai未配置时的规范在线文档站点这一机制让同一份 Skill 文案既能在线工作走规范站点又能在离线/隔离环境中无缝切换到本地文档镜像——这正是 Offline / Air-gapped Docs 文档 所描述的部署方式。三、五步工作流逐步拆解Skill 正文的核心是一条标题为“Steps (COMPLETE ALL BEFORE RESPONDING)”的强制工作流五个步骤必须全部完成才能回答。步骤 1读取官方文档Read official docs这一步定义了“如何找到正确的文档页”规则非常严格先读取文档地图docs-root/goose-docs-map.md在 doc map 中搜索与用户主题相关的页面取出这些页面的路径必须使用 doc map 中列出的原始路径。文档给出的示例若 doc map 显示docs/guides/sessions/session-management.md则读取docs-root/docs/guides/sessions/session-management.md禁止修改或猜测路径只允许读取 doc map 中显式列出的路径不得推断不存在的页并行读取多篇文档并保存到临时文件后续搜索基于临时文件进行避免重复读取。“只读 map 中列出的路径”这条约束值得注意它把 LLM 的路径幻觉hallucination风险直接封死——文档地图由构建管线生成documentation/scripts/generate-docs-map.js 将索引输出到static/goose-docs-map.mdAgent 只能在其枚举的页面集合内检索。步骤 2创建/修改内容schema 驱动的配置编写当任务涉及 goose 配置文件recipe、provider 配置等时该步骤要求先查阅 schema/字段参考文档搜索文档抽取你计划使用的每个元素的完整 schema提取示例片段以理解用法模式基于参考规格创建配置遵循示例的写法。随后是一个显式的STOP 检查门在向用户展示之前必须核对输出内容与 goose 官方文档中的 schema 和参考一致字段名与文档所示完全一致必需字段/属性齐全取值格式与示例匹配YAML/JSON 语法、数据类型等。任何一项验证失败都要修订并重复本步骤直到全部通过未通过验证的输出不得呈现给用户。这一步把“生成后自检”从建议变成了阻塞式流程。步骤 3强制验证清单MANDATORY VERIFICATION在写下最终回答前必须逐项核对对任何 goose 特有的字段、取值、名称、语法、命令不得依赖训练数据或假设回答中是否包含 “How to Use”、CLI 命令或使用说明若包含且用户并未要求 →立即删除若包含且用户要求了 → 先对照文档核命令的准确性再保留列出回答中所有 goose 特有内容命令、字段、语法、取值、用法、解释等逐项对照文档验证查不到的内容要么现在就去读相关文档验证要么删除若是用户明确要求的则注明 I could not find documentation for [X]。值得注意的是第二条Skill 明确抑制了 LLM 常见的“顺手补充教程”行为——除非用户索要否则不主动附加使用步骤避免回答膨胀与未经核实的命令混入。步骤 4回答并附上 “Verification Completed” 段落每个 goose 特有内容都必须引用具体验证过的文档文件作为出处。这使得 Agent 的回答自带可追溯的证据链读者可以据此判断每条声明的文档依据。步骤 5列出文档链接链接输出有两条格式规则只列出实际用到的文档始终链接到规范站点 https://goose-docs.ai/即使文档是从本地路径读取的绝不暴露本地文件系统路径URL 去掉.md后缀。示例读取docs/guides/sessions/session-management.md时列出的链接形如https://goose-docs.ai/docs/guides/sessions/session-management。这条规则实现了“本地读取、规范引用”的解耦离线用户本地读文档、拿到本地文件但引用链仍指向规范站点保证链接对外部读者可解析。四、源码视角内置 Skill 的编译、注册与同名覆盖4.1 编译期内嵌crates/goose/src/skills/builtin.rs 只有 11 行用include_dir!宏把src/skills/builtins整个目录编译期嵌入二进制static BUILTIN_SKILLS_DIR: Dir include_dir!($CARGO_MANIFEST_DIR/src/skills/builtins); pub fn get_all() - Vecstatic str { BUILTIN_SKILLS_DIR .files() .filter(|f| f.path().extension().is_some_and(|ext| ext md)) .filter_map(|f| f.contents_utf8()) .collect() }即目录下每个.md文件goose_doc_guide.md、web_search.md都是一份完整的 SKILL.md 内容随 goose 二进制分发运行时零 IO。4.2 发现与注册discover_skills_with_config() 按固定顺序扫描所有 skill 目录项目级.agents/skills、.goose/skills、.claude/skills插件目录全局目录对每个已见名称去重最后才处理内置 Skillfor content in builtin::get_all() { if let Some(source) parse_skill_content(content, PathBuf::new(), true, true) { if !seen.contains(source.name) { ... let path format!(builtin://skills/{}, source.name); sources.push(SourceEntry { source_type: SourceType::BuiltinSkill, path, ... }); } } }要点内置 Skill 的路径是虚拟的builtin://skills/goose-doc-guideglobal标记为trueparse_skill_content()解析 frontmatter缺少name的 Skill 会被跳过并告警同名去重意味着文件系统 Skill 优先于内置 Skill如果你在.agents/skills/goose-doc-guide/SKILL.md放了自己的版本内置版本会被压制。该行为有专门测试filesystem_skill_suppresses_same_named_builtin固化见 crates/goose/src/sources.rs测试断言项目级覆盖后内置列表里不再出现goose-doc-guide且 Skill 列表中返回的是带 project override 描述的项目版本。4.3 加载时的上下文包装会话中 Skill 被加载时loaded_skill_context()会生成如下结构标题行# Loaded Skill: {name} ({source_type})、frontmatter 的 description、正文## Content以及支持文件清单## Supporting Files含相对路径到解析后绝对路径的映射。{{GOOSE_DOCS_ROOT}}的替换就发生在这一步之前因此 LLM 最终看到的是已解析出具体文档根的指令。4.4 端到端测试佐证crates/goose/src/skills/mod.rs 的测试resolve_docs_root_placeholder_substitutes_builtin_goose_doc_guide_root验证本地路径替换内容Docs root: {{GOOSE_DOCS_ROOT}}.被渲染为Docs root: /tmp/goose docs/root.crates/goose/tests/acp_custom_requests_test.rs 从 ACP 层验证list_sources返回的goose-doc-guide条目其source_type为builtinSkill、路径为builtin://skills/goose-doc-guide确认内置 Skill 对客户端可见且可枚举。五、实战延伸离线与隔离环境中的文档根配置goose-doc-guide的设计目标之一是让 goose 在离线/气隙air-gapped环境中仍能以文档为准回答特有问题。依据 Offline / Air-gapped Docs 文档 与 config-files.md、environment-variables.md 中的参数说明完整做法如下。5.1 文档根目录结构一个合法的 docs root 包含一个索引和一棵docs/树docs-root/ ├── goose-docs-map.md └── docs/ ├── getting-started/... └── guides/...goose-docs-map.md是 Skill 首先检索的索引Skill 读取的每一个页面都必须由该索引中的某条路径引用——与第三节日记“只读 map 中列出的路径”的规则闭环。5.2 构建本地文档根用与 goose 二进制相同版本的源码构建文档保证文档与运行时匹配官方文档构建产物已包含 goose 所需的全部内容无需自定义工具git checkout v1.41.0 # match your goose binary version cd documentation npm run buildnpm run build会将文档根写入documentation/build/build/ ├── goose-docs-map.md └── docs/ ├── getting-started/... └── guides/...注意npm run build需要访问 npm registry因此必须先在线构建再把build/目录整体拷贝到隔离环境的某处例如/opt/goose-docs。5.3 指向本地文档根在config.yaml中设置GOOSE_DOCS_ROOT: /opt/goose-docs或通过环境变量export GOOSE_DOCS_ROOT/opt/goose-docs配置生效链路为GOOSE_DOCS_ROOT→Config::get_goose_docs_root()trim 判空→loaded_skill_context()中的占位符替换 → LLM 看到本地路径的文档根。当文档根是本地路径时goose 用其文件工具直接读取全程无需网络当是 HTTP(S) URL 时则作为自建镜像使用Skill 文案中“从规范站点获取”对应在线情形。两点行为边界无论实际从何处读取Agent 回答中的文档链接始终渲染为规范站点 URL对应 Skill 步骤 5对托管发行版可将文档树直接烘焙进镜像并在随附的config.yaml或启动器环境中预设GOOSE_DOCS_ROOT。六、小结goose-doc-guide虽然只是一份约 60 行的 Markdown 文件但它体现了一套完整的“可信回答”工程方法边界先行frontmatter 与正/负清单界定触发条件避免 Skill 被滥用证据闭环先读文档地图、只用显式列出的路径、schema 驱动的生成与 STOP 检查门把“凭记忆回答”逐层排除可追溯输出强制 “Verification Completed” 段落与规范站点链接让每条 goose 特有声明都有文档出处确定性注入{{GOOSE_DOCS_ROOT}}由 Rust 代码替换而非模型推断配合include_dir!编译期内嵌使 Skill 行为在不同部署环境在线 / 离线镜像 / 自建 URL 镜像下保持可预测。对扩展开发者而言这个内置 Skill 也是编写自定义 Skill 的范本清晰的触发边界、编号步骤、显式验证清单与输出格式约束均可直接移植到 deployment、code review 等场景。更多 Skill 编写约定见 Agent Skills 指南GOOSE_DOCS_ROOT参数全集见 环境变量文档。【免费下载链接】goosean open source, extensible AI agent that goes beyond code suggestions - install, execute, edit, and test with any LLM项目地址: https://gitcode.com/GitHub_Trending/goose3/goose创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考