文章摘要
本文以 NextKB 为例,完整拆解企业级知识库 Agent 的控制面与推理面解耦架构、Google ADK Agent 定义、Vertex AI Search RAG 与 Grounding 溯源、会话持久化、混合检索、多租户治理以及 Cloud Run 双流水线部署,适合要在 GCP 上落地工业级 RAG Agent 的工程师与架构师。|
此内容根据文章生成,并经过人工审核,仅用于文章内容的解释与总结

从 0 到 1 构建企业级智能知识库 Agent:NextKB 架构设计与落地实战

技术栈:Google ADK · Vertex AI Reasoning Engine · Gemini · Vertex AI Search · FastAPI · Cloud Run · GCS · Document AI

企业内部文档通常并不缺,缺的是能理解工程意图、能给出可执行步骤、还能把每一句结论指回权威文档的问答系统。关键词搜索解决不了多轮上下文;通用大模型又容易幻觉。NextKB 的目标就是把这两件事一起做掉:用企业私有知识库做 RAG,用 Agent Runtime 做工具编排,用独立控制面做治理。

本文按真实落地顺序写:业务目标 → 分层架构 → Agent 与 Prompt → RAG / 混合检索 → 控制面产品化 → 部署与权限 → 经验与演进。文中的项目 ID、桶名、Data Store 路径一律用占位符,不涉及真实账号与内部资源。


1. 业务背景与设计目标

企业里真正有价值的知识,往往散落在架构方案、SOP、Runbook、API 对接文档和工单复盘里。传统知识库有两个硬伤:

  1. 检索语义弱:无法理解「GKE 蓝绿升级失败后如何回滚」这类带上下文的工程问题,返回的是文件名而不是可执行步骤。
  2. 无法溯源:通用 LLM 会编造命令、参数和权限配置;出了事故无法证明「这句话来自哪份 Runbook」。

NextKB 因此被设计成 GCP 上的企业技术支持 Agent:员工既可以走独立 Web 门户,也可以在 Gemini Enterprise 里用 @NextKB 提问,两边打到同一套 Agent Runtime。

核心设计目标

  • 高召回、零编造:事实来源是 GCS 非结构化文档 + Vertex AI Search(Discovery Engine)。系统指令强制「检索优先、禁止臆造」。
  • 双通道接入:产品 SPA 走 FastAPI;Gemini Enterprise 直连 Reasoning Engine,不经过产品服务。
  • 控制面 / 推理面解耦:会话、租户、ACL、用量落在控制面数据库;推理、Function Calling、RAG 落在 ADK Runtime。
  • 企业级隔离tenant_id、文档 ACL、IAM 最小权限、防跨桶访问、审计日志。

一个容易被忽略但必须写进架构原则的点:控制面数据库不是知识库。SQLite / PostgreSQL 只存租户、连接器登记、会话审计、文档元数据与 chunk 自检索引。生产问答的事实层始终是 GCS + Vertex AI Search。


2. 总体系统架构

NextKB 当前仓库是 NextKB Core 的 Google Cloud Edition。Core 本身用 Provider Adapter 把 LLM、Embedding、Vector Store、Rerank、OCR、Storage、Agent Runtime、Connector 做成可替换合同,避免把产品焊死在一家云上。Google Cloud Edition 的默认绑定如下:

Provider 合同Google Cloud Edition 默认
LLMGemini on Vertex AI
EmbeddingVertex AI Embedding
Vector StoreVertex AI Vector Search
Sparse Search本地 BM25 基线
RerankVertex AI Ranking API
OCRDocument AI
StorageGCS
Agent RuntimeADK / Gemini Enterprise Agent

产品分层可以画成:

mermaid
flowchart TB
    subgraph ClientLayer["1. 接入层"]
        WebUI["企业 Web 门户\n静态 SPA"]
        AdminUI["治理控制台\n/admin"]
        GE["Gemini Enterprise\n@NextKB"]
    end

    subgraph ControlPlane["2. 控制面 Cloud Run / FastAPI"]
        Router["网关\n/api/chat /api/conversations"]
        AuthModule["鉴权与 RBAC\nAccess Code / IAP / OIDC / SAML"]
        AuditDB[("控制面 DB\nSQLite 或 Cloud SQL")]
        DocSync["连接器与知识同步"]
        Hybrid["Hybrid Retrieval\nBM25 + Vector + RRF"]
    end

    subgraph AgentRuntime["3. 推理面 Vertex AI Agent Runtime"]
        ADKRunner["Google ADK Runner"]
        SystemPrompt["结构化系统指令"]
        SearchTool["VertexAiSearchTool"]
    end

    subgraph DataLayer["4. 数据与检索层"]
        GCS["Cloud Storage 文档桶"]
        Datastore["Vertex AI Search Data Store"]
        VectorIdx["Vector Search Index"]
    end

    WebUI --> Router
    AdminUI --> Router
    GE --> ADKRunner
    Router --> AuthModule
    Router --> AuditDB
    Router --> DocSync
    Router -->|"AgentClient 流式代理"| ADKRunner
    DocSync --> GCS
    DocSync --> Datastore
    ADKRunner --> SystemPrompt
    ADKRunner --> SearchTool
    SearchTool --> Datastore
    Datastore --> GCS
    Hybrid --> VectorIdx
    Hybrid --> AuditDB

