41.用FastAPI搭建一个RAG后端需要哪些接口

用 FastAPI 搭建一个 RAG 后端需要哪些接口?

码海寻道 · 大模型、智能体与 RAG 工程组件系列第 41 篇

一个 RAG 后端不只是一个 /chat 接口。要支持文件上传、异步解析、知识库管理、问答、引用、任务状态和权限控制,应该先设计清楚资源和接口边界,再接入模型与向量数据库。

一、先按资源拆接口

text 复制代码
认证与用户
  ├── /api/v1/auth
知识库
  ├── /api/v1/knowledge-bases
文档
  ├── /api/v1/documents
任务
  ├── /api/v1/jobs
问答
  ├── /api/v1/chat
  └── /api/v1/conversations

资源型 API 负责管理事实和状态,Agent、RAG 和大模型属于服务内部的执行链路,不应把所有业务都塞进一个路由函数。

二、推荐的核心接口

接口设计先固定资源关系,再决定具体路径。生产环境建议使用 /api/v1 这类版本前缀,并为每次请求生成 request_id 或沿用上游 trace_id。接口版本、错误码和响应字段一旦被前端使用,就应通过兼容期和变更记录管理,不能只靠修改路由代码。

知识库

http 复制代码
POST   /api/v1/knowledge-bases
GET    /api/v1/knowledge-bases
GET    /api/v1/knowledge-bases/{kb_id}
PATCH  /api/v1/knowledge-bases/{kb_id}
DELETE /api/v1/knowledge-bases/{kb_id}

文档

http 复制代码
POST   /api/v1/knowledge-bases/{kb_id}/documents
GET    /api/v1/knowledge-bases/{kb_id}/documents
GET    /api/v1/documents/{document_id}
DELETE /api/v1/documents/{document_id}
POST   /api/v1/documents/{document_id}/reindex

任务

http 复制代码
GET    /api/v1/jobs/{job_id}
POST   /api/v1/jobs/{job_id}/cancel
POST   /api/v1/jobs/{job_id}/retry

对话

http 复制代码
POST   /api/v1/chat/completions
GET    /api/v1/conversations/{conversation_id}
DELETE /api/v1/conversations/{conversation_id}

三、FastAPI 路由层应该做什么?

路由层负责:

  • 解析请求和响应模型;
  • 鉴权和租户上下文;
  • 参数校验;
  • 调用应用服务;
  • 返回统一错误和状态码。

不建议在路由函数中直接写 Embedding、Milvus 和复杂事务逻辑:

python 复制代码
@router.post("/chat/completions")
async def chat(request: ChatRequest, user: CurrentUser = Depends(get_user)):
    scope = await permission_service.scope_for(user)
    return await rag_service.answer(request, scope)

业务逻辑放在 rag_service,路由更容易测试和替换。

四、请求和响应模型

python 复制代码
from pydantic import BaseModel, Field

class ChatRequest(BaseModel):
    knowledge_base_id: str
    message: str = Field(min_length=1, max_length=8000)
    conversation_id: str | None = None
    top_k: int = Field(default=5, ge=1, le=20)
    stream: bool = False

class Citation(BaseModel):
    document_id: str
    title: str
    page: int | None = None
    snippet: str

class ChatResponse(BaseModel):
    answer: str
    citations: list[Citation]
    trace_id: str

请求模型还应限制字符串长度、分页上限、top_k、模型名称和过滤条件。不要把向量过滤表达式、tenant_id 或权限字段直接交给客户端;这些字段由认证上下文和服务端策略生成。对于创建文档、提交任务和发送消息的接口,支持 Idempotency-Key,避免网络重试造成重复任务。

客户端传来的 top_k 仍需受到服务端上限约束,不能让用户任意扩大召回和模型上下文成本。

五、文件上传不要同步解析

接口只完成:

  1. 校验文件和用户权限;
  2. 保存原始文件到对象存储;
  3. 写入 PostgreSQL 文档记录;
  4. 创建任务并发布消息;
  5. 返回 202 Accepted 和 job_id。
python 复制代码
@router.post("/documents", status_code=202)
async def upload_document(
    file: UploadFile,
    kb_id: str,
    user: CurrentUser = Depends(get_user),
):
    document = await document_service.create_upload(kb_id, file, user)
    return {"document_id": document.id, "job_id": document.job_id}

解析、OCR、切分和索引由异步 Worker 完成,前端通过任务接口查看进度。

