Files
iAOP/core/llm-gateway/README.md
T

184 lines
8.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# iAOP-Core · LLM 网关(LLM Gateway)
对应 PRD 5.4「④ LLM 网关 + RAG」与 EPIC #6:
本地 70B(敏感/核心)+ 云端 API(脱敏/通用)**混合**,安全分级路由,
**敏感数据本地闭环,仅脱敏/公开内容可走云端 API**(数据不出厂)。
## 模块结构
```
core/llm-gateway/
├── __init__.py 包入口(导出各模块 API)
├── dlp.py DLP 敏感数据拦截引擎(Issue #48)
├── router.py 敏感度路由规则引擎(Issue #43 雏形)
├── prompts.py Prompt 版本管理(Issue #47)
├── hallucination.py 幻觉/事实性校验中间件(Issue #47)
├── evaluate_hallucination.py 幻觉/事实性评测报告脚本(Issue #47)
├── gateway.py 混合网关主编排(EPIC #6 主体交付)
├── config/
│ ├── dlp.template.yaml 模板 DLP 规则资产(ti-cl4 示例)
│ ├── router.template.yaml 模板敏感度路由规则资产
│ └── prompts.template.yaml 模板提示词版本库资产
└── tests/
├── _bootstrap.py 测试引导(目录含连字符,挂载包名 llm_gateway)
├── test_dlp.py DLP 引擎单元测试
├── test_router.py 路由引擎单元测试
├── test_prompts.py Prompt 版本库单元测试
├── test_hallucination.py 幻觉/事实性校验单元测试
└── test_gateway.py 网关主编排端到端单元测试
```
## DLP 敏感数据拦截(Issue #48)
出站防线:任何要发往**云端**的内容(用户 query / RAG 检索到的 context /
模型输出)先经 `DlpEngine.check_outbound()` 检查,**命中任一 block 规则
即整包拦截**(fail-closed),并落结构化审计日志(全量)。
```python
from llm_gateway.dlp import DlpEngine
engine = DlpEngine.from_template_config("config/dlp.template.yaml")
result = engine.check_outbound({
"query": user_query, # 用户提问
"context": rag_context, # RAG 命中文档片段
"output": llm_answer, # 模型生成结果
})
if result.blocked:
# 不发往云端:转本地处理 / 转人工确认 / 拒绝(PRD 5.4 异常时转人工)
engine.drain_audit() # 取走审计记录(对接外部审计管道)
```
### 语义(目标 DLP 拦截率 100%)
- **命中即拦截**:`decision="block"`、`reason="hit"`;
- **未配置即拦截**:引擎无任何规则(含内置保底)且 `fail_closed=True` 时
`reason="no_rules"`——未配置 = 不安全,保守拒绝出站;
- **审计不落明文敏感内容**:命中明细只记录规则名 / 类别 / 所属 part /
位置与 `<category>` 脱敏占位。
### 规则来源
1. **内置保底**(`DLP_DEFAULT_RULES`,内核自带):通用 PII 与凭证
(身份证、手机号、邮箱、IPv4、云访问密钥 AK、密钥键值对)+ 示例工艺词;
2. **模板资产**(`config/dlp.template.yaml`):行业敏感资产(工艺参数 /
配方 / 关键设备 / 人员岗位),同名规则覆盖内置实现模板定制。
规则两种匹配方式:`keyword`(大小写不敏感子串)与 `regex`(正则)。
### 验收对照(PRD 5.4 / 父 Issue #6)
| 验收项 | 实现 |
|--------|------|
| DLP 拦截率 100% | fail-closed:命中即 block;未配置规则也 block |
| 敏感数据本地闭环 | 出站(云端通道)必经 check_outbound 检查 |
| 敏感词/DLP 规则为配置点 | `config/dlp.template.yaml`,换行业只改资产 |
| 审计日志全量(NFR 安全-数据) | 每次检查落一条结构化审计,可 drain 对接管道 |
## 运行测试
```bash
cd core/llm-gateway
python -m unittest discover -s tests -v
```
## 混合网关主编排(EPIC #6 主体)
`LLMGateway.ask()` 串起完整闭环:**敏感度路由 → 本地/云端生成 → 引用溯源校验
→ DLP 出站防线**,覆盖 PRD 5.4 用户操作流程(提问 → 路由判断敏感级 →
本地/云端生成 → RAG 溯源校验 → 返回带引用的答案;异常转人工)。
```python
from llm_gateway import LLMGateway
from llm_gateway.dlp import DlpEngine
from llm_gateway.router import SensitivityRouter
from llm_gateway.prompts import PromptRegistry
gw = LLMGateway(
dlp=DlpEngine(),
router=SensitivityRouter.from_template_config("config/router.template.yaml"),
prompts=PromptRegistry.from_template_config("config/prompts.template.yaml"),
high_stakes_names=["alarm_explain"], # 高利害模板启用信度阈值
)
result = gw.ask("炉温偏高怎么处理", rag_context=["沸腾氯化炉异常处置SOP"])
print(result.route.target) # local / cloud / block
print(result.verdict.action) # pass / human_review / unsupported
if result.needs_human:
... # 转人工确认(PRD 5.4 异常时转人工)
```
- **敏感度路由**(router.py,Issue #43 雏形):模板配置驱动,DLP 拦截
fail-closed 强制 block,未知内容保守走本地(数据不出厂);
- **Prompt 版本管理**(prompts.py,Issue #47):semver 版本库、
运行时绑定(可复现)、一键回滚、变更审计;
- **幻觉/事实性校验**(hallucination.py,Issue #47):`[来源: X]`
引用溯源强制校验 + 高利害信度阈值 → 人工确认,并与 Prompt 版本库联动
(评测按 `name@version` 分解,Prompt 变更后可对比各版本事实一致性);
- **推理后端抽象**(gateway.py 内 `InferenceBackend`):业务代码只依赖
接口,本地 70B / 云端 API 具体接入由子任务 #44 / #45 实现。
## Prompt 版本管理 + 幻觉/事实性校验(Issue #47)
对应 PRD 5.4「Prompt 版本管理 + 幻觉/事实性校验」。
### Prompt 版本管理(prompts.py)
所有提示词模板纳入版本库(semver),变更须评审并记录(同版本号覆盖报错),
支持一键回滚;生产流程运行时按 `(name, version)` 绑定,可复现。
```python
from llm_gateway.prompts import PromptRegistry
reg = PromptRegistry.from_template_config("config/prompts.template.yaml")
pv = reg.get("qa", version="1.0.0") # 显式绑定旧版本:行为不受后续变更影响
rendered = pv.render(query="炉温偏高怎么处理")
reg.promote("qa", "1.0.1")
reg.rollback("qa") # 一键回滚
```
### 幻觉/事实性校验(hallucination.py)
RAG 答案强制引用溯源:输出中所有 `[来源: X]` 声明必须命中本次 RAG 检索的
文档片段,否则判 `unsupported`(幻觉嫌疑);高利害输出(处置建议 / 报警解释)
要求信度 ≥ 阈值,否则 `human_review` 转人工确认。
```python
from llm_gateway.hallucination import HallucinationGuard
guard = HallucinationGuard(default_threshold=0.8)
v = guard.check(
answer="建议降温。[来源: 沸腾氯化炉异常处置SOP]",
sources=["沸腾氯化炉异常处置SOP"],
confidence=0.95, high_stakes=True,
prompt_name="alarm_explain", prompt_version="1.0.0", # 与版本库联动
)
print(v.action) # pass / human_review / unsupported
```
### 定期评测报告脚本(evaluate_hallucination.py)
PRD 5.4「定期用评测集检验事实一致性」:评测集 JSON + 版本库配置 →
Markdown 评测报告(按 `name@version` 分解,Prompt 变更后可对比各版本幻觉率)。
```bash
cd core/llm-gateway
python evaluate_hallucination.py --demo --output reports/hallucination.md
python evaluate_hallucination.py --samples eval_set.json --output report.md
```
## 路由准确率评估(Issue #49)
PRD 5.4 / EPIC #6「敏感度路由准确率 ≥ 96.5%」:评测集 JSON + 路由规则
模板配置 → Markdown 评测报告(总体准确率 + 按预期路由目标分解 + 未通过
样本明细),换行业只换模板资产与评测集,内核零改动。
```bash
cd core/llm-gateway
python evaluate_routing.py --demo --output reports/routing.md
python evaluate_routing.py --samples eval_set.json --output report.md
```
## 后续子任务(EPIC #6 拆分,待扩展)
- 本地 70B 模型接入与推理封装(Issue #44);
- 云端 API(Qwen/DeepSeek)接入与安全网关(Issue #45)。