预警专家 · 数据获取能力
⛔ MCP 调用封装说明(AI 禁止裸调 MCP 工具)
本 skill 对数据类 MCP 工具的封装分两类:
- ⭐
get_user_and_org_info:由查询脚本经mcp_client内部调用(query_todo_summary.py/query_todo_detail.py),AI 禁直调(文档见references/tools/get_user_and_org_info.md)。- ✅
get_org_detail/get_pending_project_list:已封装进references/scripts/query_todo_summary.py/query_todo_detail.py,AI 只通过execute_command运行脚本拿结果,禁止裸调。其字段契约与调用规范已并入脚本 docstring 注释(唯一真相源,非独立 .md 文档)。脚本已内置:参数构造(字段类型 / 嵌套结构 / repeated 裸数组等)、入口守卫(has_pending_review / 审批中)、一致性校验(no≠old_no / 图片域名)、失败上抛(绝不降级)。脚本 docstring 注释为字段契约与调用规范的权威文档(唯一真相源),改动脚本须同步更新注释。
概述
专家内部使用的 MCP 数据获取能力封装。统一封装以下场景的 MCP 工具调用:
- ⭐ 首次查询脚本内调用
get_user_and_org_info:机构准入判定 + 拿org_no/org_name/type_of_organization(由query_todo_summary.py/query_todo_detail.py内部经mcp_client调用,AI 禁直调) - 获取机构详情(含
cert_warning证件预警清单) - 获取项目级预警分组(含
warning_types=[1]备案号即将过期)
📌 机构类型只有一个概念:
get_user_and_org_info.type_of_organization与get_org_detail.institution_type是同一个东西(同值域、同语义)。优先用脚本输出org.type_of_organization(来自get_user_and_org_info,失败时脚本已回退为institution_type),不必为了机构类型额外调接口。
触发场景
由预警专家在以下情境加载:
- 首次查询:运行查询脚本(脚本内调
get_user_and_org_info做准入 + 取上下文,输出org字段) - 查询计数意图:运行
references/scripts/query_todo_summary.py直接拿到组装好的title/subtitle(脚本内并行调get_user_and_org_info+get_org_detail+get_pending_project_list);详情用query_todo_detail.py [--scope cert|record|both] - 处理证件更新意图:需要机构编号、机构类型(决定证件字段规则)、当前证件明细等基础信息时
- 处理备案号更新意图:需要项目级备案号完整分组明细(由
query_todo_detail.py --scope record一次性拉全提供)
工具清单
| 工具名 | 用途 | 参考文档 |
|---|---|---|
get_user_and_org_info |
⭐ 由查询脚本经 mcp_client 内部调用(AI 禁直调):机构准入判定(org_no 为空则专家不可用)+ 提供 org_no / org_name / type_of_organization 等上下文(脚本输出 org 字段) |
references/tools/get_user_and_org_info.md |
get_org_detail |
拿机构详情 + cert_warning 证件预警清单(机构类型优先用脚本 org.type_of_organization) |
✅ 已封装进 references/scripts/query_todo_summary.py / query_todo_detail.py,AI 禁裸调;字段契约见脚本注释 |
get_pending_project_list |
拿项目级预警分组(备案号即将过期等) | ✅ 已封装进 references/scripts/query_todo_summary.py / query_todo_detail.py,AI 禁裸调;字段契约见脚本注释 |
查询计数意图(AI 仅做编排,调用脚本拿结果)
⛔ AI 禁止裸调
get_org_detail/get_pending_project_list,一律运行封装脚本。
机构上下文(已由脚本在首次查询时随 org 字段一并返回):org_no / org_name / type_of_organization。
查询计数(运行脚本,一步到位):
cd skills/alert-info-fetcher/references/scripts && python3 query_todo_summary.py
脚本内部已并行调 get_org_detail 与 get_pending_project_list 两个数据源(参数与分页由脚本内封装,AI 无需感知),
并按下方"查询计数意图的返回体"规范逐字符组装好 title / subtitle / kind / has_pending_review,直接返回:
{ "title": "证件更新", "subtitle": "<逐字符模板>", "kind": "cert | record | both | none", "has_pending_review": false }
- AI 原样消费
title/subtitle/kind填入可点击列表,严禁自行编造/润色任何字(逐字符模板见下方)。 kind供 AI 决定后续流程分支:cert→ 走证件更新流程;record→ 走备案号更新流程;both→ 两类都有待办、须弹窗二选一;none→ 无待办。has_pending_review:证件审批中守卫(true→ 证件入口暂不可用),仅供 AI 内部分支判断,不进 Leader 菜单。- 具体哪些证件 / 哪些项目备案号要更新,用
query_todo_detail.py [--scope cert|record|both]获取(脚本内已分页拉全、排序、过滤)。
说明:机构信息已由首次查询脚本随 org 字段一并返回(org_no / org_name / type_of_organization),无需额外调用。若在处理证件更新的开场话术中需要"张三,您好,[机构名]的证件..."之类的话术,直接取脚本输出 org.org_name(get_org_detail 已封装进脚本、AI 禁裸调,⛔ 不要为拿机构名去裸调它)。
查询计数意图的返回体(由脚本生成,AI 原样消费)
⚠️ 预警专家在查询计数意图下只返回以下扁平四字段(与
query_todo_summary.py实际输出一致):
{ "title": "证件更新", "subtitle": "法人身份证已过期, 请尽快更新证件, 我来协助你更新", "kind": "cert", "has_pending_review": false }
kind:cert→ 走证件更新流程;record→ 走备案号更新流程;both→ 两类都有待办、须弹窗二选一;none→ 无待办。供 AI 决定后续分支。has_pending_review:证件审批中守卫(true→ 证件入口暂不可用,不影响备案号更新);仅供 AI 内部分支判断,不进 Leader 菜单(Leader 菜单仅消费title/subtitle/kind)。title/subtitle由脚本逐字符生成(cert优先级 >record、只取最紧迫 1 条、has_pending_review审批中文案等规则均在脚本内实现),AI 严禁自行计算或改写。- ⛔
cert_count/record_count/cert_list/record_list等结构化字段不出现在本意图返回值中——它们是query_todo_detail.py的内部工作结构(供「处理证件/备案号更新」流程拉全量明细用),见下方「详情字段 schema」。
todo_card 组装(可点击列表专用)
⛔⛔ 一旦遇到"需要用户从多个选项中选一个"的决策点(如任务一/任务零:证件与备案号都有待办),必须调用
AskUserQuestion把选项弹出。
本 skill 负责逐字符生成 title/subtitle 文案;调用方(本专家)把这两个字段原样填入 AskUserQuestion 的 options[].label/description,MUST NOT 自行编造/润色。
⛔⛔ 头等铁律:title / subtitle 是逐字符固定的模板,严禁自由发挥
返回 JSON 只有
title、subtitle、kind、has_pending_review四个扁平字段(不含key/items/count/cert_list/record_list等)——title/subtitle由脚本逐字符生成,AI MUST 原样消费,MUST NOT 做任何"润色"、"优化"、"信息增强"。(has_pending_review仅供 AI 内部分支,不进 Leader 菜单)五条绝对禁令(每条都对应过真实事故):
- ❌ 禁止在一条 subtitle 里拼多个条目(哪怕有 5 个项目到期,subtitle 也只描述最紧迫的那一条;其余明细用户点进去后由处理流程分页展示)
- ❌ 禁止增删模板中的任何字(不许加"请尽快更新备案号"这类不在模板里的尾巴;也不许删模板里的"的"、"在")
- ❌ 禁止替换同义词("到期"不许写成"过期";"天后到期"不许写成"天后过期")
- ❌ 禁止增删标点或改变标点全半角(模板里是半角逗号+空格
,,不许换成全角,;模板里没有;就不许出现;)- ❌ 禁止自行增删占位符(
{project_no}必须出现且必须是真实项目 ID;不许自己给项目名套「」)自查方法:把你生成的 subtitle 和模板逐字符比对,只有占位符位置可以不同,其他每一个字、每一个空格、每一个标点都必须完全一致。
统一结构(扁平四字段:title / subtitle / kind / has_pending_review,由 Leader 自行补 key):
{
"title": "<菜单主标题, 严格取自脚本生成的固定值>",
"subtitle": "<单行摘要, 严格由脚本逐字符生成>",
"kind": "cert | record | both | none",
"has_pending_review": true | false
}
约定:
- 返回 JSON 只有
title/subtitle/kind/has_pending_review四个字段,没有key/count/disabled之类的控制字段——是否展示、是否有前置限制,全靠title/subtitle是否为空及 subtitle 文案内容来传达(has_pending_review仅供 AI 内部分支,不进菜单) - 本 skill(alert-expert)固定只生成 1 条
title/subtitle/kind——因为用户视角只需要一个"证件与备案号"入口,具体是证件还是备案号由本专家在「处理证件与备案号」步骤内部询问/决定,无需在入口层拆成两项(kind=both时由本专家自己弹窗二选一) - 优先级:证件 > 备案号(由
query_todo_summary.py按此规则算出,AI 不重算):kind=cert/kind=record/kind=both已直接给出分流结论;两者都无待办 →kind=none、title/subtitle留空 title为空 → 本专家 / Leader MUST 视为"该类无待办",从可点击列表中 跳过该行(等价于不下发)- 本 skill 仅负责单条 title/subtitle/kind 内容;独立入口下由本专家直接把它呈现为可点击选项;被 Leader 调度时由 Leader 自行补
key="alert"
cert 组装规则(脚本输出 spec · 仅供核对,AI 不计算)
⚠️ 以下
title/subtitle全部由query_todo_summary.py逐字符生成,AI 只原样消费、严禁自行计算或改写。本表仅作为人肉核对脚本输出是否符合规范的参考(验证 oracle),不是 AI 执行步骤。
取"最紧迫的证件"作为 subtitle 素材——cert_list 已按 expired+remaining_day 升序排序,只取 cert_list[0] 这一条(脚本内实现)。
| 条件 | title |
subtitle |
|---|---|---|
cert_count === 0 |
"" |
"" |
cert_count > 0 且 has_pending_review === false 且 cert_list[0].expired === false |
"证件更新" |
模板 A |
cert_count > 0 且 has_pending_review === false 且 cert_list[0].expired === true |
"证件更新" |
模板 B |
cert_count > 0 且 has_pending_review === true |
"证件更新" |
"当前机构信息有申请单待审批, 审批完成后才能提交证件更新。"(固定文案) |
- title 固定值:
证件更新 - 模板 A(未过期):
{cert_type_label}在 {remaining_day} 天后到期, 请尽快更新证件, 我来协助你更新 - 模板 B(已过期):
{cert_type_label}已过期, 请尽快更新证件, 我来协助你更新 - 占位符:
{cert_type_label}←cert_list[0].cert_type_label(映射见下文「cert_type 映射」);{remaining_day}←cert_list[0].remaining_day
逐字符禁改的细则(半角逗号+空格、禁拼多条、禁同义词替换等)见上方「头等铁律」,此处不再重复。
record 组装规则(脚本输出 spec · 仅供核对,AI 不计算)
⚠️ 以下
title/subtitle全部由query_todo_summary.py逐字符生成,AI 只原样消费、严禁自行计算或改写。本表仅作核对参考,不是 AI 执行步骤。
取"最紧迫的项目"作为 subtitle 素材——record_list[0](脚本内只取首项,哪怕 record_count 是 5)。
| 条件 | title |
subtitle |
|---|---|---|
record_count === 0 |
"" |
"" |
record_count > 0 |
"备案号更新" |
下方模板 |
- title 固定值:
备案号更新 - subtitle 模板(无尾巴,与证件不同):
{project_no} {project_name} 的备案号在 {pending_stop_days} 天后到期 - 占位符:
{project_no}←record_list[0].project_no(项目 ID,必须有);{project_name}←record_list[0].project_name(裸文本,不加「」);{pending_stop_days}←record_list[0].pending_stop_days
其他约束:
- 备案号 subtitle 不受
has_pending_review影响(机构级审批中锁定只针对证件) - 若首个项目恰好是
fund_raising_program_audit_status === 2(审批中)而其他项目可更新,subtitle 仍取该首项——展示只是文案,用户点入后 Skill 会按项目级守卫拦截审批中项目
注意(供处理流程消费详情时参考):
record_count是项目数(不是预警条目数);审批中项目照常计入(保持"到期数"原始语义),updatable字段供后续 Skill 决策"是否可发起更新流程"- 不返回机构整体待办计数:独立入口无需"全部待办"汇总,用户点入对应流程后再按需拉取
- 备案号更新流程需要项目级字段(由
query_todo_detail.py --scope record拉全):fund_raising_program_id用作update_org_record_number的id入参;fund_raising_program_no用作no一致性校验基准;fund_raising_program_audit_status用作项目级审批中守卫(===2时拦截)。(v2 已从warns[].id迁移到项目级fund_raising_program_id;warning_id是预警条目主键,本流程不使用)
audit_status_label 组装规则(由脚本计算,供详情展示;updatable = status != 2):
fund_raising_program_audit_status |
语义常量 | audit_status_label |
updatable |
|---|---|---|---|
1 |
AUDIT_APPROVED |
"已通过" |
true |
2 |
AUDIT_PENDING |
"审批中" |
false |
3 |
AUDIT_REJECTED |
"已驳回" |
true(用户可重新提交) |
详情字段 schema(脚本内部转换,供处理流程消费 · 参考用)
⚠️ 以下转换(
cert_warning.items→cert_list、cert_type_label映射、expired判定、排序)全部在query_todo_detail.py/query_todo_summary.py内由代码实现,并已在脚本 docstring 声明为唯一真相源。此处仅作人肉核对参考,AI 不重算、不重写。
get_org_detail 返回的 cert_warning.items 每一条形如:
{ "cert_type": 1, "end_date": "2026-09-01", "remaining_day": 25 }
转换为预警专家统一的 cert_list 结构(脚本输出,供处理流程展示):
{ "cert_id": null, "cert_type_code": 1, "cert_type_label": "社会组织法人登记证书", "expire_date": "2026-09-01", "remaining_day": 25, "expired": false }
cert_type 与 cert_type_label 的映射(与 OrgCertType 枚举一致,脚本 _cert_type_label 实现):
| cert_type 值 | label(用户可读名称) | 说明 |
|---|---|---|
| 1 | 社会组织法人登记证书 | charitable_person |
| 2 | 慈善组织公开募捐资格证书 | charitable_public,仅公募机构会出现 |
| 3 | 法人身份证 或 专项基金负责人身份证 | corporation_id_card;结合 institution_type 联合判定:institution_type ∈ {1,2} 时为机构法人身份证,institution_type == 3 时为专项基金负责人身份证 |
expired 字段(脚本计算):remaining_day == -1 → expired: true;remaining_day > 0 → expired: false
排序约定(脚本内已实现):
- 证件预警清单:按
(expired ? -1 : remaining_day)升序,已过期永远排最前 - 备案号项目预警清单:后端通常按
pending_stop_days升序,脚本拉全后如需明确顺序再排一次
非超管场景
- 后端约定:
cert_warning仅当调用账号在其所属机构内是超管时才返回(权限判断由后端完成,预警专家不主动读用户角色字段,只按 nil 处理) - 非超管调用时
cert_warning为 nil,本skill 视为"无证件预警"(cert_count: 0, cert_list: []) get_pending_project_list不受超管权限影响,非超管也能拿到项目级预警- 不主动向用户暗示"因您不是超管所以看不到",避免泄露内部权限信息
老字段的兼容性
get_org_detail 也返回旧字段 detailed.certificate_validity_day 和 detailed.charitable_public_day。预警专家应优先使用 cert_warning,理由:
cert_warning是"预警清单"(只装 <=90 天条目),已经做过窗口过滤- 老字段是"证件剩余天数"(含长期 999999、已过期 -1),需要调用方自己过滤
⚠️ 老字段禁止用于:
- 决定是否展示证件到期项(应用
cert_warning判断) - 决定分派菜单里"证件/备案号更新"是否展示
铁律
###⛔头等铁律:接口不可用时严禁降级
MCP 工具报错、RPC 未注册、超时、返回空/异常时,必须立即上抛错误,绝不允许:
- ❌ 尝试用其他 MCP 工具拼凑同一份数据(如
get_pending_project_list挂了就用get_project_list + get_project_detail拼凑备案号数据) - ❌ 尝试用其他数据源接口(如
get_org_todo_list/GetTodoInfoForSkill)代替本skill 声明的白名单 - ❌ 通过
execute_command写 Python 脚本、发起 HTTP 请求、爬网页(除非对应 Skill 明确列出脚本及严格触发条件,例如用户已提供有效慈善中国详情页链接并明确选择查询) - ❌ 静默继续跑:把接口错误吞掉,用"合理默认值"(如 count=0)返回
唯一允许的响应:如实返回错误 JSON:
{
"error": "<tool_name> 调用失败",
"reason": "<原始错误信息>",
"attempted_tool": "<tool_name>",
"retry_suggestion": "该接口暂不可用,请稍后重试。请勿使用其他接口补齐数据。"
}
为什么这条铁律头等:接口挂掉时的静默降级会导致:
- 字段口径不一致:
get_project_list.fundras_state≠get_pending_project_list.projects[].fund_raising_program_audit_status,语义未必对齐 - 用户看到假成功:以为"3个项目要更新",实际漏掉了应有的项目
- 审批状态被错标:把"审批中"标成"已通过"会引发用户点选后误操作
- 调试地狱:Skill 层看似正常运行,但数据来源与文档偏离,问题极难定位
⛔ MCP 工具白名单
本 skill 只能使用以下 3 个 MCP 工具,其他工具即使能返回类似数据也严禁使用:
-✅ get_user_and_org_info
- ✅
get_org_detail - ✅
get_pending_project_list
严禁绕道:
- ❌
get_org_todo_list/GetTodoInfoForSkill - ❌
get_project_list+get_project_detail(这些是其他专家场景的工具) - ❌
get_process_list/get_process_detail - ❌
query_data/get_data_by_template - ❌ 任何未在本文件"工具清单"章节列出的工具
其他铁律
以下数据口径约束已由 query_todo_*.py 在代码内强制(详见脚本 docstring 铁律),AI 与维护者以此为准,本文不再重复:cert_warning 为 nil 视为无预警(非报错)、cert_type→label 映射不许自创、remaining_day==-1 即已过期、warns.length 不得加总代替 pending_stop_project_count、不得传空 warning_types、不得混用两接口的 days 语义、has_pending_review 仅作用于证件(不作用于备案号)、fund_raising_program_audit_status 必须透传、审批中项目不扣减 record_count、查数阶段不传 page_size:100。
AI 行为铁律(脚本无法代劳,必须遵守):
- ❌ 返回
items数组 /key/count等字段(本专家 / Leader 仅依赖title/subtitle/kind组装可点击列表);也不允许调用方自行编造 title/subtitle - ❌ 在一条 subtitle 里拼多个条目(subtitle 只描述最紧迫的一条,其余明细由用户点进去后的处理流程分页展示)
- ❌ 增删模板中的任何字(如给备案号 subtitle 加"请尽快更新备案号"尾巴,或删掉"的"、"在")
- ❌ 替换同义词("到期"写成"过期"、"天后到期"写成"天后过期")
- ❌ 改变标点全半角(模板是半角
,,不许换成全角,;模板无;就不许出现) - ❌ 丢失
{project_no}项目 ID(备案号 subtitle 必须以真实项目 ID 开头) - ❌ 不能对非超管用户过多解释权限逻辑(数据主权)
参考文件
references/tools/get_user_and_org_info.md— ⭐ 由查询脚本经mcp_client内部调用的用户与机构基础信息 MCP 工具references/scripts/query_todo_summary.py/query_todo_detail.py— ✅ 封装脚本,也是get_org_detail/get_pending_project_list的唯一契约真相源(字段语义、铁律见脚本 docstring 注释);AI 只跑脚本、禁裸调