For AI agents: the complete documentation index is available at https://devcodex-labs.github.io/capability-graph/llms.txt, the full documentation bundle is available at https://devcodex-labs.github.io/capability-graph/llms-full.txt, and this page is available as Markdown at https://devcodex-labs.github.io/capability-graph/integrations/knowledge-reader.md.

KnowledgeReader 接入

远程来源仅合同

内置本地 Reader 优先处理 relative-file Document。自定义 KnowledgeReader 只用于其他来源:

下面为接口节选。Reader 按已有引用精确读取全文;Retriever 则根据查询在已选知识中返回片段。要读取一篇远程指南只需 Reader,不必引入索引或模型。

interface KnowledgeReader {
  readonly id: string;
  canRead(ref: KnowledgeRef): boolean;
  read(
    ref: KnowledgeDocumentRef,
    context: KnowledgeReadContext,
    budget: { maxBytes: number }
  ): Promise<{
    bytes: Uint8Array;
    contentType: string;
    contentId: string;
    source: string;
  }>;
}

canRead() 必须同步、稳定。Reader 返回的 source 要与声明 locator 一致,并严格遵守字节预算;网络连接和资源释放归 Reader 所有。

KnowledgeReadContext.sourceContext 只用于本地读取,不能序列化进 Retriever 请求或公开响应。远程引用存在但无 Reader 时返回 CG_READER_UNCONFIGURED

HTTP Reader 骨架

下面的类型可编译,但 readBounded 是接入方必须提供的传输实现,不代表主包已有 HTTP 后端。它应在接收数据时累计字节、超限立即终止,并负责访问策略、认证、重定向和超时;不能先下载任意大小的正文再检查长度。

reader-skeleton.ts
import { createHash } from 'node:crypto';
import type { KnowledgeReader } from '@devcodex/capability-graph';

export function createHttpReader(
  readBounded: (url: string, maxBytes: number) => Promise<Uint8Array>
): KnowledgeReader {
  return {
    id: 'acme-http-reader',
    canRead(ref) {
      return ref.kind === 'document' && ref.locator.type === 'http';
    },
    async read(ref, _context, { maxBytes }) {
      if (ref.locator.type !== 'http') throw new Error('Unsupported locator');
      const bytes = await readBounded(ref.locator.url, maxBytes);
      if (bytes.byteLength > maxBytes) throw new Error('Document exceeds byte budget');
      return {
        bytes,
        contentType: 'text/plain; charset=utf-8',
        contentId: `k:${createHash('sha256').update(bytes).digest('hex').slice(0, 16)}`,
        source: ref.locator.url
      };
    }
  };
}

将对象放入 OpenConfig.readers;Core 对非本地引用选择首个 canRead() 匹配的 Reader。本例只处理 UTF-8 文本,若传输返回 HTML/二进制,应按你的知识来源合同拒绝或扩展 MIME 处理,而不是无条件当作指南。

bytes 是正文原始字节,V1 的 contentIdk: 加 SHA-256 十六进制值的前 16 位;Core 会重新计算核验。source 必须等于声明的 URL,不能随意换成缓存路径或重定向地址。maxBytes 单位为字节,不能用字符串长度替代。

成功时 readDocuments() 的成功槽位返回 textbyteLengthcontentId 和原 source。伪造哈希/source 会得到 CG_ADAPTER_CONTRACT_INVALID,Reader 抛错投影为 CG_READER_UNAVAILABLE;批量读取中检查每项 ok。Reader 拥有网络资源,Core 不负责关掉它的连接池。