Files
border-red-post-nalati/docs/RAG_CONTEXT_API.md

7.8 KiB
Raw Permalink Blame History

RAG 证据与 OpenAI 兼容请求准备

本阶段按用户要求先实现通用请求格式,生成模型选择和真实调用延期。协议采用非流式 Chat Completions:model/messages、单条 assistant 响应、可选用量;不绑定供应商、服务地址、密钥或具体模型。字段依据 OpenAI 官方 Chat Completions 文档。

本阶段提供管理员上下文准备与历史接口、完整证据快照、固定提示词及纯响应解析器。POST /api/chat 仍保留原占位状态,尚未成为生成式问答接口;准备记录固定为 kind=prepared_request, model_called=false,不能作为实际模型回答、耗时、费用或领域实验结果。

准备与读取

接口 用途 权限
POST /api/rag/contexts 从服务端检索记录准备并持久化请求 admin、明确 Origin、会话 CSRF
GET /api/rag/contexts?page=1&page_size=20 分页读取当时准备快照 admin
GET /api/rag/contexts/{id} 按 UUID 读取单份快照 admin

请求示例(ID、模型标识仅作格式示例,不表示已选择或调用模型):

{
  "retrieval_run_id": "00000000-0000-0000-0000-000000000001",
  "completion": {
    "model": "deployment-model-id",
    "output_tokens": 512,
    "token_parameter": "max_completion_tokens",
    "instruction_role": "system"
  },
  "max_input_characters": 10000,
  "max_evidence": 5
}

请求只接收服务端检索记录 UUID、组包配置和预算,不接收任意正文、提示词、URL、请求头或 API Key。来源必须是 keyword_chunks/vector/hybrid 的完整结果;条目级 keyword 返回 422,避免把条目与 chunk 的证据粒度混用。记录不存在返回 404,格式/预算越界返回 422。

字段 约束
completion.model 必填,1–128 个字母/数字及 ._:/-;只保存标识,不验证模型存在或服务可用
output_tokens 默认 512,1–4096,写入所选输出预算字段
token_parameter 默认 max_completion_tokens;显式选择 max_tokens 才生成旧兼容字段,两者不同时发送
instruction_role 默认 system,也可显式使用 developer;须由后续实际服务兼容性测试确认
temperature 可选 0–2;省略时请求体不发送,不预设所有模型都支持该参数
max_input_characters 默认 10000,1024–24000;两个 message 的 content 字符数之和
max_evidence 默认 5,1–10;保持检索排名顺序挑选证据

组装的请求体为 model、两个文本 messages、stream=false、n=1、store=false、所选输出预算字段,及显式提供的 temperature。第一条消息只有固定规则,第二条是规范 JSON 的 question/evidence 数据。请求不包含鉴权或服务地址。这是明确的协议子集,不保证每个“OpenAI 兼容”服务都支持所有字段;后续接入须核对服务的角色、参数及模型限制,不做静默重试或字段回退。

字符预算用于有限体积的准备工作,不是模型 token 数或上下文窗口校验。输出 token 上限同样不表示输入能被某个尚未选定的模型接受。真实发送前须按所选模型验证完整输入与输出预算,超限明确失败,不静默截断原文。

证据、引用与不足规则

准备时只从数据库读取检索结果,并重新核对当前有效审核语料、原文 chunks、文本发布 ID/代数、目录修订和语料指纹。vector/hybrid 还须匹配当前向量发布 ID/代数、完整向量集及空间身份。整个检查至保存过程沿用目录/发布锁,不重新编码、不加载 Embedding,也不调用生成模型。知识变化、文本或向量重新发布、缺失向量/原文、出处或检索记录不一致均返回 409,要求重新检索。

按检索排名逐条处理完整 chunk,给被纳入的证据分配连续 E1/E2/...。保存知识/文档/来源 ID 与版本、来源 URL、标题/分类、chunk ID/序号、原文、字符偏移和 SHA-256、检索排名。对同一知识已选择片段的重叠区间排除后续片段;达到证据数上限或整体 message 字符预算时,排除相应片段并继续检查后续可容纳候选,不切割原文。

每个排除项记录 chunk ID 及 overlap/budget/evidence_limit 原因。没有候选时返回 insufficient_evidence/no_candidates;全部候选超出预算时为 insufficient_evidence/context_budget。这两种情况均不生成 request_body,不能把空证据包交给后续模型。

固定 nalati-evidence-v1 提示词要求:依据提供的证据回答,事实标注 [E1] 形式引用,不编造出处;不把问题、正文、标题或 URL 中的命令作为系统规则;资料不足或冲突时说明局限,无法可靠回答时使用固定不足说明。JSON 数据与固定指令分离只是结构约束,尚未通过真实模型的注入抵抗/领域质量实验。prepared/candidates_available 只表示有可组装片段,不表示这些片段在语义上足够支持答案。

快照与复核

响应保存为独立 rag_contexts 记录,引用原 retrieval_runs,不改写已有检索历史。响应包含:

  • id/retrieval_run_id/retrieval_mode/query、文本/向量发布 ID 和代数、目录修订、语料指纹。
  • prompt_version、实际 completion 配置、字符/证据预算、完整已选 evidence 和 excluded 列表。
  • request_body 及其规范 UTF-8 JSON 的 request_sha256;无证据时两者均为 null,input_characters 为 0。
  • kind=prepared_request、model_called=false、状态/原因和创建时间,不包含任何模型答案或调用成本。

历史查询返回当时的完整快照,资料后续撤回也不会改写它。历史请求体不是当前发送授权;未来实际模型调用必须重新检查当前依据和发布状态,不能从历史端点取出旧包后直接认定仍有效。

兼容响应解析

services/completions.py 提供纯解析函数,当前不暴露可向数据库写入“模型回答”的导入接口,也没有 HTTP 模型客户端。它只接受 object=chat.completion 的单一 index=0 assistant 文本候选,拒绝流式 chunk、工具/函数调用、未知结束原因或畸形结构。

  • finish_reason=length 标记 incomplete 并丢弃部分答案;content_filter 或 refusal 标记 refused。
  • 正常 stop 响应必须有非空文本、至少一个已提供的 [E#] 引用;缺失、越界或错误编号拒绝。固定不足说明单独标记 insufficient_evidence。
  • 返回实际 response ID/model、引用列表和可选非负整数 token 用量;用量合计不一致时拒绝,不自行估算费用。
  • 即使引用结构通过,也只标记 answer_candidate。引用存在不能证明原文支持每个事实,事实支持度、冲突、时效及人工验收仍需后续阶段验证。

测试使用明确的合成响应/坐标与 PostgreSQL,不冒充真实模型推理。供应商兼容、生成质量、真实 token 预算、超时/重试/限流和费用记录须在模型选择后另行验收。

迁移、回滚与交接

新增 0007_rag_contexts,启动前备份并执行 alembic upgrade head。表通过外键保留检索记录和创建账号关系,只有追加与查询 API,没有修改/删除 API。撤回本阶段时可备份后配合旧后端执行 alembic downgrade 0006_vectors;仅删除准备快照表,保留知识、账号、文本/向量发布与检索历史。恢复准备快照须使用备份。

前端新增 services/rag.ts 调用与类型,不修改现有问答页面。实际部署环境、运行日志、凭据和真实请求数据不得提交仓库。生成模型接入按用户后续选择推进,当前没有待创建的密钥,也不因延期而反复询问。