# 技术方案 - 快速回复规则后台管理 > **关联PRD**: `01-产品文档/00-产品规划/PRD-REQ-通用-002-快速回复规则后台管理-v1.2.md` > **版本**: v1.2 > **日期**: 2026-07-27(初版) / 2026-07-28(v1.2 调整) > **作者**: Simon --- ## 1. 技术架构设计 ### 1.1 整体架构 ``` ┌─────────────────────────────────────────────────────────────┐ │ ITAgent 管理后台 │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ /quick-rules /quick-rules/greeting │ │ │ │ /quick-rules/contacts /quick-rules/routing │ │ │ │ /quick-rules/targets │ │ │ └─────────────────────────────────────────────────────┘ │ └────────────────────────┬────────────────────────────────────┘ │ HTTP API ┌────────────────────────┴────────────────────────────────────┐ │ FastAPI 后端 │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ QuickRuleService (规则加载 + 缓存) │ │ │ │ - get_greeting_keywords() │ │ │ │ - get_contact_keywords() │ │ │ │ - get_routing_keywords() │ │ │ │ - get_routing_targets() │ │ │ └─────────────────────────────────────────────────────┘ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ QuickRuleCRUD API │ │ │ │ - /api/admin/quick-rules (CRUD) │ │ │ │ - /api/admin/quick-rules/refresh (热刷新) │ │ │ └─────────────────────────────────────────────────────┘ │ └────────────────────────┬────────────────────────────────────┘ │ ┌────────────────────────┴────────────────────────────────────┐ │ PostgreSQL 数据库 │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ quick_rules 表 │ │ │ │ - id / rule_type / category / keyword / ... │ │ │ └─────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────┘ ``` ### 1.2 模块设计 | 模块 | 职责 | 文件位置 | |------|------|---------| | `QuickRule` | 数据库模型 | `app/models/quick_rule.py` | | `quick_rules_api` | 管理API | `app/api/admin/quick_rules.py` | | `QuickRuleService` | 规则加载服务 | `app/services/quick_rule_service.py` | --- ## 2. 数据库设计 ### 2.1 quick_rules 表 ```sql CREATE TABLE quick_rules ( id SERIAL PRIMARY KEY, rule_type VARCHAR(50) NOT NULL, -- 枚举: greeting, routing_prefilter, routing_target category VARCHAR(50), -- 业务分类: IT服务, 行政, 人力资源, 财务, 法务, 行政-物业 keyword TEXT NOT NULL, -- 关键词内容 或 名称 priority INTEGER DEFAULT 0, -- 优先级,匹配时按优先级排序 response_template TEXT, -- 回复模板(可选) extra_data JSONB, -- 扩展字段(用于kfid等配置) is_active BOOLEAN DEFAULT TRUE, -- 是否启用 created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, CONSTRAINT uk_rule_type_keyword UNIQUE (rule_type, keyword) ); CREATE INDEX idx_quick_rules_type_active ON quick_rules(rule_type, is_active); CREATE INDEX idx_quick_rules_category ON quick_rules(category); ``` ### 2.2 初始数据 ```sql -- 打招呼关键词(从 ai_handler.py 迁移) INSERT INTO quick_rules (rule_type, keyword, priority, is_active) VALUES ('greeting', '你好', 10, true), ('greeting', '您好', 9, true), ('greeting', 'hi', 8, true), ('greeting', 'hello', 7, true), ('greeting', '在吗', 6, true), ('greeting', '在么', 5, true); -- 路由预过滤关键词(从 routing_service.py 迁移) INSERT INTO quick_rules (rule_type, category, keyword, priority, is_active) VALUES ('routing_prefilter', 'IT服务', '打印机', 10, true), ('routing_prefilter', 'IT服务', '打印', 9, true), ('routing_prefilter', 'IT服务', '电脑', 8, true), ('routing_prefilter', '行政', '复印机', 7, true), ('routing_prefilter', '人力资源', '考勤', 8, true), ('routing_prefilter', '人力资源', '入职', 7, true), ('routing_prefilter', '财务', '报销', 10, true), ('routing_prefilter', '财务', '发票', 9, true), ('routing_prefilter', '法务', '合同', 10, true); -- 路由目标配置 INSERT INTO quick_rules (rule_type, category, keyword, extra_data, is_active) VALUES ('routing_target', '行政', '机票酒店前台', '{"service_name": "机票酒店前台", "description": "受理机票、酒店、快递、访客等", "url": "https://work.weixin.qq.com/nl/innerkfid/ikfCtcYBwAAV00zNJGfmuA0aG1c2qCDnQ"}', true), ('routing_target', '人力资源', '人力资源共享服务咨询', '{"service_name": "人力资源共享服务咨询", "description": "工牌/考勤/入离职/社保", "url": "https://work.weixin.qq.com/nl/innerkfid/ikfCtcYBwAAvSRL5i5b_Xia8vCmFc2gRw"}', true); ``` --- ## 3. API 设计 ### 3.1 管理接口 | 接口 | 方法 | 说明 | |------|------|------| | `/api/admin/quick-rules` | GET | 列表查询(支持 rule_type、category、keyword 筛选) | | `/api/admin/quick-rules` | POST | 创建规则 | | `/api/admin/quick-rules/{id}` | PUT | 更新规则 | | `/api/admin/quick-rules/{id}` | DELETE | 删除规则 | | `/api/admin/quick-rules/batch` | POST | 批量导入 | | `/api/admin/quick-rules/refresh` | POST | 热刷新缓存 | | `/api/admin/quick-rules/stats` | GET | 统计各类型规则数量 | ### 3.2 请求/响应示例 **GET /api/admin/quick-rules?rule_type=greeting&page=1&size=20** ```json { "total": 6, "page": 1, "size": 20, "items": [ { "id": 1, "rule_type": "greeting", "keyword": "你好", "priority": 10, "is_active": true, "created_at": "2026-07-27T10:00:00Z", "updated_at": "2026-07-27T10:00:00Z" } ] } ``` **POST /api/admin/quick-rules** ```json { "rule_type": "routing_prefilter", "category": "IT服务", "keyword": "投影仪", "priority": 5, "is_active": true } ``` --- ## 4. 服务设计 ### 4.1 QuickRuleService ```python class QuickRuleService: """规则加载服务 - 单例模式""" _cache: dict = {} @classmethod async def load_all(cls) -> None: """启动时加载所有规则到缓存""" rules = await db.query(QuickRule).where(QuickRule.is_active == True).all() cls._cache = { 'greeting': [r.keyword for r in rules if r.rule_type == 'greeting'], 'contact': [r.keyword for r in rules if r.rule_type == 'contact'], 'routing_prefilter': {r.keyword: r.category for r in rules if r.rule_type == 'routing_prefilter'}, 'routing_target': {r.category: r.extra_data for r in rules if r.rule_type == 'routing_target'}, } @classmethod async def refresh(cls) -> None: """热刷新缓存""" await cls.load_all() @classmethod def get_greeting_keywords(cls) -> list[str]: """获取打招呼关键词列表""" return cls._cache.get('greeting', []) @classmethod def get_contact_keywords(cls) -> list[str]: """获取联系人关键词列表""" return cls._cache.get('contact', []) @classmethod def get_routing_keywords(cls) -> dict[str, str]: """获取路由预过滤关键词 {keyword: category}""" return cls._cache.get('routing_prefilter', {}) @classmethod def get_routing_targets(cls) -> dict[str, dict]: """获取路由目标 {category: {service_name, description, url}}""" return cls._cache.get('routing_target', {}) ``` --- ## 5. 代码改造计划 ### 5.1 新增文件 | 文件 | 说明 | |------|------| | `app/models/quick_rule.py` | QuickRule SQLAlchemy 模型 | | `app/api/admin/quick_rules.py` | CRUD API | | `app/services/quick_rule_service.py` | 规则加载服务 | | `migrations/versions/xxx_quick_rules.py` | Alembic 迁移脚本 | ### 5.2 改造文件 | 文件 | 改造内容 | |------|---------| | `app/services/ai_handler.py` | 从 QuickRuleService 加载打招呼关键词 | | `app/api/contacts.py` | 从 QuickRuleService 加载联系人配置 | | `app/services/routing_service.py` | 从 QuickRuleService 加载路由配置 | ### 5.3 改造示例 **改造前 (ai_handler.py)**: ```python _GREETING_KEYWORDS = ["你好", "您好", "hi", "hello", "在吗", "在么"] def check_greeting(text: str) -> bool: return any(kw in text for kw in _GREETING_KEYWORDS) ``` **改造后 (ai_handler.py)**: ```python from app.services.quick_rule_service import QuickRuleService def check_greeting(text: str) -> bool: keywords = QuickRuleService.get_greeting_keywords() return any(kw in text for kw in keywords) ``` --- ## 6. 前端实现 ### 6.1 路由配置 ```typescript // router/index.ts { path: '/quick-rules', component: Layout, children: [ { path: '', component: () => import('@/views/quick-rules/index.vue') }, { path: 'greeting', component: () => import('@/views/quick-rules/greeting.vue') }, { path: 'contacts', component: () => import('@/views/quick-rules/contacts.vue') }, { path: 'routing', component: () => import('@/views/quick-rules/routing.vue') }, { path: 'targets', component: () => import('@/views/quick-rules/targets.vue') }, ] } ``` ### 6.2 页面结构 | 页面 | 组件 | |------|------| | `quick-rules/index.vue` | 规则管理主页(标签导航 + count 徽标 + 筛选区 + 规则表格) | | `quick-rules/greeting.vue` | 打招呼关键词管理 | | `quick-rules/contacts.vue` | 业务联系人管理 | | `quick-rules/routing.vue` | 路由关键词管理 | | `quick-rules/targets.vue` | 路由目标配置 | ### 6.3 v1.2 UI 调整 移除 `src/frontend-admin/src/views/quick-rules/index.vue` 顶部 `.stats-row` 三张统计卡片;标签导航 `.tab-bar` 保留 `count` 徽标,作为规则数量的唯一页面展示来源。卡片原有点击行为仅调用 `switchTab`,标签导航已完整承担相同切换能力,因此删除不影响路由切换、筛选、批量删除、编辑、启停、分页和搜索。后端 `getQuickRuleStats` 接口保留;`quick-rules/audit.vue` 的 4 张审计统计卡片不在本次调整范围。 --- ## 7. 部署与运维 ### 7.1 部署顺序 1. 执行数据库迁移脚本(创建 quick_rules 表 + 初始数据) 2. 部署后端代码 3. 部署前端代码 4. 验证功能 ### 7.2 监控指标 | 指标 | 说明 | |------|------| | `quick_rules_query_duration` | 规则查询耗时 | | `quick_rules_cache_hit_rate` | 缓存命中率 | | `quick_rules_api_requests` | 管理API请求数 | ### 7.3 回滚方案 - 数据库:保留迁移脚本,可降级表 - 代码:旧页面保留,新页面上线后观察一周再下线旧页面 --- ## 8. 验收检查点 | 检查点 | 验证方式 | |--------|---------| | 数据库迁移成功 | 确认 quick_rules 表存在且数据正确 | | API 可用 | curl 测试 CRUD 接口 | | 规则加载正确 | 调用服务方法验证返回值 | | 前端页面可访问 | 浏览器访问 /quick-rules | | 现有功能无影响 | 发送消息验证打招呼/路由仍正常工作 | | 热刷新生效 | 修改规则后无需重启即可生效 | --- ## 9. v2.0 增量设计 — 智能体自动优化 + 导入导出 ### 9.1 新增 API 端点 | 接口 | 方法 | 说明 | |------|------|------| | `/api/admin/quick-rules/import` | POST | 批量导入(JSON/Excel) | | `/api/admin/quick-rules/export` | GET | 批量导出(JSON/Excel) | | `/api/admin/quick-rules/batch-delete` | POST | 批量删除(按ID列表) | | `/api/admin/quick-rules/agent-update` | POST | 智能体专用更新(带置信度) | | `/api/admin/quick-rules/audit-log` | GET | 规则修改审计日志 | | `/api/admin/quick-rules/stats` | GET | 规则统计(命中率、误判率) | ### 9.2 智能体专用更新请求 ```json POST /api/admin/quick-rules/agent-update { "rule_type": "routing_prefilter", "category": "IT服务", "keyword": "投影仪", "priority": 5, "confidence": 0.92, "reason": "误判率分析:最近30天5条'投影仪'相关消息被误判为闲聊", "agent_id": "rule_optimizer_v1", "execution_id": "exec_2026-07-27_001" } ``` **置信度阈值**: - ≥ 0.85:自动应用并记录审计 - 0.5 ~ 0.85:进入待审核队列 - < 0.5:拒绝(不入库) ### 9.3 批量导入导出 **导入格式(JSON)**: ```json { "rules": [ { "rule_type": "greeting", "keyword": "你好", "priority": 10, "is_active": true } ], "mode": "skip_duplicates" // skip_duplicates | overwrite | fail } ``` **导出格式**:支持 JSON 和 Excel 两种格式 ### 9.4 审计日志表 ```sql CREATE TABLE quick_rule_audit_log ( id SERIAL PRIMARY KEY, rule_id INTEGER, rule_type VARCHAR(50), action VARCHAR(20), -- create/update/delete/batch actor_type VARCHAR(20), -- human/agent actor_id VARCHAR(100), -- agent_id 或 坐席ID old_value JSONB, new_value JSONB, confidence FLOAT, reason TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); ``` ### 9.5 规则统计 ```python GET /api/admin/quick-rules/stats { "total_rules": 45, "hit_rate": 0.78, "false_positive_rate": 0.05, "active_rules": 42, "by_type": { "greeting": 6, "routing_prefilter": 25, "routing_target": 14 }, "top_unkonwn_keywords": ["云盘权限", "VPN", "VPN登录"] } ``` ### 9.6 实施步骤 | 步骤 | 内容 | 预估时间 | |------|------|---------| | 1 | 批量导入/导出 API | 1h | | 2 | 批量删除 API | 0.5h | | 3 | 智能体专用 API(带置信度) | 1.5h | | 4 | 审计日志表 + 记录逻辑 | 1.5h | | 5 | 规则统计 API | 1h | | 6 | 前端导入/导出按钮 | 1h | | 7 | 智能体调用脚本示例 | 0.5h | | **总计** | | **7h** | --- ## 10. 变更记录 | 日期 | 版本 | 变更内容 | 变更人 | 变更原因 | 影响范围 | |------|------|---------|-------|----------|----------| | 2026-07-27 | v1.0 | 初始版本 | Simon | 快速回复规则后台管理技术设计建立 | 后端、数据库及管理后台 | | 2026-07-27 | v1.1 | 新增第9章 v2.0 增量设计(智能体自动优化 + 导入导出) | Simon | 补充智能体扩展设计 | API、审计及导入导出 | | 2026-07-28 | v1.2 | 移除 `index.vue` 顶部 `.stats-row` 三张重复统计卡片,保留 `.tab-bar` 的 count 徽标;统计接口与审计页卡片保持不变 | Simon | 页面信息冗余 | 管理后台 `/quick-rules` 页面 |