数据与分析

知识库

一批文档的集合,智能体可以按语义检索并带引用地引述它们。这就是你阻止智能体编造你的政策的办法。

打开 数据 → 知识库. A 个集合 是一组命名的文档;智能体挂载的是集合,不是单个文件。

添加数据源

添加来源 用于一次性导入——文件、网页、代码仓库。 连接 则接入一个外部服务,按计划同步并保持去重。两种方式的文档都落到同一个集合、走同一条检索流水线。

文件上传

接受的扩展名,仅限:

支持的文件类型
.txt   .md   .markdown   .csv   .tsv   .log
.html  .htm  .xml        .yaml  .yml  .json
.rtf   .pdf  .docx

扫描版 PDF 什么都提不出来

我们做的是文本提取,不是 OCR。整页都是图片的 PDF 会产出零个分块,而智能体会用通识知识作答,且不会有任何异常提示。上传后请确认该文档的分块数不为零——这是一秒就能抓住这个问题的检查。

网页 / 抓取

给一个 URL,页面会被抓取并转为文本。适用于公开文档和政策页面。需要登录才能访问的页面抓不到。

GitHub 仓库

从仓库导入源码和文档,让智能体能回答关于某个代码库的问题。

接入的服务——Drive、Notion、SharePoint、Dropbox

连接 会打开一个覆盖四家提供商的向导。凭据都是粘贴进来的令牌(平台的 BYOK 模式——不需要注册 OAuth 授权页),保存时会对提供商做校验, 加密存储,且绝不回传给浏览器:编辑数据源时凭据字段是空的,保持为空就表示沿用已保存的内容。

提供商凭据同步什么是否沿用共享设置?
Google Drive访问令牌;无人值守同步需用刷新令牌 + OAuth 客户端 ID/密钥一个文件夹(子文件夹最多 5 层):Google 文档 / 表格 / 幻灯片导出为文本,另加文本格式文件是——按文件权限
Notion内部集成密钥;需把页面共享给该集成所列的页面 ID,以及所列数据库中的每一页否——该 API 不提供这类信息
SharePointEntra 应用注册:租户 ID + 客户端 ID + 密钥(Files.Read.All,需管理员同意)一个文档库或文件夹路径,文本格式文件是——按条目权限
Dropbox访问令牌;无人值守同步需用刷新令牌 + 应用 key/密钥一个文件夹路径(或全部);原生内容哈希让变更检测完全准确是——按文件成员,尽力而为

每个数据源,列举上限为 500 个条目 ,单个条目的文本上限为 40 万字符。凡是连接器看到但没有导入的——不支持的二进制文件、层级过深的文件夹、触到上限的——都会列在数据源卡片上 并附上原因,绝不会静默丢弃。

短期令牌和定时计划不搭

手动跑第一次同步,粘贴访问令牌没问题;但 Google 的大约一小时就过期,Dropbox 的最终也会轮换——凌晨三点跑的定时同步需要用刷新令牌那套字段。向导里写明了每个字段的用途。

定时同步——建索引但不产生重复

每个接入的数据源都有一个计划: 手动、每小时、每天或每周。定时同步在平台的维护轮次中执行(与刷新 BI 和 SaaS 数据的是同一个引擎),并通过抢占该数据源的下次运行时间,确保多个应用实例绝不会把同一个数据源同步两遍。

变更检测分两级,两级的存在都是为了让每小时的计划足够便宜:

  1. 1

    版本跳过——未变更的文件不下载

    提供商的变更标记(修改时间、修订号、原生哈希)会打在每个文档上。标记未变即 跳过,不做下载 ——一个 400 个文件的文件夹,重新同步的代价只相当于列举一次。
  2. 2

    内容跳过——文本没变就不重新生成嵌入

    移动文件、改权限、加评论都会让提供商更新修改时间。下载下来的文本会算哈希(sha256);若与已存的一致,就只刷新标记,文档 不重新分块、也不重新生成嵌入。嵌入的开销只跟随内容的真实变化,不跟随别的任何东西。

在提供商那边删掉的文件,这里对应的文档(及其分块)也会被删除。数据源卡片会把每次同步的结果显示为 +added ~updated =unchanged −removed;而数据库在(数据源,远端条目)上的唯一性约束保证了——即便上面所有机制都失效——也不可能出现重复文档。

同步状态