为什么这样拆

FastAPI 控制面只做它擅长的事:静态 UI、会话持久化、多租户、RBAC、连接器、审计与计量。
Reasoning Engine只做推理编排:选模型、调 VertexAiSearchTool、把 Grounding Metadata 吐回流式通道。

运行形态对照:

形态入口Agent 后端说明
本地开发127.0.0.1:8000 + /adminAGENT_BACKEND=adk同时起 adk web 与 uvicorn
Gemini Enterprise@NextKBReasoning EngineGE 直连 Runtime,不经过 FastAPI
Cloud Run 生产产品 URL + /admin推荐 reasoning_engine容器更轻,复用已部署 Agent

ADK 有一个硬约束:同一个 Agent 里 VertexAiSearchTool 不能和其他 tool 共存。MVP 因此保持单工具。以后要接工单系统、变更窗口查询等外部动作,正确做法是协调 Agent + sub-agent + AgentTool,而不是往 root_agent.tools 里硬塞第二个函数。


3. 基于 Google ADK 的 Agent 开发

3.1 智能体定义与模型选型

Agent 入口在 nextkb/agent.py。生产主模型走环境变量,并预留 fallback,避免单模型配额打满后整条问答链路宕掉。

python
# nextkb/agent.py(示意,已脱敏)
from google.adk.agents import Agent
from google.adk.tools.vertexai_search_tool import VertexAiSearchTool
import os

search_tool = VertexAiSearchTool(
    data_store_id=os.environ["VERTEXAI_DATASTORE_ID"],
)

SYSTEM_INSTRUCTION = """
你是 NextKB,企业技术支持与解决方案专家。
只基于检索到的企业知识库作答,不得臆造文档、命令或权限配置。

回答规范:
1. 结论先行:1-2 句给出可行性或核心结论。
2. 结构化步骤:用编号拆解操作。
3. 生产级示例:代码或 CLI 标明必要参数与鉴权方式。
4. 避坑:指出 IAM、配额、多租户隔离等高频陷阱。
5. 溯源:引用检索到的文档名称或 URI,禁止伪造来源。
"""

root_agent = Agent(
    name="nextkb_agent",
    model=os.environ.get("AGENT_MODEL_PRIMARY", "gemini-flash-latest"),
    description="NextKB 企业技术支持与知识问答智能体",
    instruction=SYSTEM_INSTRUCTION,
    tools=[search_tool],
)

VERTEXAI_DATASTORE_ID 必须在 import 阶段存在,否则 Agent 进程直接失败——这是有意为之:没有 Data Store 的 Agent 会上线成「会聊天的幻觉机」。

完整资源路径形态如下(把项目与 Data Store 名换成你自己的):

text
projects/${GCP_PROJECT_ID}/locations/global/collections/default_collection/dataStores/${DATASTORE_ID}

3.2 Prompt 与 Grounding

工业级 RAG 不是「把检索结果塞进 context 就结束」。NextKB 用两层约束:

  • 输出范式:结论 → 编号步骤 → 代码/命令 → 注意事项 → 引用。
  • Grounding 提取:从 Vertex AI Search 返回的 GroundingChunks / GroundingAttributions 解析文档名与 GCS URI,前端渲染成溯源徽章。

产品聊天默认仍走 Agent 原生检索NEXTKB_CHAT_CONTEXT_MODE=agent_native)。只有打开 hybrid_prepend 时,控制面才会把 Hybrid Retrieval 组装好的带编号上下文拼进请求。这避免了「控制面 RAG」和「工具 RAG」两套上下文互相打架。


4. 知识库流水线:从文档到可检索 chunk

4.1 事实层怎么建

Vertex AI Search Data Store 创建时必须 contentConfig: CONTENT_REQUIRED。数据源选 Cloud Storage、非结构化文档。推荐:

配置项建议
Locationglobal
ParserLayout Parser(表格/版式更稳)
Include ancestor headings开启
上传 MIME同步时统一 text/plain。Vertex AI Search 不吃 text/markdown

文档组织建议按领域分前缀,而不是把所有文件丢进桶根目录:

