部门过滤与综合研判:从问答机到研判助手(M6 落地实测)
系列 :城市管理 Agentic RAG ------ 从零搭建城市管理问答系统
本篇 :M6 · 部门过滤命令 + 综合研判输出(实测版)
一、M5 之后还差什么?
M5 给系统装上了「自适应检索」和「答案反思」,会自己换姿势找资料、答完自己检查作业。但用着用着,发现它还只是个被动应答的问答机------你问一句,它答一句,每次只给一个答案。
真实的城市管理场景不是这样的:
场景一:领导想看全局。 「XX 社区暴雨应急准备」------这不是一个单一问题,它牵扯气象预警、卫健急救、民政弱势群体、热线积水投诉四个领域。你只想要一段话,还是想要一份分部门、带来源、能直接拿去开会的研判报告?
场景二:你要盯住某个部门。 想单独看卫健委的急救资源情况,系统却自作主张把气象局、民政局的资料也混进来------信息是多了,但不聚焦,甚至可能带偏结论。
M6 要做的就是两件事:
- 部门过滤命令 ------
/dept 卫健委 急救资源,你说查哪个部门就查哪个部门,扩展也只在这个领域内扩; - 综合研判输出 ------
/all或问题本身跨领域时,输出四部门分块研判报告:气象、卫健、民政、热线各一段,各带来源,最后给综合建议。
打个比方:M5 之前是「前台接电话」,M5 是「接电话的人会查资料、会复核」,M6 是「这个人会给你写会议纪要」------还是分部门、带出处的会议纪要。
二、先看效果:验收场景实测
按推进表,M6 的验收是:输入「XX社区暴雨应急准备」→ 输出四部门分块报告。先看实测结果:
验收 ①:/all XX社区暴雨应急准备 → 四部门分块报告
text
❓ 问题 > /all XX社区暴雨应急准备
[路由] all(/all 命令) → 综合研判(四业务域分块报告)
[检索] 按域检索(每域 top_k=2)命中 8 块
(气象局×1、应急局×1、120急救中心×1、12345热线×2、民政局×2、卫健委×1) 最高分 0.704
📋 综合研判:
【气象研判】(来自:气象局/预警等级.txt、应急局/防汛应急响应预案.txt)
研判:XX社区暴雨应急准备需依据预警等级与响应预案联动。若气象局发布暴雨橙色及以上预警,
应急局预案要求启动Ⅳ级及以上响应,成员单位到岗、强制转移危险区群众。
当前资料未提供社区具体内涝点、水位数据,无法预判具体响应级别,需实时监测补充。
【卫健研判】(来自:120急救中心/急救流程.txt、卫健委/急救资源.txt)
120急救中心要求城区接警响应≤15分钟;市第一人民医院为三甲,空闲床位320张,
可作急救转运接收点。但资料未提供社区具体位置、急救站点距离及暴雨专项预案,
无法评估实际响应时效,需补充信息。
【民政研判】(来自:民政局/弱势群体统计.txt、民政局/养老服务设施.txt)
XX社区为老旧小区,老年人口占比32%,需优先保障独居老人156人、残疾人223人及低保户587人。
但资料未提供社区具体应急物资储备、避难场所及转移方案(资料不足),建议补充。
【热线研判】(来自:12345热线/高频诉求统计.txt、12345热线/工单案例.txt)
7月市政设施类诉求占23%(2891件)且环比上升15%,热点区域为XX路与YY路交叉口;
该处7月20日积水深30cm,已派城管局处置。建议优先部署该点位排水及井盖巡查。
【综合建议】
优先级排序:① 气象与应急联动 → ② 民政弱势群体转移 → ③ 热线积水点处置 → ④ 卫健急救保障。
跨部门协调:应急局牵头启动预案,气象局实时推送预警;民政对接街道落实弱势群体转移;
城管局优先疏通积水点;卫健委预留急救通道。
行动建议:立即补充社区内涝点、物资储备数据,完善专项预案;建立信息共享群,每2小时通报。
四个部门各一段,每段开头标注来源文件,最后综合建议给出优先级、跨部门协调、行动建议------这已经是一份能直接拿去做会前准备的研判材料了。
验收 ②:/dept 卫健委 急救资源是否充足 → 只查卫健域
text
❓ 问题 > /dept 卫健委 急救资源是否充足
[路由] 跳过(/dept 命令)→ 检索范围: 卫健委
[检索] 首轮 top_k=3(卫健委)最高分 0.476
[检索] 扩展① top_k=5(卫健委/120急救中心)最高分 0.514
[反思] 核查通过(与引用资料一致,无编造)
💬 回答:
根据现有资料,无法全面判断急救资源是否充足......
1. 救护车配置:全市救护车45辆,其中负压救护车12辆(来源:卫健委/医院床位资源.txt)。
2. 医院床位与ICU:市第一人民医院总床位1200张,ICU 80张,空床率8%......
📎 引用来源:
- 卫健委/医院床位资源.txt
- 120急救中心/急救流程.txt
检索范围死死锁在卫健域(卫健委 + 120急救中心),回答全部有据可查,还主动说明了「缺需求侧数据,无法判断是否充足」------不硬答。
验收 ③:不敲命令,问题本身跨领域也会自动触发
text
❓ 问题 > 如何统筹全市应急资源应对灾害?
[路由] all → 综合研判(四业务域分块报告)
路由判断这是跨领域综合问题,不需要用户记命令,自动切换成研判模式。命令是给「想要控制权」的人用的,普通用户直接问就行。
三、命令系统:给用户一个「方向盘」
M6 给 CLI 加了三个命令(parse_command 解析):
python
❓ 问题 > /help
可用命令:
/dept <部门[,部门...]> <问题> 指定部门精准问答(如 /dept 卫健委 急救资源充足吗)
/all <问题> 全部门综合研判(四业务域分块报告 + 综合建议)
/help 显示本帮助
直接输入问题则自动路由到相关部门;跨领域综合问题自动输出综合研判报告
可用部门:气象局、应急局、卫健委、120急救中心、民政局、12345热线
三个细节值得说:
1. 部门名有校验。 敲 /dept 城管委 积水(数据里没有这个部门),系统不会静默查空,而是提示:
text
⚠️ 未知部门:城管委(可用:气象局、应急局、卫健委、120急救中心、民政局、12345热线)
2. 多部门支持逗号/顿号。 /dept 气象局,民政局 暴雨影响 一次锁两个部门。
3. 命令前缀防误判。 一开始用 startswith("/dept") 判断,结果输入 /deptx 卫健委 这种问题也被当成命令。改成「前缀后接空白或直接结束」才修好------一个小坑,见第五节。
四、综合研判报告怎么生成
核心是一个新模块 src/formatter.py 的 ReportFormatter 类。设计上有一个关键决策:分块生成,而不是一次生成。
如果把四部门资料一次全塞给大模型,让它一口气输出四块+综合建议,会出现两个问题:模型可能漏块 (写着写着少了一个部门)、可能合并(把民政和热线并成一段)。分块生成则完全可控:
python
for domain, hits in self.group_by_domain(results):
context = format_context(hits) # 只放这一个域的资料
prompt = SECTION_PROMPT.format(domain=domain, question=question, context=context)
text = self.llm.chat(prompt, ...) # 每块独立调用一次
blocks.append(f"【{domain}研判】(来自:{self._sources(hits)})\n{text}")
每块只喂本域资料、只生成一段研判,格式 100% 可控、来源逐块标注。最后把各块研判汇总,再调一次模型生成综合建议------模型只做「汇总+提建议」,不重复读原始资料,省 token 又聚焦。
另外每个域块内的 prompt 都有硬约束:只依据给定资料作答,资料不足时明确说明,严禁编造。所以民政块即使只有 0.45 分的弱相关资料,也会老老实实写「资料未提供应急物资储备......建议补充」,而不是编一份转移方案出来------这和 M5「信息不足请明确告知」是一脉相承的底线。
五、踩过的坑(三个都是真实的)
坑 1:全库 top-k 检索会被「高分域」霸榜,低分但相关的域直接被挤出。
第一版综合研判用全库检索取前 8 条,结果四域报告只有三块------民政没了。查原因:「XX社区暴雨应急准备」对气象/热线资料的相似度普遍 0.5~0.7,而对民政数据(弱势群体统计)只有 0.447,前 8 名被气象和热线占满,民政一条都进不来。
但民政恰恰是暴雨应急要重点关注的(独居老人、低保户转移)!按相似度全局排序,不等于按业务价值排序。
解法:综合研判按业务域分组检索,每域独立取 top_k(默认 2 条),合并后再排序。这样每个域都有候选块,四域报告不会缺角:
python
for _domain, depts in REPORT_GROUPS: # 气象/卫健/民政/热线四域
hits.extend(retrieve(question, top_k=top_k, dept_filter=depts))
坑 2:/dept 命令如果沿用自适应检索的「放开全库」,会把别的部门资料混进来。
/dept 卫健委 急救资源 第一版跑出来,回答居然引用了应急局/防汛应急响应预案.txt ------因为 M5 的自适应检索在首轮分低时,会自动「移除部门过滤」放开全库再搜。这个机制对自动路由是对的(防止路由误判漏检),但对用户显式指定部门就是灾难:用户明明说只看卫健委,系统却把应急局的预案拿来讲急救资源。
解法:给自适应检索加 strict_dept + expand_dept_filter 参数------/dept 命令首轮严格按指定部门,扩展轮只在同域内找(卫健委 → 卫健委+120急救中心,两个部门同属卫健域),既保领域纯净,又避免单部门数据太少直接判无果。
坑 3:startswith("/dept") 会把 /deptx 卫健委 误判成命令。
一个 5 分钟能修的小 bug,但值得记:命令前缀判断必须「后接空白或直接结束」,否则任何以 /dept 开头的正常问题都会被吞掉。
六、验收汇总与回归
| 验收项 | 结果 |
|---|---|
① /all XX社区暴雨应急准备 |
✅ 四部门分块报告(气象/卫健/民政/热线 + 综合建议,各块带来源) |
② /dept 卫健委 急救资源 |
✅ 只检索卫健域(卫健委+120急救中心),不污染其他领域 |
③ 多部门命令 /dept 气象局,民政局 暴雨影响 |
✅ 同域扩充到气象局/应急局/民政局 |
| ④ 自然输入「如何统筹全市应急资源应对灾害?」 | ✅ 路由 all 自动触发四域综合研判 |
| ⑤ 未知部门提示 | ✅ 列出可用部门清单 |
回归抽查(M1~M5 能力不退化):
- 暴雨响应 → 首轮强相关直接答 ✅
- 独居老人救助 → 路由联动 civil+weather ✅
- 低保申请 → 只查民政,不误伤 ✅
- 你好 → 零成本欢迎语 ✅
- 气象局局长电话(库内没有)→ 明确告知,零编造 ✅
七、本阶段小结
M6 之后,系统从「问答机」变成了「研判助手」:
- 给用户方向盘 ------
/dept指定部门、/all全量研判,命令简单直接; - 自动识别跨领域------路由判 all 时自动切研判模式,不强制用户记命令;
- 报告可溯源------四域分块、逐块标注来源、资料不足如实说明,综合建议基于各块研判生成。
架构上,ReportFormatter 是推进表早就预留的接口(format() 是报告模板唯一入口)------二期想加 JSON 模板、图表渲染,只扩展这个类就行,调用方不用改。
八、下一步
M6 的能力都在命令行里,演示给领导看还不够直观。M7 计划做 Gradio Web 界面:顶部四个场景按钮(暴雨应急、医疗调度......)、侧边部门过滤下拉、下方输出区渲染综合研判报告------把今天这些命令,变成点两下鼠标就能出报告的界面。
上一篇 :[M5 自适应检索与答案反思:让系统自己检查作业](#M5 自适应检索与答案反思:让系统自己检查作业)
下一篇 :[M7 Gradio Web 界面:点两下就出研判报告](#M7 Gradio Web 界面:点两下就出研判报告)
系列目录 :[城市管理 Agentic RAG ------ 从零搭建城市管理问答系统](#城市管理 Agentic RAG —— 从零搭建城市管理问答系统)
📚 想了解更专业的内容? 本文是项目实战记录。如果你对 RAG 的原理、Prompt 工程技巧、大模型 API 接入的完整方案感兴趣,欢迎访问我的 CSDN 专栏 喵本喵叁肆的 Agentic RAG 实战专栏 阅读完整的技术博客系列(含可运行代码、架构图与验收标准)。