@carrot-foundation/ai-discovery

中文文档
2.0.1发布于 2026/11/06Apache-2.0TypeScriptESM + CJS构建来源已验证近 30 天下载 5039

AI为胡萝卜网络所发现的原始人:JSON-LD,llms.txt,机器人和一面Markdown镜.

中文使用文档
文档目录23 节
  1. 状态
  2. 安装
  3. 它提供什么
  4. 快速启动
  5. 在页面上添加 JSON- LD
  6. 生成 AI 意识机器人.txt
  7. 分类人工智能机器人流量
  8. 从 1.x 移动
  9. 构建 llms.txt 文件
  10. 显示 Markdown 镜像路由
  11. 在犬科URL上为Markdown服务
  12. 胡萝卜在各地都一样
  13. 注册只读 MCP 工具
  14. 构建关键词搜索索引
  15. 提交索引现在 URL 批次
  16. 查询公共文件词汇表 MCP
  17. JSON-LD 构建器
  18. 设计原则
  19. 项目结构
  20. 发展
  21. 释放
  22. 相关胡萝卜项目
  23. 许可证

@carrot-foundation/ai-发现

npm version CI License

人工智能发现原始人为胡萝卜网络: Schema.org JSON-LD 建设者, llms.txt 人工智能发电机 robots.txt 帮手,马克倒镜路线, 只读 MCP 脚手架、 关键字搜索、 IndexNow 提交助手和 a 公开的docs词汇客户端.

当公共胡萝卜网站或兼容的生态系统工具需要时使用此软件包 向搜索引擎、AI爬行器、LLM客户披露相同内容, 和人类开发者.

状态

释放- 触发合并到 main cI 成功后自动发布, 所以 只有在克里斯蒂亚诺审查过包裹PR和柏油丸后,它们才合并.

安装

pnpm add @carrot-foundation/ai-discovery
# or
npm install @carrot-foundation/ai-discovery

需要节点.js >=22. 一揽子措施为无害环境管理优先,船舶为共同JS双向 仍在使用的消费者的产出 require()。 。 。 .

它提供什么

模块导入路径目的
JSON-LD( 日语)@carrot-foundation/ai-discovery/jsonld为公共页面构建已验证的 Schema.org 图表节点 .
机器人@carrot-foundation/ai-discovery/robots生成 robots.txt 对已知的AI bots 的政策.
页:1@carrot-foundation/ai-discovery/llms-txt生成 /llms.txt 财务报告和审定财务报表 /llms-full.txt 样式 Markdown 文件.
标记下镜像@carrot-foundation/ai-discovery/md-mirror创建一个 Request -> Response Markdown路由处理器.
MCP 服务器@carrot-foundation/ai-discovery/mcp-server注册只读工具并处理可流式HTTP生命周期.
奥拉马搜索@carrot-foundation/ai-discovery/orama构建、搜索、序列化并恢复仅关键词索引.
现在索引@carrot-foundation/ai-discovery/index-now将 URL 批次规范化、 块化、 提交和汇总 .
词汇客户端@carrot-foundation/ai-discovery/glossary用缓存查询公共胡萝卜 Docs MCP词汇工具.
身份@carrot-foundation/ai-discovery/identity峡谷胡萝卜 Organization 创建者 Person。 。 。 .
根命名空间@carrot-foundation/ai-discovery所有模块的命名导出 .

快速启动

在页面上添加 JSON- LD

import { carrotOrganization } from "@carrot-foundation/ai-discovery/identity";
import {
  article,
  compose,
  website,
} from "@carrot-foundation/ai-discovery/jsonld";

const graph = compose([
  carrotOrganization(),
  website({
    name: "Carrot Documentation",
    url: "https://docs.carrot.eco",
    inLanguage: ["en", "pt-BR"],
    searchUrlTemplate: "https://docs.carrot.eco/search?q={query}",
  }),
  article({
    url: "https://docs.carrot.eco/docs/concepts/dmrv",
    headline: "Digital Measurement, Reporting and Verification",
    description:
      "How Carrot structures source data, evidence, and verification.",
    datePublished: "2026-04-15",
    dateModified: "2026-05-01",
    author: {
      name: "Jane Doe",
      url: "https://example.com/jane",
    },
    inLanguage: "en",
    image: "https://docs.carrot.eco/og/docs/concepts/dmrv.png",
  }),
]);