ok 表示一次干净的同步。 error 会原样给出提供商的拒绝信息——被吊销的令牌显示的是“Dropbox 401: invalid_access_token”,而不是“0 个文档”。 embed failed 表示文档已保存但语义索引没建完:在重新同步成功之前,这些文档的检索会回退到关键词搜索;无论如何所有者都会收到通知。

导入时会发生什么

file ──▶ extract text ──▶ split into chunks ──▶ embed each chunk ──▶ store
                             (few hundred words,      (vector = position
                              overlapping)             in meaning-space)

question ──▶ embed ──▶ nearest chunks ──▶ pasted into the prompt as [1] [2] …
从文档到可检索的分块。

分块 的影响比多数人以为的大。检索返回的是分块,不是文档——所以如果回答问题的那句话被切到了两个分块里,两个都答不好。分块之间有少量重叠来缓解这一点。

为什么这样设计

嵌入匹配的是 语义,而不是关键词:“我有多长时间可以寄回”能命中讲“30 天退货期”的段落,哪怕两者没有一个共同词。反过来说,语义相近但无关的文本也会得高分——这正是分块边界和重排序重要的原因。

由哪个模型生成嵌入

按集合在此设置: RAG 设置 → 嵌入。当你已接入 OpenRouter 时它就是默认选项,这样生成嵌入就不必和对话、文档生成、检索去抢同一份 OpenAI 配额——配额一耗尽,知识库检索也会跟着挂掉。内置的运维方 OpenAI 密钥是兜底,任何其他已接入、提供 OpenAI 兼容 /embeddings 端点的提供商也可以选来替代。

换模型意味着要重新生成嵌入

两个不同模型产出的向量不可比——用模型 B 的查询向量去搜模型 A 的分块不会报错,只会静默返回错误的匹配。所以每个文档在生成嵌入时都会记录当时的提供商与模型,提问也总是用该文档所用的那一套来生成向量。因此把集合切到新模型只影响此后新生成嵌入的文档:用 回填嵌入 把已有文档一并迁过去。

注意

向量存储固定为 1536 维。模型必须能输出这个维度——OpenAI 的 text-embedding-3-* 系列模型可按请求截断到任意维度。如果某个模型返回的维度不同,生成嵌入会带着明确提示失败,而不是写入无法使用的向量。

这就是为什么 OpenRouter 的默认选项是 openai/text-embedding-3-small ,而不是某个 NVIDIA nemotron 嵌入模型:它与内置密钥产出的 同一个 1536 维空间是同一个,所以为了摆脱耗尽的 OpenAI 配额而把集合切到 OpenRouter 不需要任何代价,已有分块也依然可检索。 nvidia/nemotron-3-embed-1b 和 nvidia/llama-nemotron-embed-vl-1b-v2 (既能嵌入文本也能嵌入图像)也可以选,但它们属于另一个向量空间——切过去就意味着整个集合要重新生成嵌入。

检索设置——真实的数值

设置项默认值取值范围说明
top-K51 – 8(硬上限)检索并拼进提示词的分块数量。要求超过 8 会被截到 8。
带重排序时的候选池3 × top-K,最多 20—配了重排序器时,第一轮会取更宽的候选,再重新打分收敛到 top-K。准确率的提升就来自这一步。
片段半径280 字符—答案下方的引用片段里,命中位置两侧各展示多少文本。

重排序

按智能体在此配置: 知识库 页签:一个 提供商 和 重排序模型 (例如 llama-nemotron-rerank-vl-1b-v2).

  • 成本 ——每次检索多一次模型调用。
  • 什么时候值得 ——集合里有大量近乎相同的段落:长合同、同一政策的多个修订版、一系列相似产品的说明书。
  • 什么时候不值得 ——文档彼此区分明显的小型集合。第一轮结果本来就对。

把集合挂到智能体上

  1. 1

    创建集合并往里导入内容

    把不相关的主题分到不同集合里——混在一起的集合,检索效果实测会更差。
  2. 2

    智能体构建器 → 知识库 → 关联它

    关联时会自动启用 kb_search 工具。
  3. 3

    在系统提示词里加上「必须有据可依」的要求

    少了这一条,模型会心安理得地退回通识知识,而你不会察觉。
  4. 4

    打开引用核查

    在护栏页签。当有可用来源却一条都没引用时,它会把该回答标出来——参见 护栏.
