AgentChat
← 所有文章
RAG·9 分钟阅读

如何仅使用一个文档搜索 API 构建 RAG 聊天代理

通过记录一个专注的搜索端点,将私有知识连接到代理,而无需重建整个检索系统。

此参考集成将私有知识聊天添加到名为 KnowledgeBox 的现有文档 SaaS 中。KnowledgeBox 已经为文件建立索引并强制执行工作区权限。它将其搜索 API 文档提供给 AgentChat,创建一个租户范围的会话,并让 AgentChat 决定何时以及如何检索证据。

KnowledgeBox 不会将其文档数据库上传到 AgentChat,也不会将检索功能重新构建为自定义模型工具。其自有搜索 API 仍是唯一能够读取已建立索引的客户内容的服务。

步骤 1:定义 KnowledgeBox 搜索契约

POST /v1/search
{
  "query": "How long are audit logs retained?",
  "limit": 8,
  "filters": { "collection_ids": ["security"] }
}

→ {
  "results": [
    { "document_id": "doc_42", "title": "Security Policy", "section": "Audit retention", "text": "Audit logs are retained for...", "score": 0.91, "source_url": "/documents/doc_42#audit-retention" }
  ],
  "query_id": "qry_88"
}

API 会验证注入的用户凭据,并在检索前按已获授权的工作区进行筛选。它返回精简的文本片段和引用字段,而不是完整的私密文档。智能体需要更多上下文时,第二个读取端点可以返回特定章节。

步骤 2:在 AgentChat 中注册完整的搜索指令

curl -X POST "$AGENT_CHAT_URL/api/api-documents" 
  -H "Authorization: Bearer ac_live_AGENT_CHAT_KEY" 
  -H "Content-Type: application/json" 
  --data '{
    "title": "KnowledgeBox Search API",
    "description": "Search authorized workspace documents and return citable passages.",
    "content": "# KnowledgeBox Search API\nBase URL: https://knowledge.example.com/v1\n\nUse POST /search before answering questions about workspace knowledge. Send a focused natural-language query. Results are already permission-filtered. Cite title, section, and source_url. If results are weak, reformulate once. If results remain empty, say the documents do not contain the answer. Never claim a fact that is not supported by a returned passage.\n\nPOST /search body: query string required; limit integer 1-10; filters.collection_ids optional. Response results contain document_id, title, section, text, score, source_url.\n\nGET /documents/{document_id}/sections/{section_id} reads one authorized section when a search passage is incomplete."
  }'

返回的文档 UUID 会保存到 KnowledgeBox 配置中。附加该文档的聊天会包含完整的文档内容,因此智能体在调用搜索 API 之前就能了解请求和引用规则。

步骤 3:创建工作区范围的 RAG 会话

POST /api/agent/sessions
Authorization: Bearer ac_live_AGENT_CHAT_KEY
Content-Type: application/json

{
  "title": "Workspace ws_17 knowledge assistant",
  "llm_config_id": "llm_config_uuid",
  "api_document_ids": ["knowledge_search_doc_uuid"],
  "system_prompt": "Answer from retrieved workspace evidence. Include source title and URL for factual claims.",
  "max_turns": 12,
  "host_headers": [
    { "host": "knowledge.example.com", "header_key": "Authorization", "header_value": "Bearer short_lived_workspace_user_token" },
    { "host": "knowledge.example.com", "header_key": "X-Workspace-ID", "header_value": "ws_17" }
  ]
}

KnowledgeBox 会为每个用户对话创建一个独立的 AgentChat 会话。系统会重复使用同一份搜索文档,但每个会话都会收到不同的只写标头。模型可以在提示中看到 API 合约和工作区名称,但永远看不到 bearer 令牌。

第 4 步:发送用户问题

POST /api/agent/sessions/session_uuid/chat
Authorization: Bearer ac_live_AGENT_CHAT_KEY
Content-Type: application/json

{ "message": "Can customer data be removed from backups immediately? Please cite the policy." }

AgentChat 会立即返回处理中状态。在运行期间,代理通过 http_request 调用 POST https://knowledge.example.com/v1/search。AgentChat 会匹配主机名,并在发送请求之前注入工作区标头。

实际的检索流程

  1. 搜索客户数据删除和备份删除政策。
  2. 检查 KnowledgeBox 返回的标题、章节、分数和段落。
  3. 如果备份行为不完整,则针对备份保留和恢复执行第二次聚焦搜索。
  4. 可以选择按 ID 读取一个特定章节,而不是检索完整文档。
  5. 撰写一份区分主要数据立即删除与备份按计划到期的答案。
  6. 包含 API 返回的来源标题和来源 URL。

来自同一次模型响应的搜索调用可能会并发运行。如果第二个查询依赖于对第一个结果的解读,则必须在后续的模型轮次中执行。AgentChat 会持久化每个工具结果,因此最终答案以智能体收到的确切段落为依据。

步骤 5:在 KnowledgeBox 中呈现聊天进度

GET /api/agent/sessions/session_uuid/messages?after_id=&after_revision=0
Authorization: Bearer ac_live_AGENT_CHAT_KEY

KnowledgeBox 每秒通过其后端轮询一次。它按消息 ID 合并行,并且仅在修订版本增加时接受更新。工具消息可以显示为简洁的“正在搜索工作区知识”活动,而助手内容则会根据持久化数据库支持的消息行逐步呈现。

最终答案仍是 AgentChat 历史记录的一部分。引用的来源 URL 会指向 KnowledgeBox,普通文档查看器会在打开来源前检查当前用户的权限。

为什么这是 AgentChat 集成,而不是通用的 RAG 演示

  • 搜索契约通过 /api/api-documents 进行配置,并通过文档 UUID 附加。
  • 所选模型、提示词、限制和 API 权限属于 AgentChat 会话。
  • 检索由内置 HTTP 工具执行,而不是由编译到代理中的自定义搜索工具执行。
  • 用户身份通过主机特定的会话标头注入,并且绝不会向模型披露。
  • KnowledgeBox 客户端使用 after_id 和 after_revision 游标来消费持久消息。
  • 停止、可恢复错误以及因达到最大轮次而暂停的会话,都可以通过 AgentChat continue 端点恢复。

此集成的生产环境测试

  • 在两个工作区会话中询问相同的问题,并验证每个会话只接收到属于自己的段落。
  • 返回空结果,并确认代理不会编造答案。
  • 返回相互冲突的策略版本,并确认代理会引用并解释这一冲突。
  • 使工作区令牌过期,并验证 API 返回 401,同时不会泄露文档是否存在。
  • 在多次搜索回答期间停止处理,然后从持久化历史记录继续。
  • 当搜索筛选条件或响应字段发生变化时,更新已注册的 API 文档。