const jsonLd = JSON.stringify(graph);

渲染器 jsonLd 在一个 application/ld+json 脚本标记. 构建者验证输入 在返回平原对象之前使用 Zod, 所以无效的 URL, 日期, 语言标记, 或缺少所需的字段 .

生成 AI 意识机器人.txt

import { buildRobots } from "@carrot-foundation/ai-discovery/robots";

export function GET() {
  return new Response(
    buildRobots({
      allow: "fetchers-only",
      sitemap: "https://docs.carrot.eco/sitemap.xml",
      disallowPaths: ["/api/", "/internal/"],
    }),
    {
      headers: {
        "content-type": "text/plain; charset=utf-8",
      },
    },
  );
}

allow 支持四种模式:

模式行为
all-ai-bots允许每个已知的AI机器人,每个被明确命名. 内容站点政策.
fetchers-only屏蔽训练爬行者并允许搜索索引和用户获取器.
block-all-ai封锁每个机器人 AI_BOTS;其他爬行者可以留下来.
disallow-all关闭整个网站 每一个爬行者, 对于认证的应用程序.

输出每瓶有一组,每组以注释为首,在 User-agent: * 组合。 一个爬行者只服从最具体的群体命名它, 这样 disallowPaths 重复每个允许的组. sitemap 可选; 省略 无索引的站点 :

buildRobots({ allow: "disallow-all" });
// User-agent: *
// Disallow: /
// ...one `Disallow: /` group per AI bot intent

无模式名称 Applebot苹果在Spotlight后面的普通爬行者 Siri和 Safari搜索,所以它跟随 User-agent: * 组:仅 disallow-all 从苹果搜索中删除一个站点. 苹果也可能训练其基础模型 在Applebot爬行并用它来解答AI生成的答案。 开除 页:1 Applebot-Extended 符号,作为每个模式,但 all-ai-bots 选择退出 该培训;a nosnippet 元标记保存这些答案的一页 (单位:千美元)苹果公司) (中文(简体) ).

机器人.txt只绑住那些尊重它的爬行者. 抓取者和代理人 用户的请求可能不会, 代理在 AI_AGENTS (谷歌代理公司) ChatGPT代理)没有机器人代号,因此没有模式命名. disallow-all 无法与 omitWildcard,则未知 allow 数值抛出.

分类人工智能机器人流量

AI_BOTS 列出 AI bots 机器人.txt 可以地址,以及 AI_AGENTS 大赦国际 特工不能这样 两者的条目:

外地含义
name, (中文(简体) ), operator机器人是它的运营商命名它.
intenttraining, (中文(简体) ), search-index, (中文(简体) ), user-fetch, (中文(简体) ), agent,或 ai-browser (单位:千美元)AI_BOT_INTENTS) (中文(简体) ).
robotsToken机器人们.txt User-agent 符号 . AI_BOTS 只有条目.
userAgentPatterns在请求中识别机器人的大小写不敏感子字符串 User-Agent 头曰.
vercelBotNameVercel 的价值 bot_name 维度,当Vercel的被验证的机器人目录列出时.
source操作员的文件被核对了.

仅限机器人控制符号,例如 Google-Extended 财务报告和审定财务报表 Applebot-Extended 有个 robotsToken 但是没有 userAgentPatterns:它们从未出现在请求中. 发送一个股票浏览器用户代理, 如 ChatGPT 代理的代理, 已知 只有通过 vercelBotName. AI 浏览器,如 ChatGPT Atlas 和 迷惑彗星 发送 stock Chromium 用户代理, 因此没有条目可以识别它们 .

import {
  classifyUserAgent,
  findByVercelBotName,
} from "@carrot-foundation/ai-discovery/robots";

classifyUserAgent(request.headers.get("user-agent"))?.intent;
// "user-fetch" for ChatGPT-User, undefined for a browser