最小可用的知识库依据段落
Answer only from the provided sources. Cite them inline as [1], [2].
If the sources do not contain the answer, reply exactly:
"I don't have that in my documentation."
Never fill a gap with general knowledge.

每一轮对话之前都会自动检索,并插入带编号的引用。 kb_search 工具还允许智能体在回答过程中按需再检索,用于第一次读得不够的情况。

图检索

普通检索找的是与问题相似的分块。 图检索 还会顺着跨文档抽取出来的实体关系走,回答普通检索在结构上就答不了的问题——比如 “附录 B 的这条款影响到哪些供应商?”,因为没有任何单个分块同时包含问题的两半。

  1. 1

    构建图谱

    在该集合上打开「知识库 → 图谱」。这是对文档的另一轮处理,比较慢。
  2. 2

    启用该工具

    智能体构建器 → 工具 → kb_graph_search.

小心

启用 kb_graph_search 但没有先构建图谱,返回的会是空——而智能体会把「空」理解成「不存在这个信息」,而不是配置有问题。

共享与访问权限

集合默认仅所有者可见。管理员可以在此把 只读 访问权限授予某个用户或用户组: 访问控制;被共享的集合会显示一个 已共享 徽标,且接收方不能编辑它。

由于授权是在数据库层面强制执行的,智能体的检索会自动继承它——不存在第二套需要同步维护的权限。

按数据源的访问范围

接入的数据源多了一层更细的控制: 在 某人已经能看到的集合内部,它同步来的哪些文档是他可以检索的?每个接入的数据源从三种范围里选一种,在检索时强制执行——向量路径和关键词路径都一样,且在任何重排序模型看到文本之前:

范围谁能检索到这些文档
能看到该知识库的所有人默认。文档的行为与上传的文件完全一致——由集合的可见性决定。所有既有文档都是这种方式。
仅自己只有接入者本人,仅此而已——即便集合本身已被共享或授权也不例外。
沿用来源权限逐文档沿用提供商的共享设置:在 Drive / SharePoint / Dropbox 上被授权访问原文件的人(按邮箱或域名),在这里也能检索到它;其他人不能。带公开链接的文件仍然公开。
  • 所有者永远能检索到自己的文档,无论设的是哪种范围——你自己配的限制不会把你挡在自己的数据之外。
  • 失败时倾向于拒绝。 不提供共享信息的提供商(Notion 的 API 就不提供;没有成员列举能力的 Dropbox 套餐也是),其文档会保持仅所有者可见,同步统计会把它们计入,让这个结果可见。租户范围的链接(“组织内任何人”)除所有者外谁都匹配不到——从这里无法验证租户成员身份,而错误的拒绝可以补救,错误的放通不能。
  • 公开嵌入是匿名的。 嵌入的助手只能检索默认范围的文档(以及在提供商那边公开的文档)——绝不会碰「仅自己」或受 ACL 限制的内容,即便该嵌入是以所有者的账号运行的。

当答案不对时

按顺序逐条排查。原因几乎总在其中。

#检查项说明什么
1该文档的分块数是否不为零?为零说明提取什么都没得到——几乎总是扫描版 PDF。
2在追踪里打开该次运行:有检索到任何内容吗?为空说明该集合没关联到这个智能体,或者提问的向量离集合里的一切都很远。
3检索到的分块主题对得上,但不是正确的那一段?问题在分块或措辞。试试重排序器;也可以考虑重新上传一份结构更好的原文。
4检索正确但被无视了?系统提示词没有要求必须有据可依,或者另一个工具的结果更抢眼。
5答案下方列出了知识来源吗?当答案引用了它们,或者没有别的依据时,它们就会出现。如果是网页搜索给出了答案,你会看到链接——这是正确行为,不是缺陷。

让效果更好

  • 优先用结构化的文档。 标题能给切分器有意义的边界,一整片不分段的文字给不了。
  • 按主题拆分,而不是按部门。 一个主题一个集合,检索效果好过把所有东西塞进一个集合。
  • 删掉已被取代的旧版本。 同一政策的三个修订版检索起来不分彼此,智能体无从判断哪个是现行版本。这是「自信地给出过期答案」最常见的单一原因。
  • 数字放到表里。 如果问题本质上是算术,它该归 数据目录 ——检索只引述文字,它不做计算。
  • 给文档起有描述性的名字。 文档名会出现在读者看到的引用里,所以 refund-policy-2026.pdf 胜过 final_v3.pdf.