🏛️ 民情直通车2 · 项目流程文档

民情诉求智能分析与智能派单系统(AI + 社会治理)· 双引擎语义分析 + 智能派单 + 工单状态机 + SLA 监管

版本 1.0.2 · 2026-08-21 · 作者 yangxuan

npm: baisitong2PyPI: baisitong2 测试 137/137 全绿零配置可离线运行 深色模式 · 移动适配 · 10 并发验证 Token 管控 · 重分析 · CSV 导出 · SLA 临期
9 类固定分类体系 → 7 个责任部门职责矩阵
双引擎远程 LLM ↔ 内置规则引擎,失败自动降级
5 态工单状态机 + 拒单回退 + 诉求联动
4/24/72h按紧急度分级的 SLA 办结时限
~4300 行后端 2310 + 前端 2035(wc 实测),零框架零构建
137 测试76 单元 + 46 集成 + 15 打磨,全程离线全绿
<10ms单条规则分析实测 ~0.01ms(护栏断言锁定)
10 并发提交+分析+派单零串扰,全链实测 ~61ms

1 · 项目概览

居民通过多渠道(居民上报 / 12345转办 / 网格巡查 / 线上留言)提交诉求,系统提交即分析: 自动完成 多标签分类 · 情感倾向(1-5) · 紧急度(1-3) · 关键信息抽取 · 摘要生成, 随后智能派单至责任部门,工单沿状态机流转直至办结,全程 SLA 时限监管。

与传统人工分派工单系统的本质差别是语义理解代替人工判断,核心证据见下一节的复合诉求对照。

2 · 核心演示论点:AI 是解决问题的关键要素

复合诉求:“楼下烧烤店每天晚上油烟很大,我家孩子一直咳嗽”

引擎分析结果派单结果
规则引擎(离线兜底) 只命中“烧烤/油烟”字面关键词 → 单标签 ['环境卫生'] 仅派综合执法局
远程 LLM 推理“孩子咳嗽”是油烟引发的隐含健康风险 → 复合标签 ['环境卫生','民生保障'] 主派综合执法局 + 抄送民政局,情感 2 分进入风险预警

关键词规则永远无法从“孩子咳嗽”推出“民生保障”——只有大模型的语义推理做得到。 该案例已内置为工作台一键填充示例与测试锚点 (test_composite_appeal_offline_full_flow),离线走规则引擎全流程可用, 配置 Key 后即可现场对照 LLM 的复合标签效果。

3 · 系统架构与分层

┌──────────────────────────────────────────────────────────────────┐
│            前端 原生 HTML/CSS/JS(无框架、无构建)                  │
│  诉求工作台(提交+AI分析卡) · 诉求列表(筛选/派单)               │
│  工单看板(状态分列+SLA倒计时+流转) · 统计看板(趋势/风险)      │
└───────────────────────────┬──────────────────────────────────────┘
                            │ HTTP JSON(统一 {code, message, data})
┌───────────────────────────▼──────────────────────────────────────┐
│  接口层 routers/   appeals · workorders · stats · health          │
├──────────────────────────────────────────────────────────────────┤
│  逻辑层 services/                                                │
│    analyzer.py      双引擎:RemoteAnalyzer ↔ RuleAnalyzer         │
│    dispatcher.py    职责矩阵 + SLA 计算 + 工单号生成              │
│    state_machine.py 流转校验 + 时间戳 + 诉求联动                  │
│    stats.py         DailyStat 聚合 + 看板组装                     │
├──────────────────────────────────────────────────────────────────┤
│  数据层 models/ + database.py  SQLAlchemy ORM                     │
│    Appeal · WorkOrder · Department · DailyStat                    │
│    → SQLite(默认,零配置) / MySQL 8(DATABASE_URL 切换)        │
└──────────────────────────────────────────────────────────────────┘

分层纪律:接口层薄(校验 + 编排),逻辑层厚(业务规则全部可单测), 数据层与数据库解耦 —— 无 SQLite 专属语法,JSON 列以非 ASCII 序列化存储, 保证中文标签的 LIKE 筛选在 SQLite / MySQL 两库通用。

4 · 双引擎分析管线

诉求原文居民口语化描述,来源四渠道
引擎选择配置 LLM Key → 远程;否则/失败 → 规则引擎
LLM 分析Function-Calling 强约束 JSON,15s 超时可调
归一化非法分类剔除 / 数值收敛 / 摘要兜底
落库标记analysis_source = llm | rule_fallback