text
gs://your-knowledge-bucket/
  architecture/
  runbooks/
  sop/
  faq/
  onboarding/

POC 用 10–30 份高质量 Runbook / SOP 就够;零散笔记召回噪声极大。

4.2 控制面解析与同步

后台上传链路:

  1. 文本 / Markdown 本地 UTF-8 解析。
  2. PDF / 图片走 Document AI Processor(DOCUMENTAI_PROCESSOR_NAME)。
  3. 解析文本写入 document_chunks,供 ACL 自检与本地检索回归。
  4. 点击同步:以 text/plain 上传到 KNOWLEDGE_BUCKET,再触发 Discovery Engine documents:import

未配置 GCP 凭据时,后台必须返回明确原因,而不是让半条链路静默失败。Cloud Run 文件系统是临时盘,不要把生产知识正文只放在容器本地

4.3 Connector 与增量

连接器登记在 connectors / connector_runs / connector_states。敏感字段(token、password、key)展示时脱敏。

Worker行为要点
gcs按 bucket/prefix 拉取支持格式,用 source_uri 幂等 upsert
google_drive导出 Docs/Sheets/Slides,映射 user/group/domain ACL;use_change_tokens=true 时走 Changes API 增量并删除已移除文件
SharePoint / Confluence / Slack / GitHub / Jira基础 API 同步、分页、重试、inline documents

同步文档携带 source_connector_idsource_uricontent_hashsource_updated_at,避免反复同步复制出一堆重复文档。


5. 检索层:ACL、混合融合与 RAG 组装

企业 RAG 的真正难点不是 embedding 模型,而是 权限感知检索。NextKB 文档可见性为 tenant / restricted / public,细粒度名单在 document_acls

Vector Search datapoint 带 restricts,查询时按当前 principal 生成允许列表,示意:

text
tenant_id: ["default"]
acl: ["tenant:default", "group:platform", "user:user@example.com", "public"]

Hybrid Retrieval 流水线:

  1. Sparse:本地 BM25-like 检索,先做 ACL prefilter。
  2. Vector:Vertex AI Vector Search find_neighbors
  3. Fusion:Reciprocal Rank Fusion 合并同一 chunk 的多路得分。
  4. Rerank:Discovery Engine Ranking API default_ranking_config:rank
  5. Fallback:Vector 或 Ranking 不可用时退回 fused / local 结果。

rag_context 再按字符预算压缩候选,生成 [1][2] 引用编号,后台可用 /admin/api/enterprise/rag/preview 做无模型预览。检索质量用 golden set(retrieval_eval_cases / retrieval_eval_runs)闭环,而不是靠「感觉召回还行」。


6. 控制面与产品体验

6.1 零构建静态前端

产品 UI 与 /admin 都由同一个 FastAPI 进程托管,无 Node 打包。好处是 Cloud Run 镜像简单、发布路径短。聊天走 SSE:

  • 思考中 → 检测到 function_call 显示「正在检索知识库…」
  • 累积 content.parts[].text 做 Markdown 打字机
  • 结束时挂上 grounding 引用;失败则中文错误 + 落库

6.2 会话持久化

mermaid
sequenceDiagram
    participant User as 浏览器
    participant API as FastAPI
    participant RE as Agent Runtime
    participant DB as 控制面 DB

    User->>API: POST /api/session
    API->>RE: 创建 Agent session
    RE-->>API: session_id
    User->>API: POST /api/chat
    API->>DB: 用户消息 + 会话标题
    API->>RE: 流式推理
    loop SSE
        RE-->>API: text / function_call / citations
        API-->>User: data: { text, model_version }
    end
    API->>DB: 助手全文 + Grounding

客户端用 localStorage 记住活跃 sessionId;服务端 conversations / messages 双表落库。后端不可用时 /api/session 仍返回本地 sessionId 和 backendReady=false,前端能展示可读警告,而不是白屏。

6.3 身份与治理

模式用途
access_code本地 / 演示
google_iapCloud Run + IAP 头;可验 X-Goog-Iap-Jwt-Assertion
trusted_headers企业网关注入
oidc / samlIdP 认证后注入 claim headers

解析后的 principal(tenant_iduser_id、groups)进入会话审计、ACL 检索和 tenant_memberships。后台 RBAC:auditor 只读,admin 可写,owner 最高。SCIM /scim/v2 覆盖 Users / Groups / Bulk 基础操作。用量走 usage_events / tenant_quotas,可导出成本 CSV。

密码类凭据用加盐哈希存储;响应头加上 X-Frame-Options: DENYX-Content-Type-Options: nosniffReferrer-Policy 等。连接器配置里的密钥只存控制面,接口回显必须脱敏。


7. 云原生部署与安全边界

7.1 双流水线

