Files

8.1 KiB
Raw Permalink Blame History

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),并落结构化审计日志(全量)。

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 对接管道

运行测试

cd core/llm-gateway
python -m unittest discover -s tests -v

混合网关主编排(EPIC #6 主体)

LLMGateway.ask() 串起完整闭环:敏感度路由 → 本地/云端生成 → 引用溯源校验 → DLP 出站防线,覆盖 PRD 5.4 用户操作流程(提问 → 路由判断敏感级 → 本地/云端生成 → RAG 溯源校验 → 返回带引用的答案;异常转人工)。

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) 绑定,可复现。

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 转人工确认。

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 变更后可对比各版本幻觉率)。

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 评测报告(总体准确率 + 按预期路由目标分解 + 未通过 样本明细),换行业只换模板资产与评测集,内核零改动。

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)。