Files
2026-09-22 15:42:25 +08:00

149 lines
14 KiB
Markdown
Executable File
Raw Permalink 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.
# 阶段八 · 项目 5:Level5 生产级 —— 企业智能客服 Agent
> 所属:阶段八 从入门到生产的实战项目路线
> 定位:阶段八的收尾,也是整个 16 周学习计划的毕业设计。这一级把前面所有阶段能力捏合成一个「能上线、能扩、能迭代」的完整生产系统——不是 Demo,是真的能部署给用户用的产品。
## 项目概览
| 项 | 内容 |
|-|-|
| 难度 | Level5 生产级 |
| 核心功能 | 知识库答疑 + 工单创建 + 人工转接 + 多租户后台 |
| 技术栈 | LangGraph + RAG + 工单系统 + 管理后台 + Docker 部署 |
| 周期 | 6-8 周 |
| 核心学习目标 | 完整工程落地;权限、持久化、监控告警;线上迭代闭环 |
## 一句话看懂本项目的系统分层
```mermaid
graph TD
U[用户入口<br/>客服前台] --> R[意图分流<br/>客服/订单/转人工]
R --> Q[知识问答 RAG<br/>Level2 能力]
Q --> E{能否满足?}
E -->|否| T[建工单<br/>Level4 能力]
E -->|是| A[答复]
T --> S[多租户后台<br/>权限/监控/工单管理]
S --> D[Docker Compose 部署<br/>应用+worker+Redis+PG+Qdrant]
```
> 核心认知:**生产级不是在功能上加花活,而是把每个环节的『不靠谱』都堵住**——状态不丢、权限不漏、故障可控、数据可追。这才是从 0 到 1 之后真正拉开差距的地方。
> 🔬 **深度理解 · 企业智能客服(从 Demo 到生产系统)**:
> 1. **本质**:生产级不是"多了几个功能按钮",而是把系统从"在理想条件下能跑"提升到"在真实恶劣条件下也可靠可用"——核心矛盾从'能不能实现'变成'故障/权限/合规/迭代'这些非功能属性。
> 2. **机制**:把每类『不靠谱』用确定性机制堵上——状态持久化(Checkpointer + Redis/PG,重启不丢),多租户隔离(thread_id = 租户+会话、向量元数据过滤),权限分级(高危操作审批),审计(append-only 存储 + trace_id 串链路),监控告警与优雅停机、评测/Bad-case 闭环。
> 3. **为什么重要**:它决定了系统能否进企业采购清单——补上可用性、合规、可迭代这些能力,领先的不再是"技术炫技",而是"敢不敢交付给真实用户生产环境"。
> 4. **易错点/常见误解**:别把生产化简化成"能多租户计数 + 能 Docker 跑起来"——真正的生产指标是"故障能发现、状态不丢、数据能对齐、能力能越改越好"。也常有人以为"功能越多越生产",恰恰相反,克制地收敛 scope、把底线机制做扎实才更接近生产。
## 学习内容详情
### 1. 项目要点(完整工程落地)
- **骨架**:意图分流 → 知识问答(RAG,复用 Level2)→ 满足不了 → 转人工 / 建工单(复用 Level4 的 SQL 与数据能力)。
- **多租户隔离**:`thread_id = 租户 ID + 会话 ID`;向量库元数据过滤实现租户级隔离(对照阶段六客服与阶段四向量库)。
- **状态持久化**:Checkpointer + 存储后端(Redis / Postgres);服务重启任务状态不丢(对照阶段五断点、阶段七部署)。
- **权限控制**:敏感操作(查订单 / 工单)按角色权限分级;高危动作人工审批。
- **监控告警**:任务成功率 / LLM 失败率告警 + 完整链路日志(对照阶段七监控)。
- **部署**:Docker Compose 一键拉起「应用 + worker + Redis + PG + Qdrant」(对照阶段七 docker-compose);生产规模上 K8s + HPA(呼应[阶段七 02《部署与伸缩》](../07-阶段七-工程化部署与运维/02-部署与伸缩.md)),Docker Compose 用于开发与演示。
> 🔬 **深度理解 · 多租户隔离(Multi-Tenancy)**:
> 1. **本质**:多租户隔离是在"一套系统服务多个客户(租户)"的同时,保证 A 租户的数据/会话/权限**在逻辑与物理上都不可见于 B 租户**——它不是"多用户登录",而是"租户级的数据边界"。
> 2. **机制**:落地靠"身份贯穿 + 滤波贯穿"——每个请求都解析出租户(`thread_id = 租户+会话`),状态层按租户分上下文;检索层用向量库的元数据过滤(每个文档/块带 tenant 字段)只召回本租户内容;再叠加权限分级为租户内/跨租户的高危操作设闸。
> 3. **为什么重要**:这是企业级软件的商业前提(多租户才能规模化售卖给多客户),也是最容**易被忽略导致数据越权的重大事故点**;隔离不好,售后纠纷与合规处罚都来。
> 4. **易错点/常见误解**:最容易漏的是"只做了应用层隔离却漏了检索/缓存/后台导出的隔离",让 B 租户通过向量检索或工单后台看到 A 租户数据;另一个误区是"用 thread_id 隔离就够"——必须贯穿状态、检索、数据库查询、文件/后台全链路,处处带租户条件。
> ⏳ **短期可不深究**:K8s + HPA(水平自动扩缩容)这套容器编排的生产细节,第一遍知道"It 是用来在更大流量下弹性部署/扩容的手段"即可;当前用 Docker Compose 跑通单机部署已经够完成学习,K8s 等真到数十倍流量/多副本的规模再系统学,属于"按需进阶"的环节。
### 2. 必须落地的工程实践
- **评测闭环**:自建评测集 + Bad-case 队列 + 回归测试(改 prompt 重跑评测,对照阶段五评测 + 阶段七 Bad-case 闭环)。
- **优雅停机**:发布时在途请求不切断(对照阶段七调用优雅停机机制)。
- **满意度回流**:低分会话自动进 Bad-case 队列(写 Click 埋点,异步入队)。
- 文档交付与复盘:项目文档 + 每周末复盘。
> ⏳ **短期可不深究**:埋点上报的具体实现(事件打点字段怎么设计、ClickHouse 这类分析库的建表/聚合写法、异步入队用哪套 MQ)第一遍知道"要记录低分会话并回流"即可,等真正做用户行为分析平台再细化,属于数据/基础设施侧的可选加分项。
```python
def thread_key(tenant_id: str, session_id: str) -> str:
"""多租户 + 会话的状态签名: 每个租户每个会话独立上下文"""
return f"{tenant_id}:{session_id}"
```
### 3. 合规与审计(企业级必选项)
企业级与「能跑」的分水岭不是功能数量,而是合规能力——缺这一节,系统进不了企业采购清单。
**a) 审计日志**:所有敏感操作(查订单、创建工单、权限变更、转人工)统一记录四要素——**谁**(user_id)、**何时**(时间戳 + trace_id 串联完整链路)、**做了什么**(工具 + 参数)、**结果**(成功 / 失败 + 摘要)。审计日志落**独立只追加(append-only)存储**,不与业务日志混放(业务日志滚动清理,审计日志须可追溯数年)。
```python
import json, time
def audit_log(user_id, trace_id, action, params, ok, summary, sink) -> None:
"""敏感操作审计: 谁/何时/做了什么/结果 —— 独立 append-only 存储"""
sink.append(json.dumps({ # 生产: append-only 表/日志桶, 不给 UPDATE/DELETE 权限
"ts": round(time.time(), 3), "user_id": user_id, "trace_id": trace_id,
"action": action, "params": params, # 如 {"tool": "query_order", "order_id": "A1024"}
"result": "ok" if ok else "fail", "summary": summary[:100],
}, ensure_ascii=False))
# 查订单 / 建工单 / 权限变更 / 转人工 四类敏感操作出口统一调用
audit_log("u_1001", "tr_8f2a", "query_order", {"order_id": "A1024"},
ok=True, summary="返回脱敏后订单摘要", sink=audit_store)
```
**b) PII 与数据分级**:三级——**明文**(非敏感业务标识,如订单号)/ **掩码**(默认展示层,手机号 138****1234)/ **加密**(原文密文落库,授权后解密)。手机号默认掩码展示,**完整值仅授权角色可见**(客服主管,或用户本人核身通过后),对照阶段六客服的 PII 脱敏小节。
**c) 数据驻留与保留期限**:GDPR / PIPL 要求数据不出境 / 境内存储——选境内区域 + 自托管观测(LangFuse 而非境外 SaaS);用户有权请求数据删除(被遗忘权)。对话记录设保留期限(如 **180 天**)到期自动清理——定时任务同时清掉 PG 与向量库里的副本(对照阶段四:入库的 embedding 也是个人数据)。
> ⚠️ **合规是采购评审的否决项**:企业采购评审里安全与合规一票否决——功能再花哨,没有审计日志与数据分级直接出局。Level5 演示至少要落地**审计日志**这一项。
## 本节验收清单
- [ ] Docker Compose 一键部署整套环境并跑通
- [ ] 状态落库 + 中断恢复验证(重启进程任务不丢)
- [ ] 有多租户隔离与权限分级
- [ ] 敏感操作有独立审计日志(append-only,可用 trace_id 串起完整链路)
- [ ] 有完整链路日志 + 至少一项业务监控告警
- [ ] 有自建评测集并跑过一轮迭代闭环
## 排期与前置依赖
- **前置**:Level2(RAG)与 Level4(SQL 与数据)是能力底座;阶段七工程化是工程底座。
- **建议排期**:第 15-16 周,6-8 周(可与 Level4 收尾并行)。
- **毕业判定**:这份系统能独立部署、能告警自愈、能靠 Bad-case 闭环持续变好 > 功能堆得多。
## 阶段八整体补充建议
- Level 1-2 对应计划第 7-10 周(见 [四个月学习计划](../09-四个月学习计划.md))。
- Level 3-5 建议在掌握基础后串行攻坚,同一项目同时沉淀其 Bad-case 与评测脚本。
- 五个 Level 与前面阶段的能力对应:Level1→阶段二三、Level2→阶段四、Level3→阶段五、Level4→阶段六、Level5→阶段七。**每做一个 Level,就是一次对前面知识的大串讲**。
## 本节常见面试题(深度解析)
> 针对本节核心知识的面试高频点,配合"本质+机制"式理解,能让你答得既有深度又有广度。
### 面试题 1:多租户场景下,如何确保 A 租户的数据不会被 B 租户查到?你会在哪些层做隔离?
- **面试官想考察**:你是否把多租户当作"贯穿全链路的数据边界"来设计,而非只在登录层做个标识。
- **专业作答(含深度)**:
1. 先说本质:多租户 = 身份贯穿(每个请求解析出 tenant)+ 滤波贯穿(每一层查询都带 tenant 条件),目标是租户级不可越权。
2. 分四层展开:状态层(`thread_id = 租户+会话`,上下文按租户隔离);检索层(向量库元数据过滤,仅召回本租户文档块);数据库层(SQL 处处带租户条件 + 行级权限);后台/文件层(工单、导出、缓存不跨租户)。
3. 点出常见缺口:只做应用层而漏了检索/缓存/后台导出,是越权事故的高发点;隔离要"处处带租户条件",不是"在某一个面加一把锁"。
4. 补充测试意识:越权用例(用 B 租户身份访问 A 租户资源)应纳入验收清单。
- **加分亮点 / 深度追问**:可主动提"过滤的默认行为"——宁可查不到也不跨租户可查,检索兜底要做对;追问"多租户与多用户登录的关系"时可答"多用户是身份,多租户是数据边界,二者正交叠加"。
### 面试题 2:为什么敏感操作的审计日志必须用 append-only 存储,并用 trace_id 串起完整链路?
- **面试官想考察**:你是否理解审计日志与业务日志在"可信、可追溯"上的根本差异。
- **专业作答(含深度)**:
1. 审计日志要能回答"谁、何时、做了什么、结果如何",且**不可被事后篡改**——append-only(只追加、不给 UPDATE/DELETE 权限、物理上不滚动清理)才能保证证据可信,这是它与可清理的业务日志最本质的区别。
2. 什么时候记:只记敏感操作(查订单、建工单、权限变更、转人工)并记录"工具+参数+结果摘要",不过度记录以免噪声淹没关键链路。
3. trace_id 的作用:把一次用户请求跨多个服务/规约环节的日志串成一条完整链路,任何一环出问题都能端到端定位,配合只追加存储形成"完整、不可变"的证据链。
4. 合规加成:这直接对应 GDPP/PIPL 与采购评审对"可审计、可追责"的要求,是企业能进采购清单的前提。
- **加分亮点 / 深度追问**:可对比"审计日志(append-only、不可改)vs 业务日志(滚动清理、可变)"的取舍;追问"日志也含 PII 怎么办"时可答"敏感字段脱敏后入库 + 完整值仅授权角色可见"。
### 面试题 3:一个客服 Agent 上线后怎么保证它能"越用越好",而不是上线即封版?
- **面试官想考察**:你是否具备线上迭代闭环(Evaluate-Bad-case-回归)的工程思路,而不是只会交付功能。
- **专业作答(含深度)**:
1. 闭环起点:建一套自建评测集 + Bad-case 队列,把"答错的、发生率低的、新出现的反例"收集起来。
2. 迭代机制:每次改 prompt/检索/业务规则都重跑回归测试,量化评估"是否真的变好",用数据而非感觉决定是否上线。
3. 主动回流:满意度低分会话异步入队,形成"线上真实信号 → 修复 → 回归"的正向循环,让系统适配真实用户分布。
4. 兜底保障:发布走优雅停机(在途请求不切断),监控告警兜底,出事能发现、能回滚。
- **加分亮点 / 深度追问**:可把"评测集要防腐坏"(防"把评测集背进去反而过拟合")作为进阶点,或用"Bad-case 队列就是你的微调/提示优化燃料"来串联多级能力;追问"如何衡量变好"可答"用技能指标(准确率、分流成功率、转人工率下降)对齐业务目标"。