民情诉求智能分析与智能派单系统(AI + 社会治理)· 双引擎语义分析 + 智能派单 + 工单状态机 + SLA 监管
版本 1.0.2 · 2026-08-21 · 作者 yangxuan
居民通过多渠道(居民上报 / 12345转办 / 网格巡查 / 线上留言)提交诉求,系统提交即分析: 自动完成 多标签分类 · 情感倾向(1-5) · 紧急度(1-3) · 关键信息抽取 · 摘要生成, 随后智能派单至责任部门,工单沿状态机流转直至办结,全程 SLA 时限监管。
与传统人工分派工单系统的本质差别是语义理解代替人工判断,核心证据见下一节的复合诉求对照。
复合诉求:“楼下烧烤店每天晚上油烟很大,我家孩子一直咳嗽”
| 引擎 | 分析结果 | 派单结果 |
|---|---|---|
| 规则引擎(离线兜底) | 只命中“烧烤/油烟”字面关键词 → 单标签 ['环境卫生'] |
仅派综合执法局 |
| 远程 LLM | 推理“孩子咳嗽”是油烟引发的隐含健康风险 → 复合标签
['环境卫生','民生保障'] |
主派综合执法局 + 抄送民政局,情感 2 分进入风险预警 |
关键词规则永远无法从“孩子咳嗽”推出“民生保障”——只有大模型的语义推理做得到。
该案例已内置为工作台一键填充示例与测试锚点
(test_composite_appeal_offline_full_flow),离线走规则引擎全流程可用,
配置 Key 后即可现场对照 LLM 的复合标签效果。
┌──────────────────────────────────────────────────────────────────┐
│ 前端 原生 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 两库通用。
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)、正则抽取地点/时间/人物、模板摘要。 两引擎返回同构结果,前端展示与落库字段完全一致。
| 分类 | 主责部门 | 分类 | 主责部门 |
|---|---|---|---|
| 环境卫生 | 综合执法局 | 物业管理 | 住建局 |
| 违章建筑 | 综合执法局 | 民生保障 | 民政局 |
| 噪音扰民 | 公安分局 | 邻里纠纷 | 街道办事处 |
| 公共设施 | 住建局 | 交通安全 | 交警大队 |
| 其他 | 12345热线中心(兜底) | ||
多标签规则:首个分类定主责,其余分类对应部门去重后抄送;派单支持人工纠偏指定部门;
工单号 WO-YYYYMMDD-XXXX 按日自增。
| 紧急度 | 判定 | 时限 |
|---|---|---|
| 3 紧急 | 煤气/燃气/泄漏/漏水/倒塌/伤人/火灾/爆炸/触电/坠物/危墙/被困/中毒 | 4 小时 |
| 2 一般 | 反复反映(多次/一直/天天…)或程度词(严重/很大/危险…) | 24 小时 |
| 1 较低 | 一般咨询类 | 72 小时 |
时限自建单起算;看板剩余 <4h 黄色预警、超时红色告警;办结按 completed_at 与 sla_deadline 比较记按时/超时。三档时限均可用环境变量覆盖。
pending(待派单) ──dispatch──▶ dispatched(已派单) ──accept──▶ accepted(已接单)
│ │
reject complete
▼ ▼
rejected(已拒单) completed(已完成)
│
resolve
▼
resolved(已办结)
BusinessError → 统一 400 {code,message};| 方法 | 路径 | 说明 |
|---|---|---|
| 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)。
| 表 | 关键字段 |
|---|---|
| appeals | content · source · status · categories(JSON 多标签) · key_info(JSON) · sentiment · urgency · summary · analysis_source · tokens_used(累计) · analysis_history(JSON 历史快照) · analyzed_at |
| work_orders | order_no(唯一) · appeal_id · department · cc_departments(JSON) · status · sla_deadline · handler · result_note · 四个流转时间戳 |
| departments | name · categories(JSON) · phone(启动幂等预置 7 部门) |
| daily_stats | stat_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。
测试(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 切换。
| 版本 | 日期 | 要点 |
|---|---|---|
| 1.0.0 | 2026-08-21 | 首版:双引擎分析/9类多标签/智能派单/SLA/五态状态机/批量并发/治理看板/XSS加固;92 用例 |
| 1.0.1 | 2026-08-21 | Token 管控(省流模式/usage 捕获/看板卡片)、旧库自动迁移、诉求重分析(历史版本保留/已派单重派)、 双 CSV 导出(UTF-8-BOM)、SLA 临期提醒(剩余 ≤25%);测试 92→122 |
| 1.0.2 | 2026-08-21 | 决赛收尾打磨:深色模式(CSS 变量主题化/切换/记忆/跟随系统/防闪白)、移动端 375px 适配 (窄屏导航/筛选换行/表格滚动)、筛选状态记忆、看板状态色微调、空状态语气统一;stats 无 N+1 确认 + SQL 条数护栏、热路径计时日志、性能基准护栏(规则分析 <10ms/聚合 <100ms)、 修复两处真实并发缺陷(SQLite 单连接互锁→QueuePool;工单号取号竞态→锁原子化+重试)、 10 线程并发零串扰验证;文档终版;测试 122→137 |