资讯动态

authentik 的 Agent 友好架构:从 llms.txt 文档索引到 code-mode MCP 的落地实践

发布时间:2026/9/12 12:42:36 来源:尧图企业网站定制
authentik 的 Agent 友好架构从 llms.txt 文档索引到 code-mode MCP 的落地实践【免费下载链接】authentikThe authentication glue you need.项目地址: https://gitcode.com/GitHub_Trending/au/authentik本文基于仓库中的设计文档 2026-06-24-authentik-llm-architecture-design.md 编写并结合website/下已落地的 Docusaurus 插件源码展开。文中涉及的 Layer 2、Layer 3 及authentik-agent-marketplace为设计文档中标注的外部配套仓库/规划内容当前 monorepo 内可以验证的是 Layer 1 的实现与文档中描述的其余层设计。authentik 是一个开源身份认证平台版本迭代频繁AI 编码 Agent如 Claude Code、Cursor基于预训练数据的知识往往滞后于真实版本。为此authentik 设计了一套三层 Agent 友好架构用随每个 release 自动再生的文档产物喂给 Agent让 Agent 优先做实时检索live retrieval而不是依赖训练数据。读完本文你将掌握这套架构的完整设计llms.txt 文档索引 → marketplace 技能 → code-mode MCP 服务器、Layer 1 在仓库中的真实实现细节以及给登录流加验证码这一贯穿三层的验收用例。为什么需要检索优先问题与设计目标文档开篇就点明了动机authentik 在两个 release 之间的变化非常大Agent 的预训练知识经常过期。因此目标不是把更多内容塞进模型上下文而是让 Agent 通过一个廉价的索引docs 侧是llms.txtAPI 侧是schema.yml起步按需按需拉取/执行fetch/execute on demand而不是一次性把内容或工具灌进上下文。两条检索面遵循同样的形状先给 Agent 一个轻量索引再让它按需取内容。这样稳态维护成本趋近于零——因为索引和 API 面都来自 authentik 每个 release 自动再生的产物。三类问题的路由设计文档给出了清晰的请求路由问题类型例子路由文档问题如何配置 SAML、App 和 Provider 有什么区别L1 L2不需要实例实例问题显示最近 10 次失败的登录、我运行的是哪个版本L3混合/操作问题给我的登录流加个验证码、重置我的管理员密码L2 读文档理解概念L3 写代码执行非目标YAGNI设计文档明确划定了不做的事防止架构膨胀不做第三方域名上的主llms.txtdocs/integrations 通过互链解决不做预计算的 docs→API 映射注册表code-mode 的search对实时 spec 的检索覆盖了它不做 tool-per-endpoint 的 MCPauthentik 的 API 有数百个端点每个端点暴露一个工具会淹没上下文且每个 release 都要维护code-mode 把工具面固定在约 3 个工具上与 API 规模无关不采用社区authentik-mcp原始 HTTP、手写 tool-per-endpoint、4 倍重复、无守卫每次 release 维护负担高且形态错误。Layer 1 — Docusaurusllms.txt插件仓库内已实现Layer 1 从docusaurus-plugin-llms移植并精简落在共享主题包里。仓库中真实的目录是 website/docusaurus-theme/llms-txt/注意与设计文档中的docusaurus-theme/llms-txt/相对位置对应位于website/之下与releases/、redirects/平级以源码形式发布无构建步骤与既有模式一致。文件组成plugin.mjs— Docusaurus 插件工厂默认导出node.mjs— 文件发现、MDX 解析、URL 解析逻辑generate.mjs— 各类输出根索引、全文、分组索引、单页.md的字符串组装common.mjs— 选项与数据类型markdown.mjs— MDX → 干净 Markdown 的清洗管线配套*.test.mjs单元测试与__fixtures__/样例文件。在 website/docusaurus-theme/package.json 的exports中注册./llms-txt/plugin、./llms-txt/node、./llms-txt/common等入口。Hook 选择postBuild而非loadContent插件使用postBuild钩子而不是主题其他插件常用的loadContent/contentLoaded模式。这是有意为之postBuild能拿到最终解析好的路由 URL 列表routesPaths而准确的最终 URL 必须等构建后阶段才有。在 plugin.mjs 中可以看到postBuild里用props.routesPaths调用buildLLMSOutputs并写入props.outDir。有意思的是插件同时实现了loadContent用于 dev server——它用routesPaths: []走resolveDocumentUrlFromSource的源码级 URL 解析并通过configureWebpack把生成的产物挂到 dev server 的静态目录上保证开发环境也能预览 llms.txt 产物。三级索引的索引输出按照 llmstxt.org 约定对 docs 和 integrations两个站点docs.goauthentik.io、integrations.goauthentik.io两个子域分别生成/llms.txt— 分组根索引。头部带指向姊妹站点/llms.txt的交叉链接docs 按主题分组integrations 按类别分组类别由categories.mjs驱动。仓库中该头部由 generate.mjs 的 buildHeader 生成交叉链接渲染为Related: label行。dir/llms.txt— 每个主题/类别一个索引如integrations.goauthentik.io/cloud-providers/llms.txt、docs.goauthentik.io/add-secure-apps/llms.txt只索引该子树并向上交叉链接到父索引。实现在generatePerGroupIndexesgenerate.mjs。/llms-full.txt— 站点全文拼接。设计文档强调它并不冗余这是给 RAG 索引种子和批量/离线下载的最佳单一载荷。插件既然已经遍历了整个站点生成它的成本很低generateFullText把所有页面的清洗内容按## 标题拼接页间用---分隔。每页page.md—最后一跳last-hop载荷索引链接指向这些.md文件llmstxt.org 的.md后缀约定。URL 后缀由 generate.mjs 的 applyMdExtension 处理——根首页的载荷是/index.md其余页面是url.md。每页.md载荷核心而非可选这是设计评审中决定性的修正没有每页.mdAgent 走完整条索引链后没有小块内容可拉取——只剩过大的llms-full.txt或渲染后的 HTML。所以每页.md的产出是核心功能。难点在于 authentik 的 MDX 不是普通 Markdown它使用了partial importsimport X from _shared.mdx自定义 remark 指令:::ak-version以及 enterprise/preview/support 徽章。直接拷贝.mdx会泄露未解析的 import硬性失败——内容直接缺失和指令噪音。因此清洗步骤必须在 React 组件注入之前拿到解析后的 MDX AST内联 partial imports复用源插件的resolvePartialImports思路剥离自定义指令丢弃:::ak-*/ 徽章节点——对 Agent 是噪音剥离 frontmatter然后序列化为干净的 Markdown。残留的 JSX 是可接受的——现代 LLM 能解析它真正的风险是信息丢失而非残留 JSX。这是一次性、构建稳定的投入。源码中的真实实现清洗管线实现在 markdown.mjs 的cleanMdxToMarkdownpartial 内联inlinePartials用正则匹配import X from ..._partial.mdxresolve出真实路径读取内容跳过 frontmatter再把 JSX 用法X /替换为正文对 Markdown 转义的下划线\_partial.mdx会先反转义再解析并用chain集合防止 partial 循环导入自身节点剥离stripNodesPlugin用unist-util-visit遍历 AST把mdxjsEsm、mdxJsxFlowElement、mdxTextExpression等节点替换为其文本子节点把containerDirective/leafDirective/textDirective指令节点解包为纯文本admonition 围栏stripAdmonitionFences逐行处理:::note等围栏标记保留内文且感知代码块——绝不改动围栏代码内部的内容正则兜底当严格 MDX 解析抛错格式复杂的 JSX 等时走regexClean正则兜底并计入统计日志。plugin.mjs 里会汇总输出(N skipped — no route; M used the regex fallback)。解析过程中的描述提取也相当讲究node.mjs的extractDescription会跳过标题、MDX import/export、admonition/JSX、CVE reporter 署名和纯列表块cleanDescriptionText会剥离 blockquote 标记、-- 署名行、列表符号、图片、链接保留链接文本、粗斜体与行内代码最后firstSentence截到第一句让索引行是一条干净的短描述。插件接线website/docusaurus-theme/config.js 提供createLLMSPlugin(options)工厂返回[goauthentik/docusaurus-theme/llms-txt/plugin, options]元组。两个站点各自调用docswebsite/docs/docusaurus.config.esm.mjssections: [{ path: ., routeBasePath: / }]、groupBy: topic、categories: topics来自 website/docs/topics.mjs如core → Core Concepts、glossary → Glossary等显示标签、regroup: [[core/glossary, glossary]]把术语表从 Core Concepts 中拆成独立小节crossLinks指向 integrations 的llms.txt。integrationswebsite/integrations/docusaurus.config.esm.mjsgroupBy: category、categories来自自己的 categories.mjsoverviewPages: [index, applications]把落地页作为## Overview内联为散文而非链接行并ignoreFiles: [**/template/**]跳过脚手架模板。选项速查来自common.mjs的LLMSPluginOptions选项类型说明sections{ path, routeBasePath, label? }[]要扫描的一个或多个 docs 根必填为空会抛错siteUrlstring覆盖站点 URL优先级最高title/descriptionstring覆盖站点标题/标语ignoreFilesstring[]额外的 glob 排除crossLinks{ label, url }[]头部姊妹站点链接groupBytopic \| category根索引的分组方式categories[slug, label][]分组显示名覆盖regroup[pathPrefix, groupSlug][]把某子树拆分/并入指定组overviewPagesstring[]内联进根索引## Overview的页面siteUrl的解析还有个细节resolveSiteUrl会检查 Netlify 环境变量CONTEXT与DEPLOY_PRIME_URL在 deploy-preview / branch-deploy 时把链接指向部署预览源而不是硬编码生产子域避免预览构建里的链接指向错误来源。移植时的增删取舍保留两个核心生成器索引 全文、基于路由的 URL 解析、glob ignore、排序、section/category 分组、partial import 解析 指令剥离、批量处理。删除blog 包含、pathTransformation路由解析已覆盖、customLLMFiles、keepFrontMatter、addPaths/ignorePaths。依赖gray-matterminimatch主题本已使用fast-glob。Layer 2 — Marketplace 技能authentik-agent-marketplaceLayer 2 位于设计文档标注的外部仓库authentik-agent-marketplace当前 monorepo 中不含其源码其形态是两个角色拆分的插件每个插件是一组技能。关键设计原则是技能是指针 方法绝不是知识倾倒knowledge dumps。ak-admin12 个技能— 按 authentik 对象模型组织concepts、applications、providers、sources、flows-stages、authenticators-mfa、policies-rbac、users-directory、outposts、events-monitoring、troubleshooting、operations。ak-dev11 个技能— 面向为 authentik 做贡献dev-environment、backend、frontend、docs、testing、linting、contributing、community、de-slop。每个技能由namedescription Purpose When to invoke Not this skill 组成并且每个技能都携带优先检索而非预训练authentik 随 release 变化的指令。两条接缝seams连接三层的正是这一对接线L2 → L1文档每个技能只指向稳定的根入口 URLdocs.goauthentik.io/llms.txt或integrations.goauthentik.io/llms.txt并指示 Agent动态遍历链接、拉取页面.md。技能散文里不写死深路径因此能扛住文档重组。Layer 1 生成的llms.txtURL 就是这些技能的入口。L2 → L3实例ak-admin技能追加一行转向指令——要检查或修改在线实例使用 code-mode MCP先search找端点再在execute/execute_write里写ak.request(...)。先从文档学习概念。其中events-monitoring指向executeflows-stages、users-directory等指向execute_write。设计文档还提到.mcp.json注册和SessionStart依赖安装钩子已在仓库中为 Layer 3 服务器搭好了脚手架属外部仓库内容当前 monorepo 中不可见。Layer 3 — Code-mode MCP 服务器核心思路一句话不要以 N 个工具暴露 authentik 的 API而是暴露可搜索的 OpenAPI spec 一个代码沙箱让 Agent 对着一个经过认证的ak.request(...)辅助函数写代码。这就是 code-mode 模式Cloudflare、Ronacher 提出——LLM 写代码远比发工具调用在行而且代码面把数百端点的 API 折叠成一个固定的约 3 工具、token 占用近乎不变的表面它不会随 API 增长而增长且免费跟随运行实例的版本。三个工具v1 与 v2 共用search(query)— 查询解析后的schema.yml所有$ref已内联只返回匹配的操作method path summary param / request / response 的 schema 切片。这是唯一随 API 规模伸缩的输出且返回切片从不返回整份 spec。它取代了此前find_endpoint/describe_endpoint这对工具——search直接返回 Agent 构造调用所需的参数/响应 schema。execute(code)— 在沙箱中运行 Agent 的 JS/TS沙箱唯一能力是一个绑定的ak.request(method, path, { query, body })辅助函数。只读拒绝任何非 GET 动词。execute_write(code)— 同一个沙箱完整ak.request所有动词。每次调用都需要确认。因为它也携带读操作所以一条查找→创建→绑定的混合链路可以作为一个确认块运行——code-mode 的可组合性得以保留。工具名本身也在审计轨迹中表明了意图。Agent 循环示意search(captcha stage)→ 读取端点 → 写一个调用ak.request(...)的代码块按需链式调用放进execute或execute_write。v1 — 本地 stdio 服务器可构建目标位于authentik-agent-marketplace/mcp-servers/code-mode/npm workspace 已搭好脚手架.mcp.jsonSessionStart依赖安装钩子已存在配置/认证AUTHENTIK_URLAUTHENTIK_TOKEN环境变量社区authentik-mcp验证过的部署模型。token 携带管理员自己的权限。Schema 来源启动时拉取AUTHENTIK_URL/api/v3/schema/让发现逻辑总是匹配运行实例的版本另有内置schema.yml作为兜底。这正是零维护属性——发现逻辑跟随实例这里无需再生成任何东西。沙箱——绑定即边界进程内node:vm/worker_thread全局对象剥离到只剩akconsole——没有fs没有通用fetch。ak.request是唯一的出口在execute中它仅限 GET。对抗性隔离刻意做弱因为信任模型是管理员用自己的 token 对自己的实例运行代码——Agent 本来也能通过任何精选调用做同样的事所以真正的控制是绑定只读默认 写入闸门而不是 VMRonacher 的观点。写入闸门execute_write触发 MCP 确认elicitation后才运行批准后仅该次调用写武装。每次execute_write都在本地记录日志。暴露的工具只有search、execute、execute_write。goauthentik/api不是关键路径ak.request是对schema.yml路径的通用认证 fetch生成的客户端Configuration/runtime 只是可选的传输便利不是调用面本身。v2 — authentik 原生 OAuth 端点已设计v1 验证后构建这是 authentik 作为身份提供商的天然优势几乎 1:1 映射到 enterprise-mcp 参考架构传输authentik 在产品内提供远程 MCP 端点HTTP/SSE如/mcp。认证MCP 客户端向 authentik 自身执行 OAuthauthentik 就是 OIDC 提供方——没有 API token 交接。Agent以已认证用户的身份行动。授权 authentik 自己的 RBACak.request在服务端以用户身份运行authentik 现有的 per-object / role 权限决定代码能读写什么。无需发明新的 scope 系统——复用 authentik 已强制的内容。MCP 层的 OAuth scope 仍可作为execute_write的粗粒度开关。沙箱服务端运行因此有真正的隔离可用isolate/worker 池不像 v1 的进程内 VM。审计每次execute/execute_write写入 authentik现有的事件日志——与events-monitoring管理技能查询的是同一条轨迹。设计文档给出的诚实警告v2 是产品/后端工作、随 release 门控有真实的安全面面向公众的代码执行挂在 IdP 后面。它是路线图设计必须由 v1 先行验证——在 v1 的 captcha 转折测试通过之前不要启动它。验收测试给我的登录流加验证码这一条混合任务能锻炼完整的 L1→L2→L3 回路也是大规模铺开前的门禁。用 code-mode 的术语讲flows-stages技能解释 stages/flows 概念内容来自 Layer 1 发布的页面.mdAgent 调用search(captcha stage, flow stage binding)写出一个execute_write块创建 captcha stage、找到目标 flow、POST 绑定——一次确认调用没有 per-endpoint 工具。MVP 可以对着一个 mock 服务器和一小片schema.yml切片运行。它验证的是schema 可搜索、代码可写、确认闸门可用三个层真正串起来。构建顺序依赖排序设计文档给出 10 步、含 4 个门禁的推进路线核心逻辑是先索引、后载荷、再技能、最后原生端点L1 — 核心索引 全文postBuild插件生成/llms.txt、topic/llms.txt、/llms-full.txtdocs 站点。关键路径。 门禁 — 索引健全性对真实 docs 快照——每个链接可解析、分组正确、全文包含内容。L1 — 每页.mdpartial 解析 指令剥离所有索引链接指向.md。关键路径。 门禁 — 内容质量抽 5 个不同类型的页面——无残留 import、无徽章杂物、Markdown 可读喂给 LLM 确认它能列出步骤。L2 —ak-docs技能骨架入口 URL 遍历-拉取方法。门禁 2 修复入口 URL 后即可并行。L3 v1 — code-mode 服务器核心search基于schema.ymlexecute只读沙箱execute_write需确认。可与 L2 并行只依赖 spec在转折测试关键路径上。 门禁 — captcha MVP 端到端转折点Agent 走 L2 → 读 captcha.md→searchspec → 写一个execute_write块mock 服务器即可。失败时诊断的是 schema/散文清晰度而不是工具。L1 — integrations 子域。设计文档标注已随 PR #23360 一起上线。L2 — 把ak-admin/ak-dev技能接到llms.txt入口L2→L1并加 code-mode 转向行L2→L3。可并行。L3 v2 — authentik 原生 OAuth 端点。只有v1 转折点通过后才做产品/后端投入单独 spec 计划。横切关注点安全、分发与维护安全v1本地 stdio 把管理员 token 留在自己的环境里沙箱只暴露ak无fs/fetchexecute仅 GETexecute_write每次调用确认并记日志。绑定即边界。v2对 authentik 做 OAuth授权是 authentik 自己在用户身份下的 RBAC每次调用都审计进事件日志。分发Claude Code Cursor 的 manifest 已在 marketplace 中ak-admin/ak-dev两个插件同时服务两者。维护论点docs.md 索引和 API 面对实时schema.yml的search每个 release 都直接来自 authentikL2 是薄胶水L3 没有 per-endpoint 代码要打补丁。稳态人工维护趋近于零。待规划阶段解决的开问题设计文档保留了明确的开放问题可作为后续实施的路线图注记L3search如何对schema.yml的操作做排序/过滤对 pathsummarytags 做关键词匹配每次命中返回多少 schema 切片而不撑爆上下文。L3node:vmvsworker_thread的最终选择全局如何剥离到只剩akconsoleexecute_write的 MCP 确认elicitation如何在 Claude Code / Cursor 之间呈现。L3ak.request的传输——纯认证fetchvsgoauthentik/api的Configurationruntime启动时拉取/api/v3/schema/vs 内置schema.yml兜底如何选择。L2 接线确认每个ak-admin技能的单条转向行以及稳定的llms.txt入口 URL只依赖已上线的 Layer 1。结语这套架构的核心价值可以浓缩为三句话docs 教概念Layer 1 Layer 2code-mode 执行动作Layer 3而两个检索面都由 authentik 每个 release 自动再生——Agent 的知识不再依赖最后一次训练时点的快照而是始终跟随运行实例的当前版本。对于要复刻这套模式的团队Layer 1 是唯一在仓库内完整落地的部分其 llms-txt 插件 从postBuild路由解析、partial 内联、指令剥离到三级索引输出提供了可以直接参照的完整实现样例。【免费下载链接】authentikThe authentication glue you need.项目地址: https://gitcode.com/GitHub_Trending/au/authentik创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价