🏛️ 民情直通车2(baisitong2)
民情诉求智能分析与智能派单系统 · AI + 社会治理 双引擎语义分析 + 分类职责矩阵派单 + 工单状态机 + SLA 时限监管,零配置、可离线运行
🎯 为什么 AI 是本系统的关键要素(核心演示论点)
以一条真实风格的复合诉求为例:
"楼下烧烤店每天晚上油烟很大,我家孩子一直咳嗽"
| 引擎 | 分析结果 | 派单结果 |
|---|---|---|
| 规则引擎(离线兜底) | 只能命中"烧烤/油烟"字面关键词 → 单标签 ['环境卫生'] |
仅派综合执法局 |
| 远程 LLM(智能分析) | 推理出"孩子一直咳嗽"是油烟引发的隐含健康风险 → 复合标签 ['环境卫生', '民生保障'] |
主派综合执法局 + 抄送民政局,儿童健康问题不再漏管 |
关键词规则永远无法从"孩子咳嗽"推出"民生保障"——这只有大模型的语义推理做得到。 同时,健康受害的隐含情绪、长期反映的焦灼感,LLM 也能给出更真实的情感分(2 分 vs 规则引擎的 3 分中性), 让风险预警列表第一时间捕捉到这条诉求。这就是"AI 是解决问题的关键要素"的直接证据。
该案例已内置为工作台"一键填充"示例与测试锚点(
tests/test_api.py::test_composite_appeal_offline_full_flow), 离线(无 Key)环境下走规则引擎全流程可用,配置 Key 后即可演示 LLM 复合标签的对照效果。
一分钟跑起来
方式 1:npm(任何装了 Python 3.9+ 的电脑)
npx baisitong2 # 自动建 venv、装依赖、启动,打开 http://localhost:8081
npx baisitong2 --port 9000 # 自定义端口
方式 2:pip 安装
pip install baisitong2 -i https://mirrors.aliyun.com/pypi/simple/
baisitong2 # 或 python -m baisitong2
方式 3:源码运行
./startup.sh # Linux / macOS(Windows 用 startup.bat)
# 或手动:
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
python -m baisitong2 --port 8081
零配置即用:默认 SQLite + 内置规则分析引擎(关键词多标签分类 + 情感词典 + 紧急度规则), 无需数据库、无需 API Key、无需联网。配置大模型 Key 后自动切换真模型,见配置。
功能特性
| 模块 | 说明 |
|---|---|
| 🤖 双引擎语义分析 | 远程 LLM(OpenAI 兼容 + Function-Calling 强约束 JSON)↔ 内置规则引擎;超时(15s 可调)/5xx/脏 JSON 自动降级,analysis_source 标记来源 |
| 🏷️ 多标签分类 | 固定 9 类体系(环境卫生/噪音扰民/违章建筑/公共设施/物业管理/民生保障/邻里纠纷/交通安全/其他),复合诉求一次打多标 |
| 💗 情感 + 紧急度 | 情感 1-5 五档(风险预警口径 ≤2)、紧急度 1-3(煤气/漏水/倒塌/伤人等安全词 → 3 级) |
| 📨 智能派单 | 分类 → 职责矩阵自动匹配主责部门;多标签诉求其余部门自动抄送;支持人工纠偏指定部门 |
| ⏱️ SLA 时限监管 | 紧急 4h / 一般 24h / 低 72h(环境变量可调),看板临期黄色预警、超时红色告警 |
| 🔁 工单状态机 | 待派单→已派单→已接单→已完成→已办结主线 + 拒单回退;非法流转直接 400,全程时间戳落档 |
| 📦 批量分析 | 并发受 BATCH_CONCURRENCY 管控(Token 管控),单条失败逐条降级,绝不整体失败 |
| 📊 治理看板 | 分类分布、近 7 日趋势、部门工单量与平均办结时效、情感风险预警、SLA 按时率 |
| 🖥️ 原生前端 | 纯 HTML/CSS/JS 零构建:工作台(示例一键填充)、诉求列表(多维筛选)、工单看板(SLA 倒计时)、统计看板 |
系统架构
┌──────────────────────────────────────────────────────────────────┐
│ 前端 原生 HTML/CSS/JS(无框架、无构建) │
│ 诉求工作台(提交+AI分析卡) · 诉求列表(筛选/派单) │
│ 工单看板(状态分列+SLA倒计时+流转) · 统计看板(趋势/风险) │
└───────────────────────────┬──────────────────────────────────────┘
│ HTTP JSON
┌───────────────────────────▼──────────────────────────────────────┐
│ 接口层 routers/ │
│ appeals(提交/批量/筛选/派单) · workorders(列表/流转) │
│ stats(看板) · health(健康检查) ← 统一 {code,message} 异常兜底 │
├──────────────────────────────────────────────────────────────────┤
│ 逻辑层 services/ │
│ analyzer 双引擎:RemoteAnalyzer(Function-Calling JSON) │
│ ↔ RuleAnalyzer(关键词+情感词典+紧急度规则) │
│ dispatcher 职责矩阵匹配(主责+抄送) · SLA 计算 · 工单号生成 │
│ state_machine 状态流转校验 + 时间戳 + 诉求状态联动 │
│ stats 每日聚合(DailyStat)+ 看板组装 │
├──────────────────────────────────────────────────────────────────┤
│ 数据层 models/ + database.py │
│ Appeal(诉求+分析JSON) · WorkOrder(状态机+SLA) │
│ Department(职责矩阵) · DailyStat(按日聚合) │
│ SQLAlchemy ORM → SQLite(默认) / MySQL 8(可切换) │
└──────────────────────────────────────────────────────────────────┘
│ │
GLM / DeepSeek API 内置规则引擎(离线兜底)
(配置 Key 后启用) 关键词分类 + 词典打分 + 模板摘要
AI 双引擎设计:analyze_appeal() 统一编排——优先远程 LLM
(Function-Calling 强约束返回 {categories, key_info, sentiment, urgency, summary} 严格 JSON),
超时 / 5xx / JSON 解析失败自动降级内置规则引擎,保证演示永不中断,
analysis_source 字段(llm / rule_fallback)全程标记数据来自哪个引擎。
派单管线:多标签分类 → 职责矩阵匹配(首分类定主责,其余部门抄送) → SLA 时限(紧急4h/一般24h/低72h) → 工单号 WO-YYYYMMDD-XXXX → 状态机流转 → 看板监管
状态机
诉 求: pending → analyzing → analyzed → dispatched → resolved
▲ (工单办结联动)
└── 拒单回退(可重新派单)
工 单: pending → dispatched → accepted → completed → resolved
└── dispatch ──┴── reject → rejected(终态)
动作:dispatch(派单) accept(接单) reject(拒单) complete(办结反馈) resolve(确认办结)
非法流转(跨级/终态再动)→ BusinessError → 400 {code, message}
API 一览
| 方法 | 路径 | 说明 |
|---|---|---|
| POST | /api/appeals |
提交诉求,立即分析,返回完整结果(多标签/情感/紧急度/摘要/来源) |
| POST | /api/appeals/batch |
批量分析(并发管控,逐条降级,绝不整体失败) |
| GET | /api/appeals |
列表:分页 + category/status/source/urgency/sentiment(_lte) 筛选 + q 关键词 |
| GET | /api/appeals/{id} |
诉求详情(含关联工单) |
| POST | /api/appeals/{id}/dispatch |
智能派单(body 可选 department 人工纠偏) |
| GET | /api/appeals/departments |
分类职责矩阵 |
| GET | /api/workorders |
工单列表:status/department 筛选 + q 工单号搜索 |
| GET | /api/workorders/{id} |
工单详情(含诉求摘要与时间线) |
| POST | /api/workorders/{id}/transition |
状态机流转 {action, note?, handler?} |
| GET | /api/stats |
看板:总览/分类分布/近7日趋势/部门时效/风险预警/SLA |
| GET | /api/health |
健康检查(运行模式/SLA 配置) |
配置
复制 .env.example 为 .env,全部留空即本地模式:
# LLM(OpenAI 兼容协议,留空 = 内置规则引擎)
LLM_API_KEY=sk-xxx
LLM_BASE_URL=https://open.bigmodel.cn/api/paas/v4 # 或 https://api.deepseek.com/v1
LLM_MODEL=glm-4-flash # 或 deepseek-chat
ANALYSIS_TIMEOUT=15 # 单条分析超时(秒),超时自动降级
BATCH_CONCURRENCY=2 # 批量分析并发上限(Token 管控)
SLA_HOURS_URGENT=4 # 紧急件办结时限
SLA_HOURS_NORMAL=24
SLA_HOURS_LOW=72
# 决赛环境切换 MySQL 8:
DATABASE_URL=mysql+pymysql://root:password@localhost:3306/appeal_dispatch
离线部署:无外网机器直接 ./startup.sh 即可 —— SQLite 零配置 + 规则引擎离线分析,
全部 70 个测试也在离线环境跑通(tests/conftest.py 强制弹出 Key 环境变量)。
测试
pip install -r requirements-dev.txt
pytest -q # 92 个用例,全程离线
覆盖:规则引擎(复合案例/情感边界/紧急度安全词全覆盖/关键信息)、LLM 分析器(假 httpx 响应:正常/ 超时/5xx/脏JSON/空参数/多余字段/缺字段/归一化)、职责匹配、SLA 三档与超时统计口径、工单号生成、 状态机(主线全流转/跨级非法/终态冻结/重复接单/拒单重派)、提交→分析→派单→流转→办结全闭环、 批量分析降级与脏数据拦截、组合筛选/分页边界、统计口径、health,以及 XSS 防御三件套 (payload 原样 JSON 往返、esc() 引号转义契约、用户字段拼接静态扫描 + JS 语法回归)。
项目结构
baisitong2/
├── baisitong2/ # Python 包
│ ├── main.py # 应用装配 + 异常兜底
│ ├── config.py # 环境变量集中配置
│ ├── database.py # engine / 会话工厂
│ ├── errors.py # 业务异常体系
│ ├── models/ # Appeal / WorkOrder / Department / DailyStat
│ ├── schemas/ # Pydantic DTO
│ ├── routers/ # appeals / workorders / stats
│ ├── services/ # analyzer / dispatcher / state_machine / stats / departments
│ └── static/ # 原生前端(4 页面)
├── bin/cli.js # npm 启动器(探测 Python → ~/.baisitong2/venv)
├── tests/ # pytest:单元 + API 集成(离线)
├── sql/init.sql # MySQL 8 DDL + 预置部门
├── docs/项目流程.md/html # 项目文档
└── startup.sh / startup.bat # 一键启动
License
MIT © yangxuan
Metadata
Release files for baisitong2 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| baisitong2-1.0.0.tar.gz | 76.0 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| baisitong2-1.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 141.2 kB
Release files / baisitong2-1.0.0.tar.gz
| Download URL | baisitong2-1.0.0.tar.gz |
|---|---|
| Size | 76.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9f1c89e2327351cd06aaa5bf6952bff352e893f01d08cf877b622d6c9d76e82e
|
|
BLAKE2b-256 checksum How to use checksums |
a070493a49b48685e131e9bd0345e329db2f46d69d0f1c36190468ff2e49e1f7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.9.6
|
Release files / baisitong2-1.0.0-py3-none-any.whl
| Download URL | baisitong2-1.0.0-py3-none-any.whl |
|---|---|
| Size | 65.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
32378ff4bdd8550eee1a23dd2c9b36fcc5d8784e1f50d20204216831b0aeb012
|
|
BLAKE2b-256 checksum How to use checksums |
7ef62a3b0469b7af974e55d5cb0f8708e25838553168b058ada896c2bcf78241
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.9.6
|
Security for baisitong2 1.0.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.