findByVercelBotName("chatgpt-operator")?.intent; // "agent"

两个搜索 AI_BOTS 财务报告和审定财务报表 AI_AGENTS 返回一个 AIRegistryEntry页:1 AIBotEntry 何时 robotsToken 设定, a AIAgentEntry 否则。 缩小它 与 entry.robotsToken !== undefined; 一个 in 检查不缩小。 一个用户 特工是自报的 校验( 已公布的 IP 范围, 逆向 DNS, Web Bot) 在信任它之前,我先说.

1.2起的球场仍保留在每起 AI_BOTS 条目并作折旧: userAgent 等于 robotsToken,以及 kind 折叠 agent 财务报告和审定财务报表 ai-browser 输入 user-fetch。 。 。 . AI_AGENTS 条目中既没有.

从 1.x 移动

第2版修改了机器人模块:

  • buildRobots() 每瓶发出一组 而不是每瓶发出一组. 每个组以一个 # 注释行和列表数 User-agent 线条 在其规则之前,如RFC 9309允许:

    # AI training crawlers
    User-agent: GPTBot
    User-agent: ClaudeBot
    ...
    Disallow: /
    

    在空白行上分割输出并读取一个的代码 User-agent 百分比 块断。 测试每个区块的第一行 现在第二行是 # AI training crawlers 作为用户代理 User-agent: GPTBot 作为它的规则。 分析组代替: 每组 User-agent 线条在块中共享遵循的规则。 一个被封锁的团体携带 仅限 Disallow: /· ; disallowPaths 在允许的组合中重复, 其中 留下每个机器人的有效政策.

  • AI_BOTS 以意向命令,所以按索引读取条目的代码得到一个 不同的机器人。 查找条目 robotsToken 换句话说.

  • AI_BOTS, (中文(简体) ), AI_AGENTS 他们的进入被冻结。 类型脚本已键入 他们 readonly在 Java 脚本中, push 和其他变异数组方法 丢出一个 TypeError; 指定一个字段以严格模式投掷(ES模块, "use strict"),被默默地忽略在草率的剧本中.

  • AIBotEntry 拥有需要的新字段 : name, (中文(简体) ), intent, (中文(简体) ), robotsToken, (中文(简体) ), userAgentPatterns 财务报告和审定财务报表 source。构建自己的条目的代码必须设置 他们.

  • 登记册增加了Amazonbot和Meta-ExternalAgent(培训), Amzn-SearchBot、Meta-WebIndexer和DuckAssistBot(搜索索引),以及 Meta-ExternalFatcher和Amzn-User(用户获取). fetchers-only 现在的块 两个新的训练爬行者,和 block-all-ai 7个街区.

  • buildRobots() 丢入未知的 allow 值,并持续 disallow-all 结合 omitWildcard。 。 。 . RobotsAllowMode 收益 disallow-all,所以一个 详尽无遗 switch 因为它需要新的案子.

  • 没有机器人.txt 令牌(Google-Agent, ChatGPT 代理)的代理被列出于 新建 AI_AGENTS中,没有 AI_BOTS。 。 。 .

  • userAgent 财务报告和审定财务报表 kind 继续 AIBotEntry,以有利于 robotsToken 财务报告和审定财务报表 intent。 。 。 .

构建 llms.txt 文件

import {
  buildFull,
  buildIndex,
} from "@carrot-foundation/ai-discovery/llms-txt";

const index = buildIndex({
  site: {
    name: "Carrot Documentation",
    url: "https://docs.carrot.eco",
    tagline: "The public reference for the Carrot Network.",
  },
  sections: [
    {
      title: "Concepts",
      urls: [
        {
          title: "dMRV",
          url: "https://docs.carrot.eco/docs/concepts/dmrv",
          description:
            "Digital Measurement, Reporting and Verification in Carrot.",
        },
      ],
    },
  ],
});

const full = buildFull({
  pages: [
    {
      title: "dMRV",
      url: "https://docs.carrot.eco/docs/concepts/dmrv",
      markdown: "# dMRV\n\nDigital Measurement, Reporting and Verification.",
    },
  ],
});

