Skip to content

Latest commit

 

History

History
159 lines (130 loc) · 9.19 KB

File metadata and controls

159 lines (130 loc) · 9.19 KB

raguide 架构(3 分钟版)

完整设计真相见 superpowers/specs/2026-05-20-raguide-system-architecture.md;面试技术追问的深答见 interview-qa.md;运维故障处置见 runbook.md

一句话

3C 电子产品 AI 导购 Agent:Agentic RAG(外层)+ Modular RAG(内层),Orchestrator 调度 3 个 sub-agents(Intent / Retrieval / Advisor)。默认 Claude 模型族驱动;v1.1 起业主可经「模型设置」面板把任一角色路由到 Claude / GPT / DeepSeek(密钥只走 .env,DB 仅存 env 变量名)。

系统全景

flowchart TD
    Web["Web 客户端<br/>Next.js 15 + React 19 + AI SDK 6.x"]
    BE["FastAPI + LangGraph<br/>(宿主 uvicorn :8000,非容器)"]
    Web -- "SSE 9 事件<br/>(Bearer JWT / X-Owner-Id)" --> BE

    subgraph Auth["认证 / RBAC / 统一身份"]
        AU["/v1/auth register·login·me<br/>HS256 JWT + bcrypt"]
        ID["effective_owner_id<br/>JWT.sub 优先,回退 X-Owner-Id"]
        AD0["require_admin<br/>Bearer admin JWT + X-Admin-Token 后备"]
    end
    BE --> Auth

    subgraph Agents["Orchestrator + 3 sub-agents"]
        IA["IntentAgent<br/>意图槽位 json_schema"]
        RA["RetrievalAgent<br/>Modular RAG 内层"]
        AD["AdvisorAgent<br/>5 工具 + emit_cards"]
    end
    BE --> Agents

    subgraph Stores["存储 / 检索(全自托管)"]
        QD["Qdrant<br/>text + image 双 collection"]
        TA["Tantivy<br/>BM25 稀疏"]
        PG["PostgreSQL 16<br/>specs / gold-set / feedback / 配置"]
        RD["Redis 7<br/>缓存 + 月成本累计"]
        SX["SearXNG<br/>CRAG 兜底"]
        MN["minio<br/>用户上传图"]
    end
    RA --> QD & TA & SX
    AD --> PG
    BE --> RD & MN

    subgraph Models["模型服务(自托管)"]
        BGE["bge-m3 嵌入"]
        JC["JinaCLIP-v2 图像"]
        RR["bge-reranker-v2-m3"]
    end
    RA --> BGE & JC & RR

    subgraph Obs["可观测 / 评测"]
        LF["Langfuse 3<br/>9 字段 span trace"]
        PR["Prometheus + Alertmanager<br/>9 条告警规则"]
        GF["Grafana 5 看板 32 panel"]
    end
    BE -. "trace / metrics" .-> Obs
    PR -- "webhook" --> BE
Loading

Agent 编排(LangGraph StateGraph)

flowchart LR
    O["orchestrator<br/>状态初始化<br/>(无 LLM)"]
    O -->|空/空白输入| C["clarify<br/>固定澄清话术<br/>(零 LLM)"]
    O -->|正常| I["intent"]
    I --> R["retrieval<br/>Modular RAG"]
    R --> A["advisor"]
    A -->|工具调用| T["tool_dispatch"]
    T -->|证据增广回写| A
    A -->|done| E["END + done_hook<br/>(LLM-judge 评分 + 画像更新)"]
    C --> E
Loading

条件边由 _route_after_orchestrator 决定;advisor⇄tool_dispatch 是工具循环(SAME_TOOL_CAP=3 / MAX_ITER=5 安全帽);成功的 get_product_details/spec_query_sql 结果回写 evidence channel,统一 emit_cards / 评测 F5 / LLM-judge 的 grounding 口径(P3)。

Modular RAG 内层(RetrievalAgent)

flowchart TD
    Q["query + slots"] --> PRE
    subgraph PRE["Pre-Retrieval(intent 条件路由 / 分支)"]
        HY["HyDE"]
        MQ["Multi-Query"]
        DC["Decompose"]
    end
    PRE --> FAN
    subgraph FAN["三路检索(并发 fan-out / 分支)"]
        BM["BM25 (Tantivy)"]
        DE["Dense (bge-m3)"]
        IM["Image (JinaCLIP-v2)"]
    end
    FAN --> RRF["RRF Fusion (k=60)"]
    RRF --> POST
    subgraph POST["Post-Retrieval(线性)"]
        RK["Reranker (TEI)"]
        CP["Contextual Compression"]
    end
    POST --> SE{"Self-Eval<br/>(max 2 轮)"}
    SE -->|不足| PRE
    SE -->|够| OUT["evidence"]
    SE -->|检索质量差| CRAG["CRAG SearXNG 兜底"]
    CRAG --> OUT
Loading

任一路 fan-out 失败不阻塞其余路(容错降级);TEI rerank 超时回退 RRF top-5(finding-017)。

5 个子系统

  1. KB Ingestion — 离线 job,文档(Docling 主路;MinerU/VLM 表格兜底为 descope 项未实现)→ bge-m3 → Qdrant + Tantivy + Postgres
  2. RAG + Agent Backend — 在线服务(本图主体)
  3. LLM Gateway — 自研 Ports & Adapters(不用 LiteLLM),内嵌在 ②;DB 角色映射热重载 + FallbackChain
  4. Evaluation & Feedback — 评测闭环(75 例 gold-set + AgentEvaluator + LLM-judge + CI gate)
  5. Web Client — Next.js(对话展厅 + 检索透明化 Inspector + 在线 KB/模型/预算管理)