Web 与 Gemini Enterprise 共用 Agent,因此发布顺序必须固定:先 Runtime,再把新 Engine ID 写进 Cloud Run 环境变量。

mermaid
flowchart LR
    Code["提交 nextkb/ 与 server/"] --> Tests["自动化测试"]
    Tests --> Agent["adk deploy agent_engine"]
    Agent --> SyncID["回写 REASONING_ENGINE_ID"]
    SyncID --> Run["gcloud run deploy"]
    Run --> Verify["Web 与 GE 端到端验证"]
bash
# 1) 部署 Agent Runtime(占位符)
adk deploy agent_engine \
  --project="${GCP_PROJECT_ID}" \
  --region="${GCP_AGENT_ENGINE_REGION}" \
  --display_name="NextKB Agent" \
  nextkb

# 2) 部署控制面
gcloud run deploy nextkb-ui \
  --project="${GCP_PROJECT_ID}" \
  --region="${CLOUD_RUN_REGION}" \
  --source=. \
  --set-env-vars="AGENT_BACKEND=reasoning_engine,REASONING_ENGINE_ID=${NEW_ID}"

生产控制面用 NEXTKB_DB_URL 指向 Cloud SQL PostgreSQL,不要把 SQLite 文件放在可丢失的容器盘上。

7.2 权限最小化

  • Reasoning Engine 服务账号:检索侧 roles/discoveryengine.viewer 一类只读角色即可。
  • Cloud Run 服务账号:roles/aiplatform.user 用于调用 Runtime。
  • 后台同步 GCS 时强制校验 bucket 命名空间与前缀,禁止扫到租户未授权的桶。
  • IAP 模式建议设置 JWT audience,并开启 signed JWT 校验作为入口基线。

不要把真实项目号、服务账号 JSON、Data Store 全路径、内部邮箱写进文档或截图。示例一律用 ${GCP_PROJECT_ID}gs://your-knowledge-bucketuser@example.com


8. 经验总结与后续规划

已经验证过的收益

  • 答疑成本下降:复杂拓扑、IAM 模板、API 样例可以按 Runbook 召回,而不是靠人口口相传。
  • 一次索引,多端生效:同一 Data Store 同时服务 Web、移动端适配页和 Gemini Enterprise。
  • Serverless 成本结构:无流量时 Cloud Run 可缩到接近零;推理面按调用计费。

落地时踩过的坑

  • Markdown 原文件直接导入 Search 会因 MIME 被拒或解析质量差,同步层必须转 text/plain
  • 单 Agent 多 tool 与 VertexAiSearchTool 冲突,外部动作要拆 sub-agent。
  • 控制面 RAG prepend 和 Agent 原生 Search 同时开,容易出现引用编号对不上文档。
  • Connector「能同步」不等于 SLA:限流、增量游标、ACL 映射必须用真实租户验收。

Roadmap

  1. Hybrid Fusion 作为默认生产检索,而不是仅后台自检。
  2. 连接器增量同步与供应商 ACL 精准对齐。
  3. 完整 SSO / SCIM 生命周期,而不是只信任网关头。
  4. 评测集与线上 Trace 打通,把幻觉率做成可回归指标。

FAQ

NextKB 的事实知识存在哪?

生产问答看 GCS + Vertex AI Search。控制面数据库只存元数据、审计、ACL 和本地 chunk 自检索引。

Web 门户和 Gemini Enterprise 是两套 Agent 吗?

不是。推荐共用同一个 Reasoning Engine。FastAPI 只代理产品入口;GE 直连 Runtime。

本地怎么开发?

AGENT_BACKEND=adk,本地起 ADK Web 与 FastAPI。不要在开发机写入真实生产 Data Store 的写权限。

如何证明回答不是编的?

检查 SSE / 落库消息里的 grounding 引用是否指向真实文档 URI;后台用 retrieval golden set 回归召回与权限过滤。


结语

NextKB 证明了一件事:企业知识库 Agent 的竞争力不在「再包一层聊天框」,而在 检索与推理托管、控制面治理、权限在检索前生效、发布流水线把双入口当成同一产品。Google ADK + Vertex AI Search + Cloud Run 能把这条链路从 POC 推到可审计的生产形态;真正耗时间的是文档质量、ACL 和评测,而不是再换一个模型名。

若你要从零复制,建议严格按这个顺序:先建 Data Store 与 20 份高质量文档 → 再挂 VertexAiSearchTool → 再补控制面会话与审计 → 最后才上连接器和混合检索。顺序反了,后面每一层都会在错误的事实上做功。

欢迎浏览和收藏🔖我们的主站

Start: 沃尔码API 🙏支持
对于商业化合作请留言。💼
如果本文对您有帮助,可以下方赞赏我们💪💪Good luck!
赞赏博主