buildIndex() 用于压缩的 Markdown 文本和格式 索引文件. buildFull() 以源 URL 注释连接页面 所以LLM客户端可以追踪到每个街区回它的Cononical页面.

显示 Markdown 镜像路由

import { createMdMirrorRoute } from "@carrot-foundation/ai-discovery/md-mirror";

export const GET = createMdMirrorRoute<{ slug?: string[] }>({
  async load({ params }) {
    const slug = params.slug?.join("/") ?? "index";
    const page = await loadPageAsMarkdown(slug);

    if (page === null) return null;

    return {
      markdown: page.markdown,
      sourceUrl: `https://docs.carrot.eco/docs/${slug}`,
    };
  },
});

路径帮助返回 404 何时 load() 返回时 null,否则服务 text/markdown; charset=utf-8组合 x-source-url,并应用缓存控制 头曰. 默认缓存策略是 public, max-age=300, s-maxage=86400。 。 。 .

在犬科URL上为Markdown服务

prefersMarkdown(accept) 阅读请求 Accept 标题并决定是否 cononial URL 使用页面的 Markdown 而不是它的 HTML 回答 :

import { prefersMarkdown } from "@carrot-foundation/ai-discovery/md-mirror";

prefersMarkdown("text/markdown"); // true
prefersMarkdown("text/markdown, text/html;q=0.9"); // true
prefersMarkdown("text/markdown, */*"); // true: named beats a wildcard
prefersMarkdown("text/html, text/markdown"); // false: a named tie keeps HTML
prefersMarkdown("*/*"); // false
prefersMarkdown(null); // false