认证 / RBAC / 统一身份层(M·auth,已并 main ✅)

跨三端(后端 / web / iOS)的统一身份与权限层,在不破坏游客匿名访问的前提下叠加可选登录与业主权限分级。

  • 认证POST /v1/auth/register | login 签发 HS256 JWT(claim sub / username / role),GET /v1/auth/me 凭 token 回取身份。口令经 bcrypt(72 字节截断,不存明文、不入日志);login 失败统一 401 防用户名枚举;register 在单事务内 count + insert —— 首位注册用户即 admin
  • 用户表usersid = u_acct_<hex> / username unique / password_hash / role / created_at)。
  • 统一身份(关键设计)
    • effective_owner_id(agent 路径):有效 JWT → owner_id = claim.sub;否则回退 X-Owner-Id 请求头;游客返回空串 ""游客零回归)。
    • require_owner_id(profile / conversations 路径):缺身份时返回 422。
    • 即「登录用户用稳定 u_acct_<hex>、游客用 device id」做 data-scoping,登录态与匿名态走同一套下游逻辑。
  • RBACrequire_admin = Bearer admin JWT 优先 + X-Admin-Token 后备(保留旧接入方式)。前端按角色隐藏管理入口:web {isAdmin && ...}(6 个管理入口),iOS if auth.isAdmin(管理段)。
  • token 存储:web 存 localStorage(只持久化 token,user/me hydrate,密码不入 state);iOS 存 Keychain(service raguide.auth)。
  • 配置 / 依赖config 新增 jwt_secret(env JWT_SECRET)+ jwt_expire_days;新依赖 pyjwt + bcryptJWT_SECRET 留空时 register/login 返回 503 AUTH_DISABLED,游客功能不受影响(运维细节见 runbook)。
  • Langfuse 身份分离:trace user_id = acct:<username> / guest:<device>(人读视角),与 data-scoping 用的 owner_id(稳定 u_acct_<hex> / device id)分离;session_id 按会话。

L0 评测闭环富化(已实现 ✅)

done_hook 把低分候选挖入池时一并存 signalsintent_type / 抽取槽位 / 工具);admin approve 时读 signals 富化 gold-set expected_slots(category / intent_type / preferences / mentioned_products / budget,空值丢弃)+ 富 notes 后,写入 human_verified gold-set。expected_safety 不捏造;pre-fix 阶段 signals = NULL 的存量候选降级为空槽。对应 L0 写入门禁(Action-Verified Only)。

关键设计原则(硬约束)

  • 全 LLM 输出强制 json_schema / function calling,严禁正则解析自由文本
  • Trace span 必含 9 字段(step / input / output / model / tool_name / tokens_in / tokens_out / latency_ms / error / status)
  • 评估 5 维度加权(task_completion 30% + output_quality 30% + process_quality 20% + efficiency 10% + safety 10%)
  • 测试集 5 类别覆盖(happy / edge / error / adversarial 必含 prompt injection / regression)
  • System prompt 6 要素框架(身份 / 能力 / 工作流程 / 输出格式 / 质量标准 / 安全红线)
  • 工具 metadata 含 trigger_conditions + exclusion_conditions
  • Distributed Prompt Storage:Orchestrator 极简(纯状态节点,无 prompt);领域 SOP 落 docs/sops/*.md,Advisor 用 read_sop(name) 按需加载
  • 凭据只走 .env,永不硬编码、永不进 git

关键 trade-off(面试问什么答什么 · 深答见 interview-qa.md)

Q A(一句话)
为什么 LangGraph 不 LangChain graph-native,状态机 + 条件边 + checkpoint 能讲清编排
为什么 Qdrant 不 Pinecone 成本可控 + 自托管可演示 + 数据主权
为什么 bge-m3 不 OpenAI Embedding 数据主权 + 成本 + 稠密/稀疏/ColBERT 三合一
为什么 Intent 默认用 Haiku 角色 结构化抽取任务 + 低延迟 + 便宜(provider 可经面板换)
为什么 Agent 不 RAG-only 工具调用让「5000 以内电池 5000+」这类结构化查询走 SQL(双列存储)
为什么自研 LLM 抽象不 LiteLLM Ports & Adapters 可讲;Protocol + Template Method + Registry + Chain of Responsibility 四模式协同
为什么评测规则 + LLM-judge 混合 确定性维度(efficiency/process/task/safety)规则打分稳定可复现,主观维度(output_quality)交 judge

可观测 / 评测层(已实现 ✅)

Langfuse 3 自托管(9 字段 span)+ 自研 AgentEvaluator 5 维度加权 + 75 例 gold-set(5 类别)+ LLM-as-Judge + 双门禁 CI gate(no-regression 0.03 + safety floor 0.5)+ Grafana 5 看板 32 panel + Prometheus 9 条告警规则 + Alertmanager → 后端 webhook。Ragas 4 指标已接线但 DEFERRED(ragas 0.2.x 与 langgraph 1.2.x 争 langchain-core,本环境未产出数据)。当前 baseline weighted 0.838(v3)。映射到 17 项 DoD —— 逐项验收见 dod-verification.md