跳到内容

Knowledge Starter

受众:开发者 摘要:项目知识扫描 + Markdown heading-aware 切片 + 关键词 / 本地向量 / hybrid 检索 + Ask 上下文返回。默认不依赖向量数据库或外部模型。

何时使用

场景建议
搜索团队知识、公开业务内容和受控知识源Knowledge.search(...)
给 AI Bot / 客服 / 文档助手提供检索上下文Knowledge.ask(...) 返回 snippet + citations
AI Task Handler 找资料Knowledge.search → Pipeline 组 prompt → 模型 Provider
需要轻量向量检索 / 语义相似使用默认 memory 向量库和 mode=vector / mode=hybrid
需要 PDF / Word / Excel / OCR先由 Document starter 抽取文本,再进入 Knowledge 检索
需要后台查看知识源、文档、切片和索引状态使用 Core Knowledge Admin contract
需要后台轻量问一问使用 Core Knowledge POST /api/v1/admin/knowledge/ask
需要运维侧快速判断索引规模Knowledge.summary(source) 返回文档数、切片数、token 预算和向量配置状态
需要对外开放给第三方不在第一阶段范围

Knowledge starter 只读取现有知识并生成可检索上下文,生成 AI 回答。Core Knowledge Admin 可以在后台组合 AI Model 生成回答,但模型能力是可选增强;Admin 问一问默认不生成,且 chat.policy.generation-enabled=false 时即使请求 generate=true 也会回退检索摘要。应用默认 AI Model Provider 是 simulated,不会访问真实模型服务;真实 Provider 需要显式开启生成策略和 Provider 白名单。未配置可用模型、模型调用失败或流式链路不可用时,接口应回退到检索摘要和引用。默认 embedding 是本地 hashing 实现,不需要密钥。

快速开始

yaml
spring:
  open:
    knowledge:
      enabled: true
java
List<KnowledgeSearchResult> results = Knowledge.search(
    KnowledgeSearchRequest.builder()
        .query("Web3 支付结算")
        .mode(KnowledgeConstants.MODE_HYBRID)
        .topK(5)
        .includeContent(true)
        .build()
);

默认只扫描项目 .knowledge/ 团队知识目录,开发文档 docs/、Agent 记忆 .ai/AGENTS.md 不进入默认知识库;确需内部 Agent 检索时应另建受控来源显式配置。

Core Knowledge Admin Contract

spring-open-core-knowledge 已接入 Knowledge starter,并在 spring.open.knowledge.enabled=true 时暴露后台管理接口:

方法路径说明
GET/api/v1/admin/knowledge/sources查询已配置知识来源
GET/api/v1/admin/knowledge/documents?source=project查询来源扫描到的文档
GET/api/v1/admin/knowledge/chunks?source=project查询来源切片
GET/api/v1/admin/knowledge/search?query=配置&mode=hybrid&topK=8搜索知识库
GET/api/v1/admin/knowledge/chat/config查询 Knowledge Chat 生成策略、模型可用性和护栏配置
POST/api/v1/admin/knowledge/agent-context查询后台身份可见的受控 Agent 上下文;不调用模型、不写会话
POST/api/v1/admin/knowledge/ask基于检索上下文问答;可选调用 AI Model 生成回答
POST/api/v1/admin/knowledge/ask/stream基于检索上下文流式问答;模型或流式链路不可用时返回降级事件
POST/api/v1/knowledge/me/agent-context查询当前用户可见的受控 Agent 上下文;服务端覆盖用户身份
POST/api/v1/knowledge/me/ask当前登录用户知识问答;用户端入口使用当前身份并可保存会话
POST/api/v1/knowledge/me/ask/stream当前登录用户知识流式问答;流式不可用时前端回退普通问答
POST/api/v1/admin/knowledge/refresh刷新指定来源内存索引;未传 source 时使用默认来源,传 all=true 时刷新全部启用来源
POST/api/v1/admin/knowledge/sources/url/preflight预检受控文档站 URL 来源配置;只校验根 URL 和抓取边界,不保存配置、不刷新索引

后台页面位于 views/admin/src/views/knowledge/index.vue,读接口需要 knowledge:view,刷新索引、URL 来源预检和反馈类接口需要 knowledge:update。页面已提供来源、文档、切片、搜索结果、Knowledge Chat 配置状态和“问一问”入口;来源页签展示来源类型、标题、说明、启用状态、搜索 / 刷新能力、根路径和扫描范围,停用来源会禁用搜索和刷新动作。只有生成策略允许且开启“生成回答 + 流式”时才会调用 SSE 流式接口并增量渲染,支持取消当前流式请求,流式请求不可用时自动切换普通 /ask 完整回答。问答默认不保存会话历史;请求显式传 recordConversation=true 时,会在 Conversation 底座中记录用户问题和助手回答,Conversation 不可用或记录失败时只返回 warning,不影响 Knowledge 回答。

普通用户入口使用 /api/v1/knowledge/me/**,只要求当前用户已登录,不要求配置项权限。Controller 会覆盖请求中的 userId 为当前登录用户,防止前端伪造身份;App / PC 默认传 recordConversation=true、稳定 conversationKey 和一次性 clientMessageId,用于把知识问答沉淀到 Conversation 会话历史。Admin /api/v1/admin/knowledge/ask 仍保留后台运维语义,只在请求未带 userId 时填充当前后台用户,便于管理员排查知识库和模型策略。

PC 端知识助手默认使用 business.public 来源。该来源由 Core Knowledge 聚合公开业务 contributor,不直接依赖业务模块实现,当前包含 mall.public-products(已发布商品)、cms.published-content(已发布 CMS 内容)、blog.published-articles(已发布文章)和 forum.public-topics(可见社区主题)。PC 页面同时提供来源筛选,可单独查询商品、CMS、文章、社区或团队知识;业务内容刷新仍按各自真实 source 或 business.public 聚合 source 进入 KnowledgeIndexer。

/agent-context 是给 Agent、插件或业务编排层使用的受控上下文接口。它复用 /ask 的请求体,但服务端会强制 generate=falsereturnContext=true,只返回当前身份可见的 contextscitations,不调用模型、不写 Conversation、不记录 Knowledge Chat 审计。Admin 入口按 knowledge:view 权限和后台身份过滤,用户入口按当前登录用户过滤;请求体里的 userId / tenantId / adminAccess 不会绕过服务端可见性判定。

刷新是 source 级通用入口,适用于文件系统、业务贡献方、受控文档站等所有已配置来源。未传 source 时只刷新 default-source,不代表刷新全部来源;需要批量重建时必须显式传 all=true,服务端只遍历已启用且可刷新的来源,并返回聚合统计和每个来源的子结果,避免误触停用来源。业务来源还支持事件触发刷新:CMS / Blog / Forum / Mall 在公共内容创建、更新、发布状态变化或删除后发布 Runtime 中立事件,Core Knowledge 在事务提交后按来源编码调用 KnowledgeIndexer.refresh(source)。业务模块不直接调用 Knowledge indexer,Knowledge 也不依赖业务模块实现。

type=url / web-docs 来源在通用刷新基础上额外支持 HTTP 增量能力:加载器会复用上一轮文档的 ETag / Last-Modified 发起条件请求,远端返回 304 时复用缓存正文并标记 refreshStatus=unchanged;远端返回新内容时根据 contentHash 标记 createdupdated;远端短时不可用、非 2xx 或页面超过大小限制时,如果本地已有缓存,会继续返回旧文档并标记 refreshStatus=stale,避免一次网络波动清空知识库。

刷新结果 KnowledgeRefreshResultVO 会返回 sourcesourceCountsourcesdocumentCountchunkCountcreatedDocumentCountupdatedDocumentCountunchangedDocumentCountstaleDocumentCountstartedAtfinishedAtdurationMillis;单来源刷新时 sourceCount=1sources 为空,all=true 批量刷新时 source=allsources 包含每个来源的子结果。Admin 页面会在刷新后展示新增、更新、未变化、旧缓存、来源数量和耗时统计。文档列表 KnowledgeDocumentVO 会带出 refreshStatus 和原始 metadata,Admin 文档页签展示刷新状态和关键 metadata;URL 来源 metadata 包含 canonicalUrlrootUrlhttpStatuscontentTypeetaglastModifiedcontentHashfetchedAt 等字段,方便后台和运维侧判断知识是否新增、未变化、已更新或正在使用旧缓存兜底。

Admin 页面提供“URL 预检”抽屉,可从当前 url / web-docs 来源带入已有 root 和路径范围,也可以手动录入一个新文档站。预检接口只对 root URL 发起一次 HTTP GET,并按同源、允许路径、重定向、HTTP 2xx、content-type、页面大小和 sitemap 同源规则返回校验结果;它不会保存配置,也不会触发抓取或刷新。预检通过后,抽屉会生成一段可复制到配置文件的 spring.open.knowledge.sources.<name>.url.* YAML 片段。

POST /api/v1/admin/knowledge/sources/url/preflight 请求体:

json
{
  "source": "docs-site",
  "rootUrl": "https://example.com/docs",
  "sitemapUrl": "https://example.com/docs/sitemap.xml",
  "allowedPathPrefixes": ["/docs"],
  "maxDepth": 1,
  "maxPages": 30,
  "maxBytesPerPage": 1048576,
  "maxRedirects": 3,
  "connectTimeoutMillis": 5000,
  "requestTimeoutMillis": 10000,
  "allowedContentTypes": [
    "text/html",
    "application/xhtml+xml",
    "text/markdown",
    "text/plain"
  ],
  "userAgent": "KnowledgeBot"
}

响应中的 valid 表示该配置是否可作为受控文档站来源使用;reachablecontentTypeAllowedsizeAllowed 用于拆分原因;errorswarnings 返回稳定短码,前端会转换为中文提示。常见短码包括 root_url_requiredscheme_not_supportedredirect_origin_not_allowedredirect_path_not_allowedhttp_status_not_successcontent_type_not_allowedcontent_too_large

三端可嵌入组件:

组件 / API传输策略
Adminviews/admin/src/views/knowledge/components/KnowledgeChatPanel.vue / views/admin/src/api/knowledge.ts浏览器端优先 /ask/stream,失败自动回 /ask
Appviews/app/src/pages/knowledge/index.vue + views/app/src/components/KnowledgeChatPanel.vue / views/app/src/api/knowledge.js默认普通 /me/ask,适配非 SSE 客户端环境
PCviews/pc/app/pages/knowledge.vue + views/pc/app/components/KnowledgeChatPanel.vue / views/pc/app/features/shared/useKnowledgeChatApi.ts浏览器端优先 /me/ask/stream,失败自动回 /me/ask

三端组件会把服务端 warnings 短码转换成普通用户能理解的提示,不直接向用户展示 ai_model_failed 这类内部短码。PC 端只有用户开启“实时显示回答”时才尝试流式请求;客户端不支持流式响应或流式请求失败时,会提示已切换普通回答并继续展示 /ask 完整结果。

POST /api/v1/admin/knowledge/askPOST /api/v1/knowledge/me/ask、以及对应 /ask/stream 请求体:

json
{
  "source": "project",
  "question": "Knowledge 如何接入 AI Model?",
  "topK": 6,
  "returnContext": true,
  "generate": true,
  "provider": "simulated",
  "model": "simulated-default",
  "temperature": 0.2,
  "maxTokens": 512,
  "recordConversation": true,
  "conversationKey": "admin-knowledge",
  "clientMessageId": "ask-20260607-0001"
}

字段说明:

字段说明
source知识来源编码,未传时使用 spring.open.knowledge.default-source
question用户问题,必填
topK检索上下文数量,范围 1..20
returnContext是否在响应中返回上下文列表;生成 prompt 内部仍会使用上下文
generate是否调用 AI Model 生成回答,默认 false
provider / model可选模型路由覆盖;不传时由 AI Model starter 默认路由决定
temperature / maxTokens可选模型参数
recordConversation是否把本次问答写入 Conversation,Admin 默认 false,App / PC 用户入口默认 true
conversationId可选已有会话 ID;未传时可通过 conversationKey 复用或创建 Knowledge 会话
conversationKey可选会话键,服务端会按 knowledge:{userId}:{conversationKey} 归一成 Conversation key
clientMessageId可选幂等消息 ID;助手回答会派生 {clientMessageId}:assistant

recordConversation=true 时,/me/** Controller 始终使用当前登录用户作为 userId;Admin /api/v1/admin/knowledge/ask 在请求未带 userId 时填充当前后台用户;Service 也保留 userId 字段,便于开放 API 或应用装配层在受控上下文中显式传入。会话消息使用 contentType=text,并在 attributes 中写入 source=knowledgerole=user|assistantknowledgeSourceanswerModegenerated、Provider / model 等轻量元数据。Knowledge 不复制 Conversation 私有状态,也不引入独立消息表。

响应中的 answerMode 用于前端和审计区分回答来源:

answerMode说明
generated已调用 AI Model 并返回生成式回答
extractive未调用模型,或模型不可用 / 失败后回退到检索摘要
no-context没有检索到可用于回答的上下文

响应还会在记录成功时返回 conversationRecorded=trueconversationIduserMessageIdassistantMessageId,前端可据此跳转或继续追加上下文。

warnings 当前可能包含 no_contextai_generation_disabledai_source_not_allowedai_provider_not_allowedai_model_not_allowedai_no_context_generation_disabledai_model_unavailableai_model_failedconversation_user_requiredconversation_unavailableconversation_failedai_guard_request_limitedai_guard_token_budget_exceededai_guard_concurrency_limitedai_guard_prompt_too_largeai_guard_max_tokens_clampedai_guard_duplicate_merged。这些 warning 不表示接口失败,只表示回答、模型调用或会话记录已降级;前端应继续展示检索摘要、引用和可用回答。

POST /api/v1/admin/knowledge/ask/stream 使用 text/event-stream,请求体与 /ask 一致。事件结构:

事件说明
meta首个事件,携带问题、来源、contexts、citations、maxScore 等元数据
delta模型增量文本,前端按顺序拼接到回答区
done生成完成,携带最终 answer、Provider / model、finishReason、usage
result非流式完整结果,常用于未启用生成、无模型、模型 stream 失败或服务端降级

流式模型不可用、连接失败、客户端不支持 SSE 或中途断开时,前端必须保留普通 /ask 完整回答或任务状态查询作为兜底,不能把 SSE 作为唯一可用入口。当前 Admin / PC 页面已经实现流式失败后自动回退 /ask,App 端默认使用普通 /me/ask

Facade API

java
// 关键词 / 向量 / hybrid 搜索
List<KnowledgeSearchResult> results = Knowledge.search(
    KnowledgeSearchRequest.builder()
        .query("...")
        .mode("hybrid")                   // keyword / vector / hybrid
        .topK(8)
        .includeContent(false)            // 默认只返回 snippet
        .source("project")                // 限定知识源
        .build()
);

// 问答上下文(返回 snippet + citations,不生成回答)
KnowledgeAskResult result = Knowledge.ask(
    KnowledgeAskRequest.builder()
        .question("为什么配置前缀使用 spring.open.*?")
        .topK(6)
        .returnContext(true)
        .build()
);

// 来源索引摘要(不触发 AI 回答或外部模型调用)
KnowledgeIndexSummary summary = Knowledge.summary("project");

返回字段

字段说明
documentKey文档 key
chunkIndex切片序号
title标题
path文件路径
headingPath标题路径,例 Web3 > 支付结算 > 风险审计
score相关性分数
snippet摘要片段
content完整内容(仅 includeContent=true

源码机制骨架

类型机制职责
Knowledge静态 Facade,提供业务侧短名入口
KnowledgeManagerProvider将 Facade 绑定到 Spring 容器内的 KnowledgeManager
KnowledgeManager管理文档加载、切片、关键词检索和 Ask 上下文组装
DefaultKnowledgeManager默认实现,每次按需加载来源、切片并执行轻量关键词检索
KnowledgeIndexSummary来源级索引摘要,包含文档数、切片数、token 总量、平均切片 token、索引开关和默认向量存储
KnowledgeDocumentLoader文档加载 SPI,当前默认实现读取本地文件系统知识源
CompositeKnowledgeDocumentLoader聚合多个加载器,按来源编码分派到文件系统来源或业务来源
FilesystemKnowledgeDocumentLoader按配置 paths / excludes / extensions 读取本地文件源文档;metadata 固定包含 sourcesizelastModifiedAt,容器内存在 DocumentManager 时优先消费 Document starter 的抽取结果
UrlKnowledgeDocumentLoader读取 type=url / web-docs 受控文档站来源;限制同源、允许路径、深度、页数、字节数、content-type 和重定向,并用 ETag / Last-Modified / contentHash 维护刷新状态
KnowledgeSourceContributor业务模块知识来源贡献 SPI,由 Blog / CMS / Forum / Mall 等业务模块注册 Bean 输出中性文档快照
KnowledgeSourceDocument业务知识文档快照,包含来源、业务类型 / ID、标题、摘要、正文、URL、可见性、租户 / 用户、更新时间、内容 hash 和轻量 metadata
KnowledgeSourceDocumentLoader将启用的业务贡献方快照转换为 KnowledgeDocument,供统一切片、索引和检索
KnowledgeSourceChangedEventKnowledge starter 中立事件,业务公共内容变更后发布,Core Knowledge listener 在事务提交后按 source 刷新索引
KnowledgeChunker文档切片 SPI
MarkdownHeadingKnowledgeChunker按 Markdown 标题优先切片,尽量保留标题路径和代码块
KnowledgeEmbeddingProvider文本向量化 SPI,默认本地 hashing embedding
KnowledgeVectorStore向量存储和相似度检索 SPI,默认内存实现
KnowledgeIndexer文档扫描、切片和向量索引的内部编排点
KnowledgeSearchRequest / KnowledgeSearchResult搜索请求和结果 contract
KnowledgeAskRequest / KnowledgeAskResultAsk 上下文请求和结果 contract

扩展边界

Knowledge starter 默认提供本地 hashing embedding 和内存向量库;生产级 RAG 扩展点仍保持在 Knowledge 边界内:

  • 业务模块接入公共知识来源时实现 KnowledgeSourceContributor,输出 KnowledgeSourceDocument 快照;Knowledge 不直接依赖 Blog / CMS / Forum / Mall 等业务模块。
  • 自定义非业务知识来源时实现 KnowledgeDocumentLoader,例如数据库、远程 API 或其他文件系统。
  • 自定义切片规则时实现 KnowledgeChunker,例如按段落、固定窗口或业务字段切片。
  • 配置 embedding.provider=ai-model 复用 AI Model starter 的 embeddings;需要更特殊协议时实现 KnowledgeEmbeddingProvider
  • 自定义向量存储时实现 KnowledgeVectorStore,例如 pgvector、Qdrant 或 OpenSearch。
  • DefaultKnowledgeManager 支持 keyword / vector / hybrid 三种检索模式;默认不触发外部模型或外部向量库。
  • Knowledge.ask(...) 只返回 contexts 和 citations,answer 第一阶段保持空字符串;Core Knowledge Admin 的 /ask 组合接口可按请求调用 AI Model,失败时回退到检索摘要。
  • Core Knowledge Admin 的 /ask/ask/stream 可选写入 Conversation 会话历史;该能力只通过 KnowledgeConversationRecorder 桥接 Conversation Service,不改变 Knowledge starter 的纯检索边界。
  • Core Knowledge Admin contract 只面向后台运维,不承担第三方开放接口职责。
  • PDF、Office、OCR 等文档解析先通过 Document starter 抽取文本,再交给 Knowledge;Knowledge 文件系统加载器只消费 DocumentExtractResult,不直接依赖 Tika / PDFBox / POI。

业务模块知识来源

公共、已发布、适合问答的业务内容通过 KnowledgeSourceContributor 接入。业务模块只注册自己的 contributor Bean,Knowledge starter 通过 ObjectProvider<KnowledgeSourceContributor> 聚合启用来源,并把快照转为统一 KnowledgeDocument 后进入切片和索引链路。

当前已内置的业务贡献方:

来源编码模块内容边界备注
cms.published-contentCMS已发布公共 CMS 内容输出页面、公告、专题、内容块、导航等可公开展示内容
blog.published-articlesBlog已发布文章免费文章输出正文;付费 / VIP 文章只输出公开预览或摘要,不索引锁定正文
forum.public-topicsForum公开可见主题输出公开板块下可见主题的标题、摘要、首帖正文、作者和互动热度
mall.public-productsMall已上架公开商品输出商品名称、摘要、详情、分类、价格和公开图片,不索引订单 / 购物车 / 支付 / 售后 / 结算数据
form.public-templatesForm公开模板输出 active official 模板的说明、字段 JSON 和设置 JSON,不索引用户提交数据或协作权限
meeting.help-docsMeeting会议帮助说明输出会议能力、入会、主持人控制、资料 / 聊天 / 提醒、录制 / 转写 / 纪要和开放 API 的公开帮助快照,不索引会议实例、成员、录制文件、转写或纪要正文
java
@Component
class BlogPublishedArticleKnowledgeSourceContributor implements KnowledgeSourceContributor {

    @Override
    public String sourceCode() {
        return "blog.published-articles";
    }

    @Override
    public String title() {
        return "Blog published articles";
    }

    @Override
    public List<KnowledgeSourceDocument> documents() {
        return publishedArticles().stream()
            .map(article -> KnowledgeSourceDocument.builder()
                .businessType("article")
                .businessId(String.valueOf(article.id()))
                .title(article.title())
                .summary(article.summary())
                .content(article.publicPreviewContent())
                .url("/blog/articles/" + article.slug())
                .visibility(KnowledgeConstants.VISIBILITY_PUBLIC)
                .updatedAt(article.updatedAt())
                .build())
            .toList();
    }
}

业务来源快照只表达可索引文本和轻量引用信息,不暴露模块表结构、状态机或权限细节。私有资料、交易数据、会议纪要、用户提交数据和权限知识库需要先完成权限过滤后再接入。

配置项

yaml
spring:
  open:
    knowledge:
      enabled: true
      default-knowledge-base: project
      default-source: project
      default-top-k: 8
      default-vector-store: memory
      sources:
        project:
          enabled: true
          root: .
          paths:
            - .knowledge
          excludes:
            - target/**
            - public/**
            - storage/**
            - views/**/node_modules/**
            - .ai/memory/**
            - .ai/tasks/branch-plans/**
          extensions:
            - .md
            - .markdown
            - .txt
      chunking:
        max-tokens: 800
        overlap-tokens: 100
        respect-markdown-heading: true
        preserve-code-block: true
      index:
        enabled: true
        persistent-enabled: false
        persistent-provider: pgvector
        incremental-scan-enabled: true
        keyword-weight: 1.0
        vector-weight: 4.0
        min-vector-score: 0.05
      vector-stores:
        memory:
          enabled: true
          provider: memory
        pgvector:
          enabled: false
          provider: pgvector
          options:
            table: knowledge_embedding
            vector-column: embedding_vector
            metadata-column: metadata_json
      embedding:
        provider: hashing
        external-enabled: false
        fallback-to-hashing: true
        external-provider:
        external-model:
        dimensions: 256
        min-token-length: 1
      chat:
        policy:
          generation-enabled: false
          default-generate: false
          default-provider: simulated
          default-model:
          default-temperature: 0.2
          allowed-sources: []
          allowed-providers:
            - simulated
          allowed-models: []
          generate-without-context: false
          no-context-answer: 未检索到可用于回答的知识上下文。
        guard:
          enabled: true
          default-max-tokens: 512
          max-tokens-per-request: 1024
          max-prompt-tokens: 4096
          requests-per-minute: 30
          tokens-per-day: 100000
          concurrent-requests: 4
          rate-limit-store:
配置默认值说明
enabledtrue启用开关
default-knowledge-baseproject默认知识库(写入 / 检索归属)
default-sourceproject默认知识来源
default-top-k8默认返回结果数
default-vector-storememory默认向量存储配置名;内置 provider 包含 memory 和默认关闭的 pgvector
sources.<name>.extensions.md / .markdown / .txt扫描的文件扩展名;接入 Document starter provider 后可显式加入 .pdf / .docx 等富文档扩展名
sources.<name>.languagezh-CN来源默认语言
sources.<name>.typefilesystem来源类型;本地文件使用 filesystem,受控文档站使用 url / web-docs
sources.<name>.root.来源根目录
sources.<name>.paths项目知识路径要扫描的文件或目录
sources.<name>.excludes内置排除规则要排除的 glob
sources.<name>.url.root-url文档站根 URL;仅 type=url / web-docs 生效
sources.<name>.url.sitemap-url可选 sitemap URL;只接受同源 sitemap,页面仍按 allowed path 过滤
sources.<name>.url.allowed-path-prefixesroot URL 路径允许抓取的路径前缀,默认使用 root URL 的 path
sources.<name>.url.max-depth1最大递归深度;不执行 JS,不抓登录态页面
sources.<name>.url.max-pages30单次最多抓取页数
sources.<name>.url.max-bytes-per-page1048576单页最大字节数,超过后跳过
sources.<name>.url.allowed-content-typesHTML / Markdown / text允许处理的 content-type 前缀
sources.<name>.url.connect-timeout5sHTTP 连接超时
sources.<name>.url.request-timeout10s单次请求超时
sources.<name>.url.max-redirects3最多跟随重定向次数;目标仍必须同源且命中允许路径
sources.<name>.url.user-agentKnowledgeBot抓取文档站时使用的 User-Agent
chunking.max-tokens800单切片最大近似 token
chunking.overlap-tokens100切片重叠近似 token
chunking.respect-markdown-headingtrue是否按 Markdown 标题分块
chunking.preserve-code-blocktrue是否尽量不拆代码块
index.enabledtrue是否启用内存向量索引;关闭后 vector / hybrid 回退为关键词检索
index.persistent-enabledfalse是否启用生产持久索引;默认关闭,避免本地刷新意外依赖外部向量库
index.persistent-providerpgvector生产持久索引 provider 标识;当前内置 pgvector provider 仍需显式启用
index.incremental-scan-enabledtrue是否暴露增量扫描状态;当前 URL / web-docs 来源通过 ETag / Last-Modified / contentHash 返回 created / updated / unchanged / stale
index.keyword-weight1.0hybrid 模式关键词分数权重
index.vector-weight4.0hybrid 模式向量相似度权重
index.min-vector-score0.05向量结果最小相似度
vector-stores.<name>.enabledtrue / false是否启用该向量存储配置
vector-stores.<name>.providermemory向量存储 provider;内置 memory / pgvector,其他向量库通过自定义 KnowledgeVectorStore bean 接入
vector-stores.<name>.options{}provider 专属扩展配置,例如 pgvector 表名、向量列名和 metadata 列名
embedding.providerhashingembedding provider;hashing 为本地默认,ai-model 通过 AI Model starter 调用 embeddings
embedding.external-enabledfalse是否启用外部 embedding;默认关闭,避免索引刷新触发外部模型成本
embedding.fallback-to-hashingtrue外部 embedding 失败或 AI Model 不可用时是否回退到本地 hashing
embedding.external-provider使用 ai-model provider 时的 AI Model Provider 覆盖
embedding.external-model使用 ai-model provider 时的 embedding 模型覆盖
embedding.dimensions256默认 hashing embedding 维度
embedding.min-token-length1默认索引 token 最小长度
chat.policy.generation-enabledfalse是否允许 Knowledge Chat 调用模型生成;默认关闭,保证检索摘要和引用始终可用
chat.policy.default-generatefalse请求未传 generate 时的默认值
chat.policy.default-providersimulated请求未传 Provider 时使用的默认 Provider;真实 Provider 需显式配置
chat.policy.default-model请求未传模型时使用的默认模型
chat.policy.default-temperature0.2请求未传 temperature 时使用的默认温度
chat.policy.allowed-sources允许生成的来源白名单;为空表示不限制来源
chat.policy.allowed-providerssimulated允许生成的 Provider 白名单;默认只允许模拟 Provider
chat.policy.allowed-models允许生成的模型白名单;为空表示不限制模型
chat.policy.generate-without-contextfalse无检索上下文时是否仍允许调用模型;默认直接返回 no-context
chat.policy.no-context-answer固定中文提示无检索上下文时返回的回答
chat.guard.enabledtrue是否启用 Knowledge Chat 模型调用护栏;只影响 generate=true 的模型生成,不影响检索摘要
chat.guard.default-max-tokens512未传 maxTokens 时的默认生成 token 上限
chat.guard.max-tokens-per-request1024单次生成 token 上限,超过时裁剪并返回 ai_guard_max_tokens_clamped
chat.guard.max-prompt-tokens4096单次 prompt 近似 token 上限,超过时不调用模型并回退检索摘要
chat.guard.requests-per-minute30单个主体每分钟最多生成请求次数;非正数表示不限制
chat.guard.tokens-per-day100000单个主体每天最多消耗近似 token;非正数表示不限制
chat.guard.concurrent-requests4本实例同时进行的生成调用上限;非正数表示不限制
chat.guard.rate-limit-store可选 Rate Limit store 名称;为空时使用 Rate Limit starter 默认 store

Knowledge Chat 先经过 chat.policy,再经过 chat.guard。策略层负责是否允许生成、来源白名单、Provider / model 白名单和无上下文策略;护栏层复用 Rate Limit starter 控制成本和并发。单机或本地学习默认使用 memory store;多实例生产环境建议把 Rate Limit 默认 store 切到 Redis / Redisson,才能让每分钟次数和每日近似 token 预算跨实例生效。策略拒绝、超出预算、并发满、prompt 过大或短时重复请求时,接口会回退到 extractive / no-context,保留 citations,不让模型不可用或 token 成本影响 Knowledge 基础检索能力。

生产 RAG 的默认姿态是“显式开启”:默认 memory 向量库和 hashing embedding 不访问外部服务;需要 PostgreSQL 持久向量索引时启用 pgvector store,并将 default-vector-store 指向 pgvector;需要真实 embedding 时设置 embedding.provider=ai-modelembedding.external-enabled=true,并通过 external-provider / external-model 指向已授权的 AI Model Provider。fallback-to-hashing=true 时外部模型短时失败会继续以本地 hashing 完成索引和检索;生产环境若希望配置错误直接暴露,可关闭 fallback。

扩展 SPI

不提供 Provider 切换。扩展能力通过 SPI:

  • 实现 KnowledgeSourceContributor 注册业务模块公共知识来源(Blog / CMS / Forum / Mall 等)
  • 配置 sources.<name>.type=web-docs 接入受控文档站 URL 来源;内置 loader 只抓同源、允许路径前缀、限定页数 / 深度 / 字节数 / content-type 的公共文档,不执行页面脚本,并通过 ETag / Last-Modified / contentHash 支持增量刷新和 stale 缓存兜底
  • 实现 KnowledgeDocumentLoader 注册其他非业务自定义知识来源(数据库 / 远程 API / 其他文件系统)
  • 实现 KnowledgeChunker 自定义切片器
  • 实现 KnowledgeEmbeddingProvider 接入外部 embedding 模型
  • 使用内置 pgvector store,或实现 KnowledgeVectorStore 接入 Qdrant / OpenSearch / 专用向量库

向量检索演进

当前版本已提供本地 hashing embedding + 内置 memory 向量库,不需要外部模型、向量数据库或密钥,适合作为框架默认轻量能力;同时内置默认关闭的 PostgreSQL pgvector store,用于生产持久索引。进入生产级 RAG 阶段时建议保持三层边界:

作用建议
KnowledgeEmbeddingProvider把文本切片转成向量默认本地 hashing;通过可选 provider 接入 OpenAI-compatible、本地模型或自建服务
KnowledgeVectorStore保存向量并做相似度检索内置 memory / pgvector;独立部署向量服务时优先 Qdrant
KnowledgeManager对外提供 search / ask保持 facade 不变,内部组合关键词、向量和引用结果

Embedding Provider

Provider 面向「模型服务能力」,不是面向某个业务模块:

Provider适用场景默认依赖
disabled默认禁用向量生成,适合未配置模型服务或隔离诊断
openai-compatibleOpenAI / Azure OpenAI / 兼容 OpenAI 协议的模型网关后续可选依赖
localOllama、自建模型服务或内网模型网关后续可选依赖

建议配置形态:

yaml
spring:
  open:
    knowledge:
      default-embedding-provider: disabled
      embedding-providers:
        openai-compatible:
          provider: openai-compatible
          enabled: false
          base-url: ${SPRING_OPEN_KNOWLEDGE_EMBEDDING_BASE_URL:}
          api-key: ${SPRING_OPEN_KNOWLEDGE_EMBEDDING_API_KEY:}
          model: text-embedding-3-small

Vector Store

向量存储只放在 Knowledge 边界内,不让业务模块直接依赖 pgvector / Qdrant / Milvus SDK:

Store推荐级别说明
pgvector第一优先适合 PostgreSQL 项目,运维成本低,和文档元数据事务边界更容易收口
qdrant第二优先独立向量服务,部署轻,适合中等规模语义检索
elasticsearch / opensearch按需已有搜索集群时适合做关键词 + 向量混合检索
milvus后续大规模向量检索再引入,第一阶段不建议默认依赖
memory内置默认用于单测、预览或本地轻量验证,不作为生产级持久化方案

当前可绑定配置形态:

yaml
spring:
  open:
    knowledge:
      default-vector-store: memory
      vector-stores:
        memory:
          enabled: true
          provider: memory
        pgvector:
          enabled: false
          provider: pgvector
          options:
            table: knowledge_embedding
            vector-column: embedding_vector
            metadata-column: metadata_json
        qdrant:
          enabled: false
          provider: qdrant
          options:
            url: ${SPRING_OPEN_KNOWLEDGE_QDRANT_URL:}
            api-key: ${SPRING_OPEN_KNOWLEDGE_QDRANT_API_KEY:}

pgvector store 只有在 default-vector-store 指向 provider 为 pgvector 的配置、classpath 含 spring-jdbc 且存在 DataSource 时启用;否则默认仍是内存向量库。项目提供可选 Liquibase 片段 classpath:/db/changelog/optional/knowledge-pgvector.xml,仅负责结构化创建 knowledge_embedding 表;生产启用前需要在 PostgreSQL 预先安装 pgvector 扩展,HNSW 等向量索引按部署规模由 DBA 或运维脚本单独添加。默认 master changelog 不自动 include 它,避免普通 MySQL / H2 / 未安装 pgvector 的 PostgreSQL 启动失败。

最小启用示例:

yaml
spring:
  open:
    knowledge:
      default-vector-store: pgvector
      vector-stores:
        pgvector:
          enabled: true
          provider: pgvector
          options:
            table: knowledge_embedding
            vector-column: embedding_vector
            metadata-column: metadata_json

混合检索

RAG 不建议只依赖向量相似度。更稳的顺序:

  1. 关键词检索负责精确命中配置 key、类名、路径、错误码。
  2. 向量检索负责语义相似问题。
  3. KnowledgeManager 合并结果、去重、按 score / 来源 / 标题层级排序。
  4. Ask 仍只返回上下文和 citations,真正生成回答交给 AI Task / AI Model Provider。

切片规则

默认切片器是 Markdown heading-aware:

  • 优先按 # / ## / ### 等标题分块
  • 保留 headingPath(例 Web3 > 支付结算 > 风险审计
  • 尽量不拆断代码块
  • 单块默认约 800 tokens
  • 搜索默认只返回 snippet,减少上下文消耗

知识源约定

来源作用
.knowledge/默认采集团队知识、FAQ、运营经验和产品知识
业务来源 contributor默认用于用户侧公开业务内容,例如商品、CMS、文章、社区
docs/正式开发者文档,默认不采集;仅内部 Agent 场景显式配置
.ai/AI Agent 长期上下文、计划和决策,默认不采集
AGENTS.mdAI Agent 项目入口规则,默认不采集

默认不采集docs/.ai/**AGENTS.mdtarget/storage/public/node_modules/。避免把开发文档、Agent 记忆、执行日志、构建产物和运行文件塞进用户知识检索结果。

与 AI Task 协作

Knowledge 负责「找资料」,AI Task 负责「组织任务」。两者不硬依赖,按场景组合:

text
AI Task Handler
    → Knowledge.search / Knowledge.ask
    → Pipeline 组装 prompt 或上下文
    → 模型 Provider(后续接入 spring-open-starter-ai-model)
    → 返回结果 / 发送通知 / 写入业务记录

使用建议

  • topK 保持克制,默认不把大量文档塞进上下文
  • 普通搜索优先返回 snippet,需要生成回答时再打开 content
  • citations 应随回答一起保留,方便后台审查和用户追溯来源
  • docs/.ai/**AGENTS.md、构建产物、运行目录不要进入默认知识源

当前边界

已具备暂不包含
Knowledge facade + KnowledgeManager数据库持久化索引
文件系统来源扫描生产级向量库持久化
Document starter 抽取结果接入-
Markdown 标题切片外部 embedding 模型默认依赖
本地 hashing 向量 / hybrid 检索-
关键词搜索Open Platform 对外开放 API
Ask 上下文返回计费 / 配额
-Knowledge 内置 PDF / Word / Excel / OCR 解析器

后续阶段按「Embedding Provider 抽象 → Vector Store 抽象 → pgvector 生产 store → Qdrant 可选 store → AI Task / AI Model 组合」推进。

验证命令

bash
./mvnw -pl spring-open-starters/spring-open-starter-knowledge -am test -DskipITs

相关

Released under the Apache License 2.0.