# IPRAG
**Repository Path**: ipoter/iprag
## Basic Information
- **Project Name**: IPRAG
- **Description**: No description available
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2026-10-23
- **Last Updated**: 2026-10-23
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# IPRAG · 知识产权智能检索问答系统
面向知识产权从业者的 RAG 问答系统:专利法规 / 专利撰写 / 案例库语料,意图识别 + 四策略混合检索 + 三级缓存 + 引用溯源 + 部门级行级权限,全链路可评估(RAGAS 四指标 + 结构化 trace + Bad Case 回归)。
## 架构
### 离线数据管道(幂等,可重复执行)
```mermaid
flowchart LR
A[8 份源文档 + 50 条 FAQ] --> B[解析与元数据抽取
条款号/章节面包屑/生效日期]
B --> C[一文一块切分
法条按条款 / FAQ 按 Q&A]
C --> D[(MySQL 8.4
文档·chunk·FAQ 元数据)]
C --> E[BGE-M3 本地编码]
E --> F[(Milvus 2.4
5 库向量检索)]
C --> G[jieba 分词]
G --> H[(MySQL BM25 倒排)]
C --> I[50 条 FAQ 发布]
I --> J[(Redis L1 标准问)]
I --> D
```
### 在线问答链路(四级幻觉防线)
```mermaid
flowchart LR
Q[用户提问] --> P{Redis 5 轮会话窗口}
P --> INT[意图识别
patent_law/writing/litigation/search/闲聊]
INT -->|高频问| C1[L1 语义缓存 ≥0.92]
INT -->|FAQ 近似| C2[L2 BM25 缓存 ≥0.85]
INT -->|冷问| ST[策略路由]
ST -->|直问| S1[Direct]
ST -->|检索分析| S2[HyDE 假设答案]
ST -->|维权诉讼| S3[SubQuery 拆解]
ST -->|追问| S4[Backtrack 改写]
S1 & S2 & S3 & S4 --> RT[向量 + BM25 双召回]
RT --> RRF[RRF 融合]
RRF --> RK[ONNX int8 精排 Top5]
RK --> LLM[DeepSeek 流式生成]
C1 & C2 --> LLM
LLM --> CK{引用条款校验
防线4}
CK -->|未通过| DEG[降级提示]
CK -->|通过| ANS[引用卡片 + 答案]
ANS --> T[结构化 trace 日志
25 字段]
```
幻觉四道防线:① 系统 Prompt 只准依据资料回答;② 资料带编号/条款号/效力状态注入;③ 输出模板(结论→依据→建议→免责声明);④ 事后引用条款校验,未核验到则降级提示。
## 快速开始
### 前置条件
- Docker Desktop(分配 ≥ 8GB 内存)
- Python 3.12(conda 环境 `iprag`,`pip install -r requirements.txt`)
- DeepSeek API Key(留空则 /health 中该检查为 skipped,不影响启动)
- 模型:`models/bge-m3`(约 2.1GB)与 `models/bge-reranker-v2-m3`(含 ONNX int8);缺省时首次运行自动在线下载
### 方式一:Docker Compose 一键启动(含应用容器)
```bash
cp .env.example .env # 填入 DEEPSEEK_API_KEY
docker compose -f docker/docker-compose.yml up -d --build
# 基础设施(MySQL/Redis/Milvus/etcd/MinIO)+ 应用容器 iprag-app:8000
```
### 方式二:本地开发模式
```bash
docker compose -f docker/docker-compose.yml up -d # 仅基础设施
conda activate iprag
uvicorn iprag.main:app --port 8000 # PYTHONPATH=src
```
### 灌库(幂等,重复执行自动跳过已入库文档)
```bash
bash scripts/run_stage1_pipeline.sh
```
打开 → 零框架前端,可直接体验流式问答 / 引用卡片 / 反馈点踩;演示身份(专利代理师/商标代理人/律师)在前端切换,验证部门级行级权限。
### 测试与评估
```bash
python -m pytest # 全量测试
PYTHONPATH=src python scripts/eval_ragas.py # RAGAS 四指标评估(黄金集 144 条)
locust -f locustfile.py --headless --host http://127.0.0.1:8000 # 压测 6 分钟
```
## 配置分层
优先级从高到低,同名配置高优先级覆盖低优先级:
| 层 | 位置 | 用途 |
|----|------|------|
| 环境变量 | 容器/进程注入 | 部署期覆盖(compose 已注入服务地址) |
| `.env` | 仓库根(不进镜像) | 密钥与本地连接参数 |
| `config/settings.yaml` | 仓库根(可提交) | 非密钥的项目级调参(Top 融合口径/阈值/温度) |
| 代码默认值 | `src/iprag/config.py` | 兜底默认 |
多环境可用环境变量 `IPRAG_SETTINGS_YAML` 指定其他 yaml 配置文件。
## 指标(实测,报告见 `data/eval/`)
| 指标 | 实测值 | 说明 |
|------|--------|------|
| RAGAS 综合(四指标均值) | 基线 0.834 | 门槛 0.6;`ragas_baseline_report.md` |
| Faithfulness | 基线 0.720 | 4c 优化前后对比见 `ragas_4c_report.md` |
| 意图分类准确率 | 见 `intent_eval_report.md` | 50 条标注集 |
| FAQ 缓存命中(高频集) | 82.9%(35 条) | `cache_eval_report.md` |
| 精排收益 MRR@5 | 0.825 → 0.950 | `rerank_eval_report.md` |
| 策略路由一致率 | 90.3%(130/144) | `strategy_eval_report.md` |
| 流式首包延迟 | 738ms ~ 1.1s | SLO < 1.5s |
| locust 压测观察值 | 待补 | 日 5000 次 QPS 曲线压至 6 分钟 |
## 技术决策 FAQ
**Q1:RAG 相对直接问大模型解决了什么?引用溯源如何实现?**
大模型对专利法这类强时效、强专业语料存在知识截止与幻觉风险。本系统把 82 条法条、撰写规范与 FAQ 切块入库,回答时只允许依据检索资料生成;每条资料带 `[编号] 来源 + 条款号 + 效力状态` 注入 Prompt,答案逐条标注,前端渲染引用卡片可回溯原文(chunk_id → MySQL 原文),并有引用条款事后校验兜底。
**Q2:四种检索策略各适合什么问题?为什么不能只用 Direct?**
口语化的检索分析问法(“怎么查一个方案有没有被人申请过?”)与法律文书向量距离远,Direct 召回弱。路由按意图分流:直问走 Direct;检索分析走 HyDE(先让 LLM 写假设答案贴近资料表述分布,与原问向量加权融合召回);维权诉讼这类复合问题走 SubQuery 拆解多路召回 RRF 合并;追问走 Backtrack 依赖改写。任何策略失败自动降级 Direct,保证链路不中断。
**Q3:三级缓存的收益账怎么算?为什么不全走向量检索?**
高频问题集缓存命中 82.9%:L1(Redis 标准问 + 语义近重复 ≥0.92)/ L2(MySQL FAQ BM25 ≥0.85)/ L3 真实检索生成。命中一次省掉整条“编码→双路召回→精排→LLM”链路,既省 token 成本又把 P95 延迟从秒级压到百毫秒级。全走向量检索无法利用 FAQ 的精确匹配语义,且每问都付全链路成本——二八分布下缓存是确定性收益。
**Q4:部门级权限怎么隔离?**
用户身份(专利代理师/商标代理人/律师)带 access_level,检索在 Milvus expr 与 MySQL WHERE 两层同时注入行级过滤,律师可及案例库、代理人不可见;有/无权限对照实测隔离延迟毫秒级。
**Q5:怎么防幻觉?**
四道防线(见架构图):Prompt 约束、编号化资料注入、结构化输出模板、引用事后校验。校验失败的回答自动降级提示“以上方引用卡片为准”,并写入 Bad Case 池。
**Q6:为什么用 RAGAS?LLM-as-Judge 有什么坑?**
RAGAS 四指标(faithfulness / answer_relevancy / context_precision / context_recall)覆盖“答案忠实、切题、检索准、检索全”四个正交维度,可在无人工标注下做全量回归。实测的坑:判分模型对条款号书写格式敏感(阿拉伯数字 vs 中文数字会导致忠实度误判)、答案过短时 relevancy 偏低、高速率判分时约一半样本产生 NaN 噪声——所以本项目的对比一律用“同队列成对有效样本”口径,并把低分样本导入 Bad Case 池人工复核后再归因。
**Q7:DeepSeek 挂了怎么办?多模型回退怎么工作?**
LLM 走 DeepSeek(主)→ QWEN → OLLAMA 自动回退链:主模型返回 402/401/429/5xx 或网络不可达时,依次切换下一个已配置 Key 的模型(即最多两次回退重试),业务代码只依赖 BaseLLM 抽象、无感知切换。流式回答只在首包前回退——一旦开始产出内容,异常直接上抛,避免同一回答拼接两个模型的输出。`/health` 分项展示三个模型各自状态:主模型挂但备用可用时整体仍为 ok(分项提醒充值),已配置的模型全部不可用才 degraded。两个刻意不回退的口径:评测判分(eval_ragas.py 的 judge)固定 DeepSeek 单模型,保证与 4a 基线判分一致;未配置备用 Key 时链退化为单模型,行为与历史版本完全一致。
## 演示
演示 gif/录屏(待补):5 类用户各问 1 个代表问题 + 1 次追问 + 1 次权限对比 + 1 次缓存命中。
## 目录结构
```
docker/ compose 编排 + 应用镜像 Dockerfile
src/iprag/ 应用源码(api/generation/retrieval/storage/evaluation/observability)
scripts/ 离线管道 + 评估 + Bad Case 管理 + 回归脚本
config/ settings.yaml 项目级配置层
models/ BGE-M3 与 reranker 模型(不入库不入镜像)
data/ 语料与评估产物(黄金集/报告)
tests/ 160+ 测试(单测 + 真实基础设施集成测试)
locustfile.py 压测(日 5000 次 QPS 曲线 → 6 分钟)
```