🏘️ 社区百事通 · 项目流程文档
社区政策咨询智能助手(AI + 社会治理)· RAG 知识库 + 多轮对话 + 来源引用 + SSE 流式
版本 1.0.4 · 2026-08-21 · 作者 yangxuan
npm: baisitongPyPI: baisitong
测试 49/49 全绿零配置可离线运行
1970行 Python 后端(FastAPI + SQLAlchemy)
773行原生前端(无框架、无构建)
49个 pytest 用例(29 单元 + 20 集成)
3 级降级链路(远程→本地引擎→无答案兜底)
1 · 项目概览
居民用口语提问("养狗要办证吗?"),系统基于内置政策知识库做 RAG 检索增强问答,
回答附带可溯源的原文引用,支持多轮追问,全程 SSE 流式输出。
核心亮点
- 零配置离线可用:不配 Key、不装数据库,
npx baisitong 直接起服务;内置 TF-IDF 检索与抽取式生成,断网也能完整演示。
- 演示永不中断:远程大模型失败/超时/中途断线自动降级;半段回答保留并提示;客户端断开时部分回答仍落库。
- 答案可溯源:回答带
[1][2] 引用 + 文档标题 + 原文片段 + 相关度;无答案明确告知,绝不编造。
- 混合检索管线:向量 + 关键词双路,归一化 α 加权融合;多轮指代改写 + 口语→政策用语同义词归一。
2 · 快速开始
# 方式一:npm(自动建 venv/装依赖/启动)
npx baisitong # http://localhost:8080
# 方式二:pip
pip install baisitong && baisitong
# 方式三:源码
./startup.sh # Windows 用 startup.bat
# 常用参数
baisitong --port 9000 --host 127.0.0.1
baisitong --db mysql+pymysql://root:pwd@localhost:3306/community_assistant
3 · 系统架构(严格三层)
┌─────────────────────────────────────────────────────────────┐
│ 前端 static/(原生 HTML/CSS/JS,无构建) │
│ 会话侧栏 · SSE 打字机气泡 · 引用卡片(相关度条) · 热门问题 │
├─────────────────────────────────────────────────────────────┤
│ 接口层 routers/ │
│ chat(SSE) · conversations · knowledge · questions │
│ feedback · stats · health │
├─────────────────────────────────────────────────────────────┤
│ 逻辑层 services/ │
│ rag(问答编排) · retriever(混合检索+查询改写) │
│ embeddings(向量引擎) · llm(大模型/本地引擎) │
│ documents(分块入库) · prompts(提示词模板) │
├─────────────────────────────────────────────────────────────┤
│ 数据层 models/ + database.py │
│ SQLAlchemy ORM → SQLite(默认) / MySQL 8(一键切换) │
└─────────────────────────────────────────────────────────────┘
│ │
GLM/DeepSeek API 内置本地引擎(离线兜底)
(配置 Key 后启用) TF-IDF 检索 + 抽取式生成
分层职责严格单向:routers → services → models/database。
接口层不写业务逻辑、逻辑层不感知 HTTP、数据层统一 ORM——直接对应 AI 评委
"模块划分清晰、分层合理、组件解耦"(架构分 40%)。
4 · RAG 核心管线(8 步)
查询改写短问句/指代词拼接上一轮;口语→政策用语同义词归一
向量化远程 Embedding 或本地 TF-IDF(与索引同分布)
双路检索向量余弦 top-10 + 关键词覆盖(词元×0.6 + 字符×0.4)
融合排序各路按最大值归一后 α=0.7 加权;双路均低于绝对下限→无答案
检索预览先推 retrieval 事件,用户感知"正在查资料"
Prompt 组装政策原文片段 + 最近 6 条对话历史
流式生成远程 LLM SSE 逐字;失败自动降级本地抽取引擎
引用后处理只保留实际 [n] 引用的来源;回答与来源落库
5 · API 一览
| 方法 | 路径 | 说明 |
| POST | /api/chat | 问答(SSE 流式:retrieval → token×N → suggestions → done) |
| GET | /api/conversations | 会话列表 |
| GET / DELETE | /api/conversations/{id} | 会话详情 / 删除 |
| POST | /api/knowledge/init | 初始化预置知识库(force 重建) |
| POST | /api/knowledge/upload | 上传政策文档(自动分块 + 向量化) |
| GET | /api/knowledge/documents | 文档列表 |
| GET | /api/knowledge/search?q= | 手动检索(调试) |
| GET | /api/questions/hot | 热门问题 |
| POST | /api/feedback | 点赞 / 点踩 |
| GET | /api/stats | 运营统计(今日答疑 / 满意度 / 热门) |
| GET | /api/health | 健康检查(运行模式自检) |
| GET | /docs | OpenAPI 自动文档 |
6 · 双引擎与降级策略
| 组件 | 远程模式(配置 Key) | 本地模式(默认 / 兜底) |
| LLM | OpenAI 兼容流式(GLM / DeepSeek) | 抽取式引擎:噪音句过滤 + 词元打分 + 关键事实加权,同格式输出 |
| Embedding | OpenAI 兼容 /embeddings | 中文二字组 TF-IDF 稀疏向量(语料 IDF) |
- 远程客户端 1.0.2+ 进程内单例,复用 httpx 连接池
- 断线三级保障 1.0.3+:半段保留 + 开局失败整体降级 + 客户端断开部分落库
- MySQL 连接
pool_pre_ping + pool_recycle=3600,长演示不掉线
7 · 测试(49 用例全绿,全程离线)
| 分层 | 数量 | 覆盖 |
| 单元 test_units.py | 29 | 分块策略 / TF-IDF 余弦 / 检索融合与无答案下限 / 查询改写 / 引用提取 / 本地抽取回答 / 远程客户端与 Embedder 单例 |
| 集成 test_api.py | 20 | 健康检查 / 知识库 / SSE 问答 / 多轮追问 / 无答案兜底 / 流式顺序 / 远程中途断线保留半段 / 开局失败整体降级 / 客户端断开部分落库 / 会话 CRUD / 反馈统计 |
pip install -r requirements-dev.txt
pytest tests/ -v # 49 passed
8 · 发布与分发
| 平台 | 包 | 安装 |
| npm | baisitong(Python 项目 + Node 启动器) | npx baisitong / npm i -g baisitong |
| PyPI | baisitong(纯 Python 包) | pip install baisitong |
启动器逻辑:探测 Python 3.9+(Windows 优先 py -3,无 shell 防路径空格断裂)→
~/.baisitong/venv 持久虚拟环境(依赖装一次,requirements 变更自动重装)→
pip 镜像优先阿里源、失败回退官方 → 启动并透传参数。
离线部署:pip download baisitong -d pkgs/ 拷贝后
pip install --no-index --find-links=pkgs/ baisitong,全程无需联网。
9 · 版本迭代记录
| 版本 | 日期 | 要点 |
| 1.0.0 / 1.0.1 | 2026-08-21 前 | 首版:RAG 问答、双引擎、npm / PyPI 首发 |
| 1.0.2 | 2026-08-21 | 远程客户端连接池单例;断线保留半段回答不拼接;流式脏行容错;作者 yangxuan;+5 测试 |
| 1.0.3 | 2026-08-21 | 客户端断开部分回答兜底落库;启动地址友好显示;README 精简;+1 测试 |
| 1.0.4 | 2026-08-21 | 项目流程文档(MD+HTML)、CHANGELOG、决赛评分对照;文档随 npm 包分发 |
10 · 决赛评分对照
| 评分项(分值) | 本项目应对 |
| 系统架构设计(AI 评分 40%) | routers / services / models 严格三层单向;配置集中;双引擎统一接口可扩展;零重依赖 |
| 代码质量(AI 评分 60%,重复率≤10%,核心逻辑需单测) | 49 用例覆盖分块 / 检索 / 改写 / 引用 / 降级全核心链路;命名注释规范;无复制粘贴 |
| 核心功能完成度(展示 50 分) | 政策问答 / 多轮 / 引用 / 知识库管理 / 统计看板全闭环,一键启动 ≤3 步 |
| 用户体验(展示 25 分) | 打字机流式 + 检索预览 + 引用卡片相关度条 + 热门问题推荐 |
| 业务解决效果(展示 25 分,AI 须为关键要素) | 混合检索 + 查询改写解决"口语 vs 政策原文"鸿沟——规则关键词做不到语义召回,是"AI 关键要素"的典型论据 |
| 稳定性(扣分项防御) | 三级降级 + 断线落库 + MySQL 连接池保活,演示不断电 |
11 · 15 分钟演示路径建议
| 时间 | 环节 | 要点 |
| 1 min | 开场痛点 | 居民看不懂政策原文、社区人工答复重复 |
| 2 min | 一键启动 | npx baisitong → localhost:8080,强调零配置离线 |
| 3 min | 基础问答 | "养狗需要办证吗?"→ 流式回答 + 引用卡片 + 相关度条 |
| 2 min | 多轮追问 | "费用是多少?"→ 正确指代到养犬费用 400 元 |
| 2 min | 无答案诚实 | 知识库外问题 → 明确"未找到" + 推荐热门问题 |
| 2 min | 知识库管理 | 上传 txt → 自动分块入库 → 立即可检索 |
| 1 min | 运营看板 | 今日答疑数、满意度、热门问题 |
| 2 min | 技术收尾 | 架构图 + 双引擎降级演示(断网仍可问答) |