它尊重q值,让最具体的媒体范围取胜. 马克倒数取胜 何时 text/markdown 重过重 text/html同等重量 0以上,名称范围 text/markdown 击出 text/html 仅匹配 结束 text/* 或者说 */*这样 text/markdown, */* 得到马克德。 相同重量 当两者均被命名时,或当两者单独通过通配符匹配时,保留 HTML。 A 类 标出 0 的下方重, 带有任何畸形区域或缺少标题的页眉 保留 HTML 。 仅在类型和子类型上匹配的范围:参数 q 被忽略,所以 text/markdown;profile=x 计数为 text/markdown他们必须 仍然身材不错 name=value 双对,所以 text/markdown;foo 错误 并保留 HTML。 信头读取为发送: 类型和子类型取 ASCII 令牌 只匹配 A- Z 上的不区分大小写, 只匹配空格和标签 计为白空格,所以一个未破解的空格或开尔文符号是错的 保留 HTML。 发送 Vary: Accept 取决于它的反应.

胡萝卜在各地都一样

这个 identity 每个胡萝卜网站都声称:

import {
  CARROT_ORGANIZATION,
  carrotOrganization,
} from "@carrot-foundation/ai-discovery/identity";
import { compose, website } from "@carrot-foundation/ai-discovery/jsonld";
import { buildIndex } from "@carrot-foundation/ai-discovery/llms-txt";

const graph = compose([
  carrotOrganization(),
  website({
    name: "Carrot Documentation",
    url: "https://docs.carrot.eco",
    inLanguage: ["en", "pt-BR"],
  }),
]);

const index = buildIndex({
  site: {
    name: CARROT_ORGANIZATION.name,
    url: "https://docs.carrot.eco",
    tagline: CARROT_ORGANIZATION.description,
  },
  sections: [],
});

carrotOrganization() 返回时 Organization 节点: 名称 Carrot备注 名称 Carrot Foundation一个标志,胡萝卜自己的简介 sameAs,则 @id 胡萝卜网站已经出版。 其创始人伊恩·麦基被嵌入了 Person (单位:千美元)carrotFounder()上面有他的个人资料.

注册只读 MCP 工具

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { z } from "zod";
import { registerReadOnlyTool } from "@carrot-foundation/ai-discovery/mcp-server";

const server = new McpServer({ name: "carrot-docs", version: "1.0.0" });

registerReadOnlyTool(server, {
  name: "search_docs",
  title: "Search docs",
  description: "Search public Carrot documentation.",
  inputSchema: {
    query: z.string(),
  },
  handler: (input) => ({
    results: searchPublicDocs(input.query),
  }),
});

registerReadOnlyTool() 对每个工具应用相同的安全说明: readOnlyHint: true, (中文(简体) ), destructiveHint: false, (中文(简体) ), idempotentHint: true,以及 openWorldHint: false。 。 。 . createMcpHttpHandler() 提供通用流程 HTTP 请求使用应用提供的速率键的生命周期,主机的遥测,以及 工具名允许列表如此原始的正文, 原始的 IP 密钥, 信头, 以及快速文本 文库不释放.

构建关键词搜索索引

import {
  buildSearchIndex,
  searchIndex,
  serializeSearchIndex,
} from "@carrot-foundation/ai-discovery/orama";

const index = await buildSearchIndex([
  {
    id: "en/blog/massid",
    title: "MassID launch",
    url: "https://www.carrot.eco/en/blog/massid",
    text: "MassID traceability for circular economy data.",
    locale: "en",
    kind: "post",
  },
]);

const results = await searchIndex(index, { query: "massid", limit: 5 });
const serialized = serializeSearchIndex(index);

Orama 包装器只在 1.1.0嵌入和交叉财产 联邦有意留待以后阶段.

提交索引现在 URL 批次

import {
  chunkIndexNowUrls,
  formatGitHubActionsSummary,
  submitIndexNowUrls,
} from "@carrot-foundation/ai-discovery/index-now";

const urls = [
  "https://www.carrot.eco/en",
  "https://www.carrot.eco/en/blog/massid",
];

const indexNowKey = process.env.INDEXNOW_KEY;
if (!indexNowKey) {
  throw new Error("INDEXNOW_KEY is required");
}

for (const batch of chunkIndexNowUrls(urls)) {
  const result = await submitIndexNowUrls({
    host: "www.carrot.eco",
    key: indexNowKey,
    keyLocation: "https://www.carrot.eco/indexnow-key.txt",
    urls: batch,
    fetch,
  });

  console.log(formatGitHubActionsSummary(result));
}

normalizeIndexNowUrls() 在所配置的主机下只保留唯一 HTTPS URL . 非-2xx响应返回打入的失败,但不包括原始响应机构. 设定 INDEXNOW_KEY 打电话前 submitIndexNowUrls()。 。 。 .

查询公共文件词汇表 MCP

import {
  createDocsGlossaryClient,
  createMemoryGlossaryCache,
  getGlossaryTerm,
} from "@carrot-foundation/ai-discovery/glossary";

const glossary = createDocsGlossaryClient({
  endpoint: "https://docs.carrot.eco/mcp",
  fetch,
  cache: createMemoryGlossaryCache({ ttlMs: 60_000 }),
});

const trc = await getGlossaryTerm(glossary, { term: "TRC", locale: "en" });

术语表客户端是针对公众的 get_glossary_term 工具。 没有 Authorization 默认标题和缓存 提供了缓存.

JSON-LD 构建器

JSON-LD模块输出用于公共页面类型胡萝卜站点的构建器 最常见的情况是:

构建器Schema.org 节点
apiReference()APIReference 带有 WebAPI 目标.
article()BlogPosting, (中文(简体) ), Article, (中文(简体) ), TechArticle,或 HowTo。 。 。 .
breadcrumbList()BreadcrumbList。 。 。 .
definedTerm()DefinedTerm。 。 。 .
definedTermSet()DefinedTermSet。 。 。 .
faqPage()FAQPage。 。 。 .
organization()Organization,可选 alternateName 财务报告和审定财务报表 founder。 。 。 .
person()Person,带有可选稳定 id。 。 。 .
podcastEpisode()PodcastEpisode,带有可选媒体和平台链接.
podcastSeries()PodcastSeries,有可选的网络反馈和平台链接.
speakable()SpeakableSpecification。 。 。 .
website()WebSite,可选 SearchAction。 。 。 .

使用 compose(nodes) 用于条形输出形状:

{
  "@context": "https://schema.org",
  "@graph": []
}

使用 schemaId(siteOrigin, kind, payload?) 当你需要决定 @id 自定义节点的值.

设计原则

  • 建设者是纯. 它们返回字符串或平庸对象而不执行 我/欧.
  • 验证通过Zod schemas在边界上发生.
  • 缺席时省略可选字段,而不是设置为 undefined。 。 。 .
  • AI bot政策是明确的,并产生于一个经过审查的清单.
  • Markdown 输出保留了可追溯性源 URL.
  • 每个顶级模块可作为小消费者的子路径输出 捆绑.

项目结构

src/
  index.ts          # Root namespaced exports
  jsonld/           # Schema.org JSON-LD builders and validation helpers
  robots/           # AI bot registry and robots.txt builder
  llms-txt/         # llms.txt index and full-content builders
  md-mirror/        # Request -> Response Markdown route helper
  mcp-server/       # Read-only MCP registration and HTTP lifecycle helpers
  orama/            # Keyword search index helpers
  index-now/        # IndexNow URL normalization and submission helpers
  glossary/         # Carrot Docs glossary MCP client
  identity/         # Canonical Carrot Organization and founder
test/
  jsonld/
  robots/
  llms-txt/
  md-mirror/
  mcp-server/
  orama/
  index-now/
  glossary/
  identity/

新增顶级模块时, 保持公用表面同步 :

  1. 添加导入并需要成对到 package.json exports。 。 。 .
  2. 将模块条目添加到 tsup.config.ts。 。 。 .
  3. 添加名称空格再导出到 src/index.ts。 。 。 .
  4. 镜像测试 test/<module>/。 。 。 .

发展

pnpm install --frozen-lockfile
pnpm test
pnpm build
pnpm type-check
pnpm lint
pnpm format:check
pnpm spell-check
pnpm check

pnpm check 是完整的本地门和镜像 CI:格式、线条、类型检查, 拼写检查、测试、构建、出口类型检查、干洗包装和生产 审计.

有用的焦点命令 :

pnpm vitest run test/jsonld/article.test.ts
pnpm vitest -t "robots"
pnpm check-types-exports
pnpm pack --dry-run

释放

释放是自动的,语义上从 main 之后 Check Code 工作流程成功推动. 手动 workflow_dispatch 保存为回收 路径.

不要颠倒 version 手动. 留下来 0.0.0-development; 语义释放 确定从常规委员会发布的版本.

许可证

Apache 许可证 2.0。见 通知 为归属, 商标和保函.

版本与发布记录

@carrot-foundation/ai-discovery 共发布 7 个版本,首次发布于 2026/05/08;过去 12 个月发布了 7 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
2.0.1latest2026/11/063 天前
2.0.02026/10/2020 天前
1.2.02026/05/145 个月前
1.1.22026/05/135 个月前
1.1.12026/05/096 个月前
1.1.02026/05/086 个月前

关于 @carrot-foundation/ai-discovery 的常见问题

@carrot-foundation/ai-discovery 是什么?

AI为胡萝卜网络所发现的原始人:JSON-LD,llms.txt,机器人和一面Markdown镜.

如何安装 @carrot-foundation/ai-discovery?

在项目目录运行 npm install @carrot-foundation/ai-discovery,或使用 pnpm add / yarn add / bun add。

@carrot-foundation/ai-discovery 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@carrot-foundation/ai-discovery 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@carrot-foundation/ai-discovery 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=24。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@carrot-foundation/ai-discovery 可以商用吗?

@carrot-foundation/ai-discovery 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

@carrot-foundation/ai-discovery 的下载量有多少?

根据 npm 官方下载统计,@carrot-foundation/ai-discovery 在 2026/10/09 – 2026/11/07 这 30 天内被下载 5,039 次,日均约 168 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@carrot-foundation/ai-discovery 还在维护吗?

最新版本 2.0.1 发布于 2026/11/06(3 天前);至今共发布 7 个版本,其中过去 12 个月发布了 7 个;首次发布于 2026/05/08。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。