RemoteAnalyzer:OpenAI 兼容 /chat/completions 非流式调用, system prompt 定义“民情诉求分析专家”并要求推理隐含问题;通过 tool submit_appeal_analysis 的 JSON Schema 强约束返回结构 (分类枚举 / key_info / 情感 / 紧急度 / 摘要);优先解析 tool_calls.arguments,兼容模型直接把 JSON 写进 content(自动剥 ``` 围栏)。

降级链路:超时 / 5xx / 脏 JSON / 空参数 → 一律捕获并降级 RuleAnalyzer ——9 类关键词表多标签分类、正负情感词典(基准 3 分收敛 1-5)、紧急度规则 (安全词→3,反复/程度词→2)、正则抽取地点/时间/人物、模板摘要。 两引擎返回同构结果,前端展示与落库字段完全一致。

5 · 智能派单 · SLA · 状态机

5.1 职责矩阵

分类主责部门分类主责部门
环境卫生综合执法局物业管理住建局
违章建筑综合执法局民生保障民政局
噪音扰民公安分局邻里纠纷街道办事处
公共设施住建局交通安全交警大队
其他12345热线中心(兜底)

多标签规则:首个分类定主责,其余分类对应部门去重后抄送;派单支持人工纠偏指定部门; 工单号 WO-YYYYMMDD-XXXX 按日自增。

5.2 SLA 时限

紧急度判定时限
3 紧急煤气/燃气/泄漏/漏水/倒塌/伤人/火灾/爆炸/触电/坠物/危墙/被困/中毒4 小时
2 一般反复反映(多次/一直/天天…)或程度词(严重/很大/危险…)24 小时
1 较低一般咨询类72 小时

时限自建单起算;看板剩余 <4h 黄色预警、超时红色告警;办结按 completed_at 与 sla_deadline 比较记按时/超时。三档时限均可用环境变量覆盖。

5.3 工单状态机

pending(待派单) ──dispatch──▶ dispatched(已派单) ──accept──▶ accepted(已接单)
                                    │                            │
                                  reject                      complete
                                    ▼                            ▼
                             rejected(已拒单)              completed(已完成)
                                                                 │
                                                              resolve
                                                                 ▼
                                                          resolved(已办结)

6 · API 一览

方法路径说明
POST/api/appeals提交诉求,立即分析,返回完整结果
POST/api/appeals/batch批量分析(并发受 BATCH_CONCURRENCY 管控,逐条降级绝不整体失败)
GET/api/appeals分页 + category/status/source/urgency/sentiment(_lte)/q 筛选
GET/api/appeals/export诉求 CSV 导出(筛选同列表口径,UTF-8-BOM 流式)
GET/api/appeals/{id}诉求详情(含关联工单/分析历史/Token 消耗)
POST/api/appeals/{id}/dispatch智能派单(可选人工指定部门)
POST/api/appeals/{id}/reanalyze重新分析(可 force_rule=true 强制规则引擎;结果变化保留历史)
GET/api/appeals/departments分类职责矩阵
GET/api/workorders工单列表(status/department/q)
GET/api/workorders/export工单 CSV 导出(status/department 筛选,UTF-8-BOM 流式)
GET/api/workorders/{id}工单详情(诉求摘要 + 时间线)
POST/api/workorders/{id}/transition状态机流转 {action, note, handler}
GET/api/stats治理看板:总览/分类分布/近7日趋势/部门时效/风险预警/SLA(含 sla_ending 临期)/Token
GET/api/health健康检查(运行模式 / SLA / Token 管控配置)

统一响应 {code, message?, data};异常兜底链:BusinessError(400/404)→ HTTPException → RequestValidationError(422,首条可读信息)→ Exception(500)。

7 · 数据模型与统计口径

关键字段
appealscontent · source · status · categories(JSON 多标签) · key_info(JSON) · sentiment · urgency · summary · analysis_source · tokens_used(累计) · analysis_history(JSON 历史快照) · analyzed_at
work_ordersorder_no(唯一) · appeal_id · department · cc_departments(JSON) · status · sla_deadline · handler · result_note · 四个流转时间戳
departmentsname · categories(JSON) · phone(启动幂等预置 7 部门)
daily_statsstat_date(唯一) · new_appeals · analyzed_appeals · avg_sentiment · new_orders · categories_json · order_status_json · on_time/overdue_count · tokens_used

口径:新增按 created_at 自然日(本地时间,与 SLA 同口径);分类分布只统计已分析诉求(多标签拆计); 部门平均时效 = completed_at − dispatched_at 平均小时数;风险预警 = 情感 ≤2 且未办结; SLA 临期 = 在办且剩余 ≤ 总时长 25%(恰好 25% 计入);Token = 当日完成分析诉求累计消耗 (远程取 API usage,本地 1.6字/token 折算)。v1.0.0 旧库启动时自动补列,零手工 DDL。

8 · 测试与部署

测试(137 用例 = 76 单元 + 46 集成 + 15 打磨,全程离线):规则引擎复合案例/情感边界/紧急度安全词全覆盖、 LLM 假 httpx 响应(正常/超时/5xx/脏 JSON/多余字段/缺字段)、职责匹配、SLA 三档与超时口径、工单号、 状态机合法/非法流转(终态冻结/重复接单/拒单重派)、复合诉求离线全闭环、批量降级、 组合筛选/分页边界、统计口径、health,以及 XSS 防御三件套(载荷 JSON 原样往返、 esc() 引号转义契约、用户字段拼接静态扫描 + JS 语法回归); v1.0.1 新增 Token 管控(折算口径/省流 Prompt 与请求体断言/usage 捕获)、补列迁移重分析(历史保留/强制规则/已派单重派)、CSV 导出(BOM/行数与筛选一致)、 SLA 临期四边界(恰好 25% 计入、33%/超时/已完成排除)与看板 Token 字段; v1.0.2 新增 深色模式静态契约(变量整组覆盖/徽章零硬编码/四页切换与防闪白脚本/node 行为矩阵)、 移动端断点筛选记忆10 线程并发零串扰性能基准护栏 (规则分析 <10ms 实测 ~0.01ms;stats 聚合 <100ms 实测 ~3.9ms)与 stats SQL 条数护栏(≤8,实测 6)。 tests/conftest.py 设临时 SQLite 并弹出 LLM_API_KEY,强制规则引擎零网络依赖。

部署:npx baisitong2 / pip install baisitong2 / ./startup.sh;默认端口 8081(与“社区百事通”8080 错开,可同机联合演示); 默认 SQLite,MySQL 8 用 sql/init.sql + DATABASE_URL 切换。

9 · 决赛演示路径

离线可靠性/api/health 展示规则引擎模式,拔网线全流程可用
提交即分析普通诉求一表提交 → 分析卡即刻输出,一键派单生成 SLA 工单
核心对照(重点)烧烤店复合诉求:规则单标签 vs LLM 复合标签 + 抄送民政局,一分钟现场对照
紧急通道煤气泄漏诉求 → 紧急度3 → SLA 4h 红色倒计时
状态机严谨跨级流转 400 拒绝;拒单自动回退可重派
批量降级批量提交混合诉求,fallback_count 透明可观测
Token 管控今日/累计 Token 卡片实时增长,省流模式 600 token/条预算
治理价值分类分布/SLA 临期/风险预警/部门时效一屏总览,CSV 一键导出
体验与性能深色模式一键切换 + 375px 移动适配;137 测试全绿,10 并发隔离现场可跑

10 · 版本迭代记录

版本日期要点
1.0.02026-08-21 首版:双引擎分析/9类多标签/智能派单/SLA/五态状态机/批量并发/治理看板/XSS加固;92 用例
1.0.12026-08-21 Token 管控(省流模式/usage 捕获/看板卡片)、旧库自动迁移、诉求重分析(历史版本保留/已派单重派)、 双 CSV 导出(UTF-8-BOM)、SLA 临期提醒(剩余 ≤25%);测试 92→122
1.0.22026-08-21 决赛收尾打磨:深色模式(CSS 变量主题化/切换/记忆/跟随系统/防闪白)、移动端 375px 适配 (窄屏导航/筛选换行/表格滚动)、筛选状态记忆、看板状态色微调、空状态语气统一;stats 无 N+1 确认 + SQL 条数护栏、热路径计时日志、性能基准护栏(规则分析 <10ms/聚合 <100ms)、 修复两处真实并发缺陷(SQLite 单连接互锁→QueuePool;工单号取号竞态→锁原子化+重试)、 10 线程并发零串扰验证;文档终版;测试 122→137