外观
RAG 专项边界
RAG 是 Chat 和处方能力的运行时依赖,但它不是普通工具函数。当前代码把业务入口、兼容实现、检索编排、证据策略、LLM 生成和生产配置拆成多个层次,读代码时应优先从 runtime 入口和业务调用方建立边界。
边界总览
| 层级 | 主要文件 | 职责 | 不承担 |
|---|---|---|---|
| 运行时装配 | app/bootstrap.py、app/runtime.py | 在 app.state 绑定 rag_engine_getter,业务代码通过 resolver 取运行时对象。 | 不包含检索策略。 |
| 兼容入口 | app/core/rag_runtime_gateway.py | 对外暴露 safe_search_and_generate、generate_prescription_with_fallback 等稳定入口,并把调用委托给底层实现。 | 不直接实现检索、生成或安全规则。 |
| 底层实现 | app/core/rag_engine.py | 保留 RAGEngine、legacy 流程和对拆分模块的编排入口。 | 不应成为新业务层直接 import 的对象。 |
| RAG package | app/core/rag/* | 承接 query understanding、DB 检索、rerank、证据裁剪、context formatting、response generation、prescription generation。 | 不直接注册 API route。 |
| 业务调用方 | app/use_cases/chat/send_message.py、app/services/prescription_service.py | 决定何时调用 RAG、如何持久化结果、如何处理 fallback。 | 不改写底层检索策略。 |
入口约束
当前业务层不直接绑定 get_rag_engine()。入口约束由测试固定:
| 约束 | 说明 |
|---|---|
runtime.py 默认 getter | bind_runtime_context() 缺省注入 get_rag_runtime_gateway。 |
bootstrap.py 生产装配 | create_app() 明确把 rag_engine_getter=get_rag_runtime_gateway 传入 runtime context。 |
| API / service 装配 | Chat、Prescription、Safety 的本地构造函数默认使用 gateway 或 resolve_rag_engine(...)。 |
| 直接 import 限制 | from app.core.rag_engine import get_rag_engine 只允许出现在 gateway 模块。 |
Chat 边界
Chat 主链由 SendChatMessageUseCase 编排:
- 根据请求参数可切换 LLM provider。
- 调用
SafetyFilter.check_content_safety()做输入安全检查。 - 高风险且有
suggested_response时直接返回安全建议,不进入 RAG 检索。 - 安全通过后补充用户画像和会话历史。
- 调用
rag_engine.safe_search_and_generate(...)。 - 根据 RAG 返回的
intelligent_response、suggested_response、model_info.fallback生成前端响应。 - 登录用户写入
chat_sessions与dialogue_logs;未登录或写库失败时走临时存储回退。
处方边界
处方主链由 PrescriptionService.generate_prescription() 编排:
| 步骤 | 行为 |
|---|---|
| 用户档案 | 读取基础信息、健康指标、疾病史、手术史和评估上下文。 |
| 对话历史 | 拉取近期对话历史作为处方生成上下文。 |
| 生成入口 | 调用 generate_prescription_with_fallback(...)。 |
| 当前实现 | PrescriptionGenerationService 直接构造处方 prompt 调用 LLM,不检索 knowledge_chunks。 |
| 安全检查 | 对生成的处方结构执行 check_prescription_safety(...)。 |
| 持久化 | 写入 sport_schemes;带 session 时可写入 dialogue_logs 处方卡片。 |
处方链路虽然通过 RAG runtime 入口访问,但当前返回中 rag_used=false、knowledge_sources=[]、information_source=基于循证医学通识。文档和联调都不应把处方生成写成已经使用知识库召回。
知识表边界
| 表 | 当前角色 | 使用方式 |
|---|---|---|
knowledge_chunks | 当前 canonical 知识主表 | hybrid / legacy 检索都通过该表承接知识片段和表格记录。 |
rag_knowledge_items | legacy 表 | 生产估算行数为 0,不作为当前主路径。 |
rag_vector_index | legacy 表 | 生产估算行数为 0,不作为当前主路径。 |
app/core/rag/persistence_topology.py 是 RAG 持久化拓扑的代码侧真相源,明确声明 knowledge_chunks、legacy 表名、HNSW index 名和 rag_schema 过滤逻辑。
生产与本地差异
| 维度 | 代码默认 | 生产运行 |
|---|---|---|
| RAG pipeline | legacy | hybrid |
| Rerank | False | true |
| Hybrid schema tag | v1 | v1 |
| 默认 LLM provider | moonshot | moonshot |
本地默认值用于缺少 .env 时保持服务可启动;生产事实以 ECS 环境变量和 fitdoc-core 当前运行配置为准。
测试护栏
| 测试 | 覆盖点 |
|---|---|
tests/core/test_rag_entrypoint_contract.py | 业务入口不得直接 import 旧 engine getter。 |
tests/core/test_rag_runtime_gateway.py | gateway 委托核心方法并保留属性透传。 |
tests/api/test_rag_local_assembly.py | Chat、Prescription、Safety 本地装配默认使用 runtime gateway。 |
tests/test_rag_hybrid_contract.py | hybrid 主链字段、错误回退和安全短路契约。 |
来源锚点
- Runtime:
apps/backend_service/app/runtime.py - App assembly:
apps/backend_service/app/bootstrap.py - Gateway:
apps/backend_service/app/core/rag_runtime_gateway.py - Chat use case:
apps/backend_service/app/use_cases/chat/send_message.py - Prescription service:
apps/backend_service/app/services/prescription_service.py - RAG topology:
apps/backend_service/app/core/rag/persistence_topology.py - Tests:
apps/backend_service/tests/core/test_rag_entrypoint_contract.py、apps/backend_service/tests/api/test_rag_local_assembly.py