上传接口的成功只表示"文件已接收并创建任务",不表示文档已经可检索。响应中应返回 document_id、upload_id、job_id、当前状态和查询地址;任务状态由数据库维护,Worker 通过版本号或乐观锁更新,避免旧任务把新版本覆盖回去。

六、统一错误格式

json 复制代码
{
  "error": {
    "code": "DOCUMENT_NOT_READY",
    "message": "文档仍在解析中",
    "trace_id": "trace-001",
    "details": null
  }
}

错误码供前端和监控使用,展示文案可以由前端根据语言环境转换。不要把数据库堆栈、密钥和内部路径直接返回给用户。

错误还应区分客户端可修正、权限拒绝、依赖暂时不可用和服务端未知异常。对 429、503 等暂时性错误返回 retry_after;对流式接口已经发送部分内容后的失败,则通过事件发送最终 error 或 cancelled 状态,并把运行结果持久化。

七、RAG 问答接口内部流程

text 复制代码
请求进入
  ↓ 鉴权与租户范围
  ↓ 加载会话上下文
  ↓ 查询改写
  ↓ Embedding
  ↓ Milvus / pgvector 检索
  ↓ Reranker 与去重
  ↓ Prompt 组装
  ↓ 大模型生成
  ↓ 引用回查与审计

每一步应有 trace_id 和耗时记录,便于区分是检索慢、模型慢还是数据库回查慢。

八、同步响应还是流式响应?

短回答可以返回 JSON;长回答和聊天体验可以提供 SSE。建议保持同一个业务接口的请求语义,使用 stream=true 选择响应方式,或提供独立的 /chat/stream 接口。

流式接口仍要保存最终消息和引用,不能因为客户端断开就丢失服务端事实。

接口层还要明确取消语义:客户端断开、主动点击停止和服务端超时不是同一种状态。取消请求应沿 run_id 传播到模型、检索、工具和异步任务;无法立即中断的下游调用,要标记为 cancelling 并由后台完成收尾。

九、接口安全清单

  • 所有资源接口都校验用户和租户范围;
  • 文件上传检查大小、类型、哈希和恶意内容;
  • 问答接口限制消息长度、Top K 和模型预算;
  • 数据库和向量过滤由服务端生成;
  • 写操作具备幂等键;
  • 长任务返回 job_id,不阻塞请求;
  • 错误响应不泄露内部信息;
  • 记录 trace_id、审计和调用成本。

结语

FastAPI RAG 后端应该围绕知识库、文档、任务和对话设计资源接口,把路由、业务服务、异步 Worker 和模型链路分层。接口先稳定,内部组件才有替换和扩展空间。

下一篇将转向前端,比较 Vue、React 和 Next.js 如何设计 AI 应用交互。

参考资料

  1. FastAPI 官方文档
  2. FastAPI 官方文档:Request Files
  3. FastAPI 官方文档:Response Model

本文为"码海寻道"原创技术文章。FastAPI、Pydantic 和相关 SDK 会随版本变化,正式项目请以目标版本文档为准。

相关推荐
程序员cxuan1 小时前
玩了一天 REA,我号快没了
人工智能·后端·程序员
阿里云大数据AI技术1 小时前
聚数成湖,以智驭行:卓驭如何构建移动物理 AI 的数据底座
人工智能·spark
武子康2 小时前
150毫秒和2400毫秒:同一 Agent 任务的两种延迟
人工智能·后端·agent
暖心hebbie设计学习2 小时前
GitHub 热榜周报(10.19)|5 个把 AI 装回本地的开源项目:多 agent 控制台、本地语音、节点式生成(含技术看点)
人工智能·github
猪脚踏浪2 小时前
open webui 在docker容器里跑,并且是在内网断绝互联网的环境下。生成ppt
人工智能
海边捡石子2 小时前
FreeSWITCH 入门:把电话系统接入语音客服机器人
人工智能·后端
桃西西呀3 小时前
我把网关限流配置成每秒 100 请求,大促一来照样被打挂,还把别人也拖垮了
人工智能·llm·ai编程
武子康3 小时前
Agent 偏好记忆怎样确认写入:范围、版本与撤销的一个最小例
人工智能·后端·agent
王中阳Go3 小时前
质保期第 90 天我翻了一遍日志目录:交付后真正会坏的 3 处
人工智能·后端·agent
桃西西呀4 小时前
我把整本接口文档塞进 system prompt,前 3 轮答得准,第 8 轮开始胡说,账单还翻了 4 倍
人工智能·llm·ai编程