关于 UNICEF Stats MCP
UNICEF Stats MCP 是一款实验性 MCP 服务,供 AI 助手查询 UNICEF Data Warehouse 的儿童相关统计数据。它支持按指标、国家和细分维度查询,无需 API 密钥;该项目并非 UNICEF 官方产品,引用数据前应核实。
主要功能
- 01查询 790 多项儿童相关指标
- 02覆盖 200 多个国家
- 03按性别、年龄、财富和居住地筛选
- 04返回精简或完整 JSON 数据
- 05提供用于分析的提示词和资源
适用场景
- 01按国家查询儿童发展指标
- 02跨国家比较指标
- 03按人口细分维度探索统计数据
- 04准备 AI 辅助统计分析
MCP 相关
该服务通过 MCP 工具提供 UNICEF 统计数据,并附带用于数据探索的提示词和资源。它经由 SDMX API 查询 UNICEF Data Warehouse,无需 API 密钥。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
9收录的工具列表 · 更新于 2 周前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| limit | integer | 否 | 返回的指标候选项最大数量。 |
| query | string | 是 | 自然语言搜索查询(例如“under-5 mortality”、“stunting”、“IMR”、“modelled estimates”)。接受缩写、常见同义词和方法论短语。 |
| offset | integer | 否 | 分页偏移量——返回结果前跳过此数量的最高排名匹配项。与 `limit` 配合使用,可分页浏览较长的匹配列表(例如 limit=20、offset=0 表示第 1 页;offset=20 表示第 2 页)。响应封装中包含 `has_more` 和 `next_offset`,供 LLM 判断是否继续分页。 |
详细介绍
unicefstats-mcp
实验性项目——非 UNICEF 官方产品。引用于出版物之前,请对照 UNICEF 数据仓库核实获取的数值。请参阅局限性与幻觉风险。
用于查询 UNICEF 儿童发展统计数据的 MCP 服务。可查询覆盖 200 多个国家的 790 多项儿童相关指标,并按性别、年龄、财富五分位和居住地进行细分。无需 API 密钥。
指标涵盖儿童死亡率、营养、教育、儿童保护、WASH(水、环境卫生与个人卫生)、HIV/AIDS、免疫接种、儿童早期发展等领域。许多指标与 SDG 目标相符,但该数据集的范围比 SDG 更广。
数据来源:UNICEF SDMX API
身份信息
| 属性 | 值 |
|---|---|
| MCP 身份标识 | io.github.jpazvd/unicefstats-mcp |
| PyPI 软件包 | unicefstats-mcp |
| 规范源代码库 | github.com/jpazvd/unicefstats-mcp |
| 数据来源 | 通过 SDMX REST API 访问 UNICEF 数据仓库 |
| 维护者 | Joao Pedro Azevedo(jpazvd) |
| 状态 | 实验性项目——未经 UNICEF 认可 |
第三方聚合平台(LobeHub、Smithery、mcp.so、Glama)的列表不受维护者控制。请对照上方的规范来源进行核实。
目录
- 与 unicefdata 软件包的关系
- 与其他数据 MCP 的比较
- 概览:官方统计数据 MCP 服务
- 与 sdmx-mcp 的关系
- 快速开始
- 工具
- 演示
- 提示词
- 基准测试结果
- 部署
- 开发
- 贡献
- 局限性与幻觉风险
- 来源与所有权
- 如何验证此 MCP
- 许可证
关键文档
| 文档 | 说明 |
|---|---|
| PROVENANCE.md | 数据来源、所有权、分发流程、验证步骤 |
| CHANGELOG.md | 版本历史(v0.1.0–v1.5.5),并附有引用来源 |
| RELEASE.md | 发布流程检查清单和版本管理 |
| CONTRIBUTING.md | 开发环境设置、代码风格、PR 指南 |
| CODE_OF_CONDUCT.md | Contributor Covenant v2.1 |
| examples/RESULTS.md | 包含 EQA 分解的完整 300 条查询基准测试分析 |
| examples/LITERATURE_REVIEW.md | 文献综述:官方统计数据 MCP 服务——生态系统、模式、评估、15 篇论文 |
| examples/LANDSCAPE.md | 全景分析:深入评估了 20 个服务(2026 年 3 月),并为 92 个服务编目并标注状态(2026 年 10 月)——时间线、功能矩阵、优缺点 |
| examples/results/related_work.md | 注释书目——15 篇关于工具增强型幻觉的论文 |
| examples/results/statistical_summary.md | 对基准测试结果进行 Wilcoxon、bootstrap CI、McNemar 检验 |
| examples/MCP-DIRECTORY-STATS.md | 所有官方统计数据 MCP 服务的综合目录 |
| examples/mcp-smoke-test/MULTIMODEL_SMOKETEST.md | 针对 v0.7.3 跨提供商泛化问题的跨模型冒烟测试(Anthropic / OpenAI / Google / OpenRouter)——设计、评分标准、约 $1 的默认运行成本,以及迈向完整 mini-EQA 的路径 |
与 unicefdata 软件包的关系
unicefstats-mcp 不能替代 Python、R 或 Stata 中的 unicefdata 软件包。它们面向不同的用户群体:
| unicefstats-mcp | unicefdata (Python/R/Stata) | |
|---|---|---|
| 受众 | AI 助手(Claude、Cursor、Copilot) | 数据科学家、研究人员、分析师 |
| 接口 | MCP 协议(通过 JSON 调用工具) | 原生语言 API(library()、import、ssc install) |
| 用例 | 对话式数据探索、快速查询、AI 辅助分析 | 可复现研究、ETL 流水线、统计分析 |
| 输出 | 为大模型上下文优化的 JSON(精简或完整) | DataFrame、tibble、Stata 矩阵 |
| 脚本编写 | 否——通过 AI 聊天执行单次查询 | 是——可进行完整的编程控制、循环、连接和转换 |
| 缓存 | 委托给 unicefdata | 内置 SDMX 响应缓存 |
| 批量下载 | 有限(每次调用最多 500 行) | 不限——专为完整数据集下载而设计 |
在底层,unicefstats-mcp 封装了 unicefdata Python 软件包。每次工具调用最终都会调用 unicefdata.unicefData() 或其元数据函数。可以将 MCP 理解为基于同一数据层构建的精简 AI 友好型接口。
如何选择:
- 当你正在与 AI 聊天,并希望快速探索指标、检查数值或比较国家时,使用 unicefstats-mcp
- 当你编写脚本、构建仪表板、运行回归分析,或进行任何可复现的分析工作时,使用 unicefdata(Python/R/Stata)
与其他数据类 MCP 的对比
服务按仓库命名,并带有状态标签(官方、独立、社区或商业),定义见状态标签。“—”表示该功能未在相应仓库的公开 README 中说明。计数方式以及如何提出更正,请参阅关于这些表格。
| 功能 | unicefstats-mcp(本仓库) | data360-mcp(世界银行,官方) | fred-mcp-server(社区) | world_bank_mcp_server(社区) |
|---|---|---|---|---|
| 工具 | 9 个(搜索 → 元数据 → 数据 → 代码 → 身份 + 严格的规范查找) | 16 个(搜索指标/数据集 → 元数据 → 数据 → 分类维度 → 代码表查找 → 列表;汇总 / 排名 / 比较国家;扩展国家组;单指标和多指标 Vega-Lite 可视化规范;API URL;另有一个交互式选择 UI 工具) | 3 个(浏览 → 搜索 → 获取) | 1 个(仅获取) |
| 指标 | 790 多个以儿童为重点的指标 | Data360 目录,包含多个数据库(WB_WDI、WB_SSGD,……) | 800,000 多个经济序列 | 约 1,600 个指标 |
| 国家 | 200 多个(ISO3) | 200 多个(ISO3 REF_AREA) | 以美国为主(包含部分国际数据) | 200 多个(ISO2) |
| 分类维度 | 性别、年龄、财富五分位、居住地 | 性别、年龄、城市化程度(按指标提供,通过 data360_get_disaggregation 获取) | 频率、季节性调整 | 无 |
| MCP 提示词 | 5 个(compare_indicators、trend_analysis、country_profile、sdg_progress、write_unicefdata_code) | 7 个 | 无 | 无 |
| MCP 资源 | 6 个(system-prompt、context、llm-instructions、categories、countries、glossary) | 11 个(system-prompt、context、agent-recipe、databases、codelists、data-schema、data-filters、metadata-fields、search-usage、viz/chart-grammar,……) | 无 | 无 |
| 输出模式 | 精简(5 列)/ 完整(所有列) | SDMX 格式的 JSON,每条观测都带有 claim_id(8 个字符的“携带证明的数字”哈希);聚合工具使用精简序列化器 | JSON | CSV |
| 数据摘要 | 数值范围、年份范围、国家数量 | summarize_data、rank_countries、compare_countries 工具;Vega-Lite 图表规范 | 无 | 无 |
| 分页元数据 | total_rows_available 与 rows_returned | 使用 limit/offset,并提供 total_count、has_more、next_offset(MCP 最佳实践模式) | limit/offset | 无(固定为 20K) |
| 输入验证 | 验证 ISO3、性别、财富、居住地 | 代码表解析工具 + 服务端国家覆盖范围检查(required_country) | Zod 模式 | 无 |
| 错误指引 | error + tip,提供后续步骤 | 结构化的 error_code(例如 http_error:search)+ 消息,以 MCP ToolError 的形式抛出 | HTTP 状态文本 | 原始异常 |
| API 密钥 | 不需要 | 不需要 | 需要 FRED_API_KEY | 不需要 |
| 截断处理 | rows_truncated 标记 + 筛选提示 | 将载荷精简为核心字段,同时保留 claim_id(docs/payload_analysis.md) | 无 | 无 |
| 已发布 | PyPI | PyPI | npm | 否 |
生态概览:官方统计数据 MCP 服务
本项目属于不断壮大的国际和官方统计数据 MCP 服务生态。表格按其封装的数据源对服务分组;状态列说明其维护者,并使用状态标签中定义的标签。
关于这些表格
状态标签
状态说明的是由谁维护服务,而不是服务质量或其数据质量。
- 官方:由数据的生产机构,或运营提供该数据的平台的机构,在该机构的账号下发布,或在该机构的网站上宣布。若该机构有说明,则会标注成熟度限定词:(beta)、(lab)、(pilot)。
- 独立:由该机构的员工以个人身份构建,如 README 或维护者个人资料中所述,且未获该机构认可。本仓库属于此类别。
- 社区:由未声明与数据生产方存在关联的个人或团体构建。
- 商业:由公司作为产品、托管服务或付费服务的一部分提供,且未声明与数据生产方存在关联。
官方指的是服务,而不是数据。目录会单独列出数据并非官方统计的数据服务,例如研究估算;维护自有服务的研究生产方会标记为生产方维护,而非官方。
证据含糊不清时,我们不会声称其具有官方或独立身份:该条目会标记为社区,并说明原因。我们看不到的关联信息,可通过下方的生态更正问题模板补充。
数量与更正
比较表和生态表是某一时点的快照,并非登记册。每项数量(工具、提示词、资源、星标)均指各仓库的公开默认分支上,在最后一次修改该条目的提交日期时可见的内容——目前为 2026-10-24 至 2026-10-27;而生态发展速度远快于此 README。此规则适用于所有服务,包括本服务:除非有公开材料佐证,否则我们不会使用维护者私下提供的数据。
如果你维护其中某个服务,或知道有遗漏或描述不准确的服务,请提交生态更正问题,并附上仓库链接以及需要更改的内容。欢迎提出更正、补充和澄清,我们会在核实后标注日期并予以更新。
2026 年 10 月,世界银行的 Olivier Dupriez 和 Aivin Solatorio 指出,一个社区封装器被标记为世界银行的服务,而官方的 data360-mcp 却被遗漏。之后,我们更正了世界银行相关条目。Aivin 对官方服务的比较构成了上方 data360-mcp 列的依据。感谢两位。这次交流促成了命名规则、状态列以及这些标签定义。
联合国机构
| 服务 | 数据源 | 状态 | 工具 | SDMX | 发布平台 |
|---|---|---|---|---|---|
| unicefstats-mcp(本仓库) | UNICEF 数据仓库 | 独立 | 9 | 是 | PyPI |
| sdmx-mcp | 任意 SDMX 注册库 | 官方(UNICEF DRP,测试版) | 31 | 是 | 否(Docker / Fly) |
| UN System Data Commons | data.un.org — 来自 26 个联合国实体的公开数据(Data Commons 平台,于 2026 年 9 月 17 日上线) | 官方(UN DESA / UNSD) | 2 | 否 | 托管的 MCP 端点 |
| unicef-datawarehouse-mcp | UNICEF 数据仓库 | 社区(由 Tryolabs 构建;未说明 UNICEF 是否参与) | 3 | 是 | 否 |
| faostat-mcp | FAO FAOSTAT | 社区 | 23 | 否 | PyPI |
| uis-mcp-server | UNESCO UIS | 社区 | 5 | 否 | 远程 |
| ilostat-mcp-server | ILO ILOSTAT | 社区 | 9 | 是 | npm |
| who-gho-mcp-server | WHO 全球卫生观察站 | 社区 | 6 | 否 | npm |
| un-comtrade-mcp-server | UN Comtrade | 社区 | 9 | 否 | npm |
| unhcr-opendata-gateway-mcp | UNHCR 开放数据(联邦网关) | 独立(UNHCR 工作人员) | 8 | 否 | 否 |
| mcp_unhcr | UNHCR 难民数据 | 社区 | 5 | 否 | 否 |
| medical-mcp | WHO GHO / FDA / PubMed | 社区 | 18 | 否 | npm |
国际组织
| 服务 | 数据源 | 状态 | 工具 | SDMX | 发布平台 |
|---|---|---|---|---|---|
| data360-mcp | 世界银行 Data360 | 官方(世界银行) | 16 | 否 | PyPI |
| world_bank_mcp_server | 世界银行开放数据 API | 社区 | 1 | 否 | 否 |
| fred-mcp-server | FRED(超过 80 万个序列) | 社区 | 3 | 否 | npm |
| imf-data-mcp | IMF(IFS、BOP、WEO) | 社区 | 5 | 是 | 否(通过 Git 使用 uvx) |
| OECD-MCP | OECD(超过 5,000 个数据集) | 社区 | 9 | 是 | npm |
| eurostat-mcp | Eurostat 欧盟统计数据 | 社区 | 7 | 是 | 否 |
| ecb-mcp | 欧洲中央银行 | 社区 | 8 | 是 | npm |
国家统计局
| 服务 | 数据来源 | 状态 | 工具 | 发布方式 |
|---|---|---|---|---|
| us-census-bureau-data-api-mcp | 美国人口普查局 | 官方 | 5 | 否 |
| esankhyiki-mcp | 印度 MoSPI / NSO | 官方(测试版) | 4 | 否 |
| datagouv-mcp | 法国 data.gouv.fr | 官方(平台运营方) | 10 | 托管 |
| McpDiffusion | 法国 INSEE | 官方(实验室,测试版) | 12 | 托管(测试版) |
| Idescat MCP | 加泰罗尼亚(Idescat) | 官方 | 7 | 托管 |
| us-gov-open-data-mcp | 40+ 个美国政府 API | 社区 | 300+ | npm |
| ibge-br-mcp | 巴西 IBGE(227 项测试) | 社区 | 23 | npm |
| ukrainian-stats-mcp-server | 乌克兰 SDMX v3 | 社区 | 8 | npm |
| istat_mcp_server | 意大利 ISTAT SDMX | 社区 | 8 | 否 |
| mcp-statcan | 加拿大统计局 | 社区 | — | PyPI (uvx) |
| swiss-statistics-mcp | 瑞士 BFS | 社区 | 15 | PyPI (uvx) |
| korea-stats-mcp | 韩国统计厅(KOSIS) | 社区 | — | npm |
| estat-mcp | 日本 e-Stat | 社区 | 4 | PyPI |
已知空缺
社区服务现在已覆盖 UNESCO UIS(自 2026 年 2 月起)、WHO GHO 和 UN Comtrade(自 2026 年 5 月起)以及 ILOSTAT(自 2026 年 8 月起),因此这些不再是尚未覆盖的领域;但它们都不是由相关机构自行维护的。截至 2026-10-26,仍未发现适用于 UNDP/HDI、UNSD SDG Global Database API(UN System Data Commons 端点涵盖了部分 SDG 系列数据)、UN DESA Population、UNAIDS、WFP 或 WTO 的 MCP 服务;BIS 没有专用服务,不过社区聚合器 openecon-data 可以查询它。未发现 Eurostat、IMF、OECD 或任何中央银行提供的官方服务。上表仅列出部分内容;下方目录列出了 92 个官方统计服务,以及研究和其他相关来源与一个长尾列表。
完整目录及安装命令:MCP-DIRECTORY-STATS.md
与 sdmx-mcp 的关系
UNICEF 还维护着通用 SDMX 协议 MCP 服务 sdmx-mcp。这两个服务互为补充,而非相互竞争:
| unicefstats-mcp(本仓库) | sdmx-mcp | |
|---|---|---|
| 范围 | 仅限 UNICEF 儿童发展数据 | 任意 SDMX 注册表(UNICEF、Eurostat、OECD,……) |
| 工具 | 7 个(便于分析师使用的 4 步工作流) | 23 个(面向 SDMX 高级用户,支持结构化查询) |
| 数据层 | 封装 unicefdata Python 包 | 通过 httpx 直接调用 SDMX REST API |
| 输出 | 针对大模型格式化(紧凑表格、摘要、提示) | 原始 SDMX-JSON/CSV |
| 准确率(EQA) | 0.891(v0.7.3 + 修复) | 0.074 |
| 幻觉率 | hall_b 1.00%(mcp060)/ 2.25%(mcp073)——低于无工具时的 hall_a 基准(2.50%) | 0% T1 / 0% T2 |
| 每次查询成本 | ~$0.04 | $0.087 |
| 延迟 | 平均约 10 秒 | 平均 60 秒 |
主要权衡:unicefstats-mcp 的准确率高得多(EQA 为 0.891,对比 0.074),因为其格式化输出针对大模型解析进行了优化。sdmx-mcp 通过积极使用 assistant_guidance 字段和 validate_query_scope 模式,在查询不存在的数据时实现零幻觉;它的准确率下限太低,不具实用价值,但拒绝查询的规范堪称典范。unicefstats-mcp v0.7.3 + 修复首次证明:在查询不存在的数据时,MCP 能让模型比无工具基准更安全(hall_b < hall_a),且无需付出 sdmx-mcp 那样的准确率代价。
如何选择:
- UNICEF 儿童发展分析请使用 unicefstats-mcp——它更简单、更快速,准确率也高得多
- 需要查询非 UNICEF 的 SDMX 注册表、探索数据流结构或处理分层代码表时,请使用 sdmx-mcp
三方完整基准测试(仅大模型 vs unicefstats-mcp vs sdmx-mcp):examples/results/
快速开始
pip install unicefstats-mcp
Claude Code
添加到 ~/.claude/.mcp.json:
{
"mcpServers": {
"unicefstats": {
"command": "unicefstats-mcp"
}
}
}
Cursor / VS Code
添加到 MCP 设置中:
{
"unicefstats": {
"command": "unicefstats-mcp"
}
}
v1.1.0 新增内容
v1.1.0 是增量更新:v1.0.0 的 ambiguity_flag、candidates 和 abstain_instruction 在遇到歧义查询时仍会照常触发。v1.1.0 在此基础上增加了四个建议性封装字段:
requires_confirmation——当服务希望助手暂停并等待用户输入时为 truerecommended——服务建议的下一步操作(代码、国家、年份或工具)assistant_guidance——大模型可以转述的简短自然语言提示next_step——大模型可以接续调用的结构化工具/参数建议
判定顺序(4 个阶段):严格规范查找 → 歧义检查(v1.0.0 字段)→ 确认关卡(requires_confirmation)→ 建议提示(recommended / assistant_guidance / next_step)。
结论:允许(无行为回归;建议字段会在 Sonnet 的 30 个成对卡住查询中触发 23 次,在 Haiku 的 30 个成对卡住查询中触发 26 次;参见 internal/v1.1.0_design/ab_results.md)。
v1.5.x 新增内容(2026 年 6 月)
v1.5.x 系列针对一类长期存在的情况进行了改进:v1.0.0/v1.1.0 的歧义判定触发后,模型仍无法选出正确的指标。6 个版本在 7 天内发布,均在 v1.1.x 的决策顺序上进行增补。
| 版本 | 范围 | 机制 |
|---|---|---|
| v1.5.0 | 减少搜索层面的歧义 | 在启发式 Path B 中添加单数据流保护;在差异化器中累积所有匹配项;分层模糊同义词评分器(data360-mcp 模式);协作式 abstain_instruction(faostat-mcp 模式) |
| v1.5.1 | 修复 Tier 2c 错误路由 | 提高 Jaccard 阈值(70→75);添加子串层长度比保护(≤1.5);添加明确的反义词同义表达(unimproved drinking water → WS_PPL_W-UI);添加明确的限定词同义表达(antenatal care 4+ visits → MNCH_ANC4) |
| v1.5.2 | 主管机构默认值 | CURATED_PREFERRED 条目会根据 SDG 4 主管机构惯例,将教育完成率(ED_CR_L1/L2/L3_UIS_MOD)和失学率(ED_ROFST_L1/L2/L3_UIS_MOD)查询默认指向 UIS 模型估算系列。WASH JMP 核心指标(WS_PPL_W-I、WS_PPL_H-B)以及防止反义词误匹配的 WS_PPL_W-UI 排序保护。每个条目的 dimension_hint 都会明确列出数据仓库中的其他版本 |
| v1.5.3 | 长尾精选指标簇 | PT_F 亲密伴侣暴力(SDG 5.2.1)、18 岁前遭受性暴力(SDG 16.2.3)、MNCH_BIRTH18、PT_CHLD_5-17 童工、ED_ROFST_L02、HVA_PED_LOST(UNAIDS 艾滋病致孤儿童) |
| v1.5.4 | Copilot 驱动的正确性修复 | 从 PT_F 15-49 默认项中移除误导性的 15-19 同义词;重写 HVA_PED_LOST 的 dimension_hint,改为「艾滋病所致合计」(而非「全因」) |
| v1.5.5 | 加强批量使用稳定性(可选启用) | 新增两个环境变量:UNICEFSTATS_SDMX_THROTTLE_MS(调用间延迟)和 UNICEFSTATS_SDMX_RETRY_403=1(遇到 403 时采用 30/60/120 秒指数退避)。普通使用时默认行为不变;建议在大批量处理或基准测试场景中启用 |
实证验证 — v1.5.5 与 v1.2.4 6 月 1 日基线进行的 1484 单元格配对重新验证,在 v9 Arm B 样本上测得平均 EQA 0.749(+29.1 个百分点,p = 2×10⁻¹⁰⁵)(该基准测试与下方的 300 条查询 EQA 测试不同,规模更大)。两个评分表请参阅基准测试结果。
精选主管机构默认策略 — 对于目录中同时提供行政数据系列和主管机构模型估算系列的指标类别(教育采用 UIS,水与卫生设施采用 JMP,营养采用 WHO/UNICEF 联合估算),v1.5.x 会将自然语言查询默认指向模型估算系列或主管机构系列,并在 dimension_hint 中列出其他版本。明确需要原始数据或行政数据的用户可以通过提示信息重新路由;LLM 可以完整查看这两类数据。
工具
| 工具 | 用途 | 是否调用 API? |
|---|---|---|
search_indicators(query, limit) | 按关键词查找指标 | 否 |
list_categories() | 浏览主题类别(CME、NUTRITION、EDUCATION 等) | 否 |
list_countries(region) | 列出带有 ISO3 代码的国家 | 否 |
get_indicator_info(code) | 完整元数据、SDMX 详情、可用的细分维度 | 否 |
lookup_by_code(code) | v1.0.0 严格按规范代码查找(拒绝自然语言输入,并提供弃答指令) | 否 |
get_temporal_coverage(code) | 可用年份范围和国家数量 | 是(轻量调用) |
get_data(indicator, countries, ...) | 获取观测数据,可选细分筛选条件 | 是 |
get_api_reference(language, function) | unicefdata 软件包 API 参考(Python/R/Stata) | 否 |
get_server_metadata() | 服务身份、版本、来源信息、数据来源 | 否 |
工作流
1. search_indicators("child mortality") → find indicator codes
2. get_indicator_info("CME_MRY0T4") → check disaggregations & SDMX details
3. get_temporal_coverage("CME_MRY0T4") → check year range
4. get_data("CME_MRY0T4", ["BRA", "IND"]) → fetch data
5. get_api_reference("python", "unicefData") → get code template to continue in a script
资源
该服务公开了六个 MCP 资源,客户端可加载这些资源以获取指导和参考数据:
| URI | 用途 |
|---|---|
unicef://system-prompt | 推荐的系统提示词——操作循环 + 时间前沿检查 + 防止外推指令(在会话开始时加载) |
unicef://llm-instructions | 完整的必做/禁止规则、常见错误和防伪造指南 |
unicef://context | 运行时上下文——用于时间查询合理性检查的 current_date / current_year |
unicef://categories | 所有指标类别及其数量 |
unicef://countries | ISO3 代码和国家名称 |
unicef://glossary | 分类代码和指标前缀说明 |
system-prompt 和 context 资源用于应对 T2 幻觉失效模式(模型为超出数据前沿的年份编造数值)。采用的模式来自世界银行的 data360-mcp 服务。请参阅 CHANGELOG 中 v0.5.0 的条目。
范围:仅限 UNICEF DW 指标
unicefstats-mcp 搜索并提供 UNICEF Data Warehouse SDMX 目录——其中包含约 790 项关注儿童的指标,涵盖死亡率、营养、教育、儿童保护、WASH、HIV/AIDS、免疫接种和幼儿发展。指标代码遵循 UNICEF 的惯例(例如 CME_MRY0T4、NT_ANT_HAZ_NE2、ED_ANAR_L1)。
其他组织的代码不在支持范围内。 MCP 无法查找、解析或获取这些代码,因为它们不存在于 UNICEF SDMX 目录中。以下是超出支持范围的代码系列示例:
| 来源组织 | 前缀示例 | 典型内容 |
|---|---|---|
| 世界银行 WDI | SI.POV.DDAY、NY.GDP.PCAP.PP.KD、SE.PRM.NENR | 贫困、GDP、更广泛的教育数据 |
| 世界银行 ASPIRE | per_allsp.cov_pop_tot、per_* | 社会保护覆盖率 |
| ILO / ILOSTAT | EIP_*、EAP_*、DF_*_SEX_RT | 劳动力、就业、NEET |
| UNESCO UIS | UIS.* | 教育经费、学习成果 |
这些代码会使 search_indicators 无法返回任何结果,并使 get_data 返回未找到错误。拒绝处理是正确行为,并非错误。
对于跨组织查询,请使用配套 MCP:
data360-mcp— 世界银行为其 Data360 平台提供的官方服务,通过统一的工具界面涵盖 WDI、ILO、UN 及其他官方数据提供方。world_bank_mcp_server— 社区封装工具(anshumax),仅封装世界银行开放数据 API;并非世界银行产品。
对于针对任意注册机构(Eurostat、OECD、各国 NSO)的 SDMX 高级用户查询,请参阅 sdmx-mcp——通用 SDMX 协议服务,详见与 sdmx-mcp 的关系。
在 v9 边缘测试样本发现三个提示词的真实代码(SI.POV.DDAY、NY.GDP.PCAP.PP.KD、per_allsp.cov_pop_tot)属于世界银行体系而非 UNICEF Data Warehouse 后,v1.1.1 进一步明确了范围边界。完整说明见 internal/v1.1.0_design/ambiguity_forensic.md 第 C-4 至 C-6 节(仅限开发仓库)。
理解 UNICEF 指标代码
为何这很重要——MCP 的语义层
UNICEF SDMX 指标代码乍看晦涩难懂——PT_F_20-24_MRD_U18、
NT_ANT_HAZ_NE2、TRGT_2030_IM_DTP3——大模型在处理这些数据时,大多数失败都始于选错代码。与原始 SDMX 端点相比,这个 MCP 提供的最大价值在于揭示这些代码内部的语义结构,让助手无需猜测即可消除歧义。相关实现位于 src/unicefstats_mcp/differentiator.py(片段级后缀含义,以及基础代码与变体的说明)和
src/unicefstats_mcp/indicator_resolver.py(自然语言同义词和已知的歧义词元)。v1.1.1 新增了一个能根据查询调整的 CURATED_PREFERRED dimension_hint,用于告知解析器在特定措辞下应优先呈现某个指标系列中的哪个代码(例如,“target” → TRGT_*,“modelled” → *_MOD,“child” → _T 总计,而非按性别细分的变体)。
本节介绍 MCP 所依据的惯例,帮助用户和下游 Agent 直接解读代码,也便于审核者审查解析器的选择。
UNICEF 代码的结构
UNICEF DW 代码由不含句点、以下划线分隔的片段串联而成,应从左到右按范围由宽到窄依次读取。以目录中的一项分层保护指标为例:
PT_F_20-24_MRD_U18
│ │ │ │ │
│ │ │ │ └── Marriage cutoff: U18 = first union before age 18 (SDG 5.3.1)
│ │ │ └────── Indicator class: MRD = ever-married / in-union
│ │ └──────────── Age band (cohort): 20-24 = women 20-24 (retrospective denominator)
│ └────────────── Population restriction: F = female-only indicator (women/girls)
└───────────────── Family prefix: PT = Child Protection
读出来是:“儿童保护 / 女性受访者 / 年龄为 20-24 岁的群体 / 曾婚 / 未满 18 岁时”——也就是 20-24 岁女性中 18 岁前初婚的比例。注意,这里的 F 并非附加在性别中立父级代码后的性别细分后缀;它是构建在一组仅适用于女性受访者的指标系列中的人群限定标记(FGM、童婚、女性贫血、产前保健)。请参阅下文“人群限定与性别细分”。
营养人体测量模式也适用相同的从左到右读取方式:
NT_ANT_HAZ_NE2
│ │ │ │
│ │ │ └── Threshold: NE2 = below -2 SD (NE = "negative end", 2 = SD count)
│ │ └────── Metric: HAZ = Height-for-Age Z-score
│ └────────── Sub-family: ANT = Anthropometry
└───────────── Family: NT = Nutrition
NT_ANT_HAZ_NE2 是 5 岁以下儿童发育迟缓患病率指标。若要获取按性别分层的数值,请使用 SEX 维度筛选器查询该指标(get_data(indicator='NT_ANT_HAZ_NE2', sex='F')),而不是在代码后追加 _F——请参阅下一小节。
还有派生指标模式,这是 v1.1.1 中能根据查询调整的评分机制专门针对的模式:
TRGT_2030_IM_DTP3
│ │ │ │
│ │ │ └──── Antigen / dose: DTP3 = third dose of DTP
│ │ └─────── Family: IM = Immunization
│ └──────────── Target year: 2030 = SDG horizon
└───────────────── Derived metric: TRGT = country-set target value
组合式解读——系列 → 子系列 → 指标 → 阈值/年龄段 → 细分词元——是目录中几乎所有代码背后不成文的约定。下表将逐一列出这些组成部分。
主题前缀(类别)
第一个部分表示主题类别。目录中排名前 10–12 的前缀涵盖了绝大多数儿童相关指标:
| 前缀 | 含义 | 示例代码 |
|---|---|---|
CME | 儿童死亡率估算——按年龄段划分的死亡率(新生儿、婴儿、5 岁以下儿童、儿童、死产) | CME_MRY0T4(5 岁以下儿童死亡率)、CME_SBR(死产率) |
NT | 营养——人体测量、贫血、出生体重、微量营养素 | NT_ANT_HAZ_NE2(发育迟缓)、NT_BW_LBW(低出生体重) |
ED | 教育——按 ISCED 等级划分的完成率、识字率、出勤率 | ED_CR_L1(初等教育完成率)、ED_15-24_LR(青年识字率) |
WS | WASH——水、环境卫生、个人卫生;人口层面的服务覆盖情况 | WS_PPL_W-SM(安全管理饮用水) |
IM | 免疫接种——按抗原/剂次划分的疫苗覆盖率 | IM_BCG、IM_DTP3、IM_MCV1 |
MNCH | 孕产妇、新生儿与儿童健康——产前保健、熟练接生、过早生育 | MNCH_ANC1、MNCH_SAB、MNCH_BIRTH18 |
ECD | 儿童早期发展——学习材料、父母提供的启蒙活动、出勤情况 | ECD_CHLD_LMPSL(学习材料) |
PT | 儿童保护——女性生殖器切割、童婚、暴力管教 | PT_F_20-24_MRD_U18(18 岁前结婚) |
HVA | HIV/AIDS——抗逆转录病毒治疗覆盖率、流行率、青少年指标 | HVA_ADOL_ART_RECEIVE |
PV | 儿童贫困——货币贫困与多维贫困 | PV 类别 |
COD | 死因——特定疾病和病症的死亡率/发病率 | COD_ACUTE_HEPATITIS_A |
DM | 人口统计——家庭构成、人口结构 | DM_HH_U18(有成员未满 18 岁的家庭) |
MG | 移民——儿童移民、流离失所 | MG 类别 |
GN | 性别/青少年女孩(通常与 NT 交叉) | GN_ANEMIA_ADOL_GRL |
TRGT | 国家集合目标(见下文“派生指标”) | TRGT_2030_* |
HAZARD | 灾害暴露(气候、冲突、灾难) | HAZARD 类别 |
自然语言短语与这些前缀的完整映射位于
indicator_resolver._SYNONYMS 中——例如,“发育迟缓” → NT_ANT_HAZ_NE2,“童婚” →
PT_F_20-24_MRD_U18,“BCG” → IM_BCG。
方法与来源后缀
末尾部分通常表示数值的生成方式,而非测量内容。这些后缀是 v1.1.1 查询感知评分的关键,因为用户几乎总是只需要“调查数据”或“模型估算”,很少两者都需要。
| 后缀 | 含义 | 示例代码 |
|---|---|---|
_MOD | 模型估算(联合估算组的输出,例如教育领域的 UIS、死亡率领域的 IGME) | ED_CR_L1_UIS_MOD(模型估算的初等教育完成率) |
_MERGE | 将多个来源调查/年份的数据合并为单个可比较序列 | ECD_CHLD_LMPSL_MERGE |
_PRXY | 代理指标——用相关变量代替概念上精确的指标 | ECD_CHLD_LMPSL_PRXY |
_NEW | 新/修订的方法序列(通常会与旧版序列并行一个周期) | *_NEW |
_NUMTH | 分子/阈值变体——某些机构采用的替代口径 | *_NUMTH |
_AGG | 汇总值(地区或收入组汇总,而非国家观测值) | *_AGG |
_UIS | 联合国教科文组织统计研究所来源/方法 | ED_CR_L1_UIS_MOD |
MCP 的 differentiator.py:_SUFFIX_MEANINGS 表是规范来源。
如果两个代码仅末尾部分不同,explain_difference() 会将其报告为基础项与变体(例如,以 ECD_CHLD_LMPSL 为基础项,_MERGE
和 _PRXY 为推导变体)。
人口限制与性别细分
这种区别很容易被忽略,也经常让下游 Agent 出错。
人口限制(内置于代码)。 一些 UNICEF 指标只适用于一种性别,因为其底层测量只针对一种性别:FGM 流行率、童婚队列、育龄妇女贫血、产前保健覆盖率。在这些指标系列中,代码开头附近的 F 段(PT_F_*、NT_ANE_WOM_*、MNCH_BIRTH18、产前保健代码)是指标身份的一部分,属于人口限制标记。童婚指标没有对应的 PT_M_20-24_MRD_U18;该指标以女性受访者为统计对象。这里的 F 是指标名称的一部分,而不是细分开关。
性别细分(查询时应用 SEX 维度筛选)。 对于适用于两种性别的指标(5 岁以下儿童死亡率、小学教育完成率、发育迟缓率、识字率),性别不会编码在代码中,而是一个独立的 SDMX 维度,即 SEX 维度,其值为 F、M、_T(总计)。查询时可选择一个切片:
get_data(indicator='CME_MRY0T4', sex='F') # under-5 mortality, girls
get_data(indicator='CME_MRY0T4', sex='M') # under-5 mortality, boys
get_data(indicator='CME_MRY0T4', sex='_T') # under-5 mortality, total
differentiator.py:_SUFFIX_MEANINGS 表将 F、M、_T、MF 列为性别标记含义;这些条目描述的是 SEX 维度的取值,而不是可追加到任意代码的后缀。给原本不包含 _F 的代码追加 _F(例如臆造 NT_ANT_HAZ_NE2_F)将无法解析,因为目录中没有此类代码。
年龄/财富/居住地细分标记
细分标记可能嵌入代码中(当它们属于规范定义的一部分时,例如 PT_F_20-24_MRD_U18),也可能通过 get_data() 筛选器在查询时应用。以下标记在这两种情况下相同。
年龄段
嵌入代码时,年龄按 LOW-HIGH 格式编码(含两端);也可以在代码末尾使用界限标记。
| 标记 | 含义 |
|---|---|
15-19、20-24、15-49 | 含两端的年龄段(年) |
Y0 | 不满 1 岁(新生儿/婴儿变体) |
Y0T4 | 0 至 4 岁,含两端(不满 5 岁) |
Y1T4 | 1 至 4 岁,含两端(儿童期,婴儿期之后) |
U5、U15、U18 | “不满”界限——严格低于指定年龄 |
ADOL | 青少年(10–19 岁,偶尔为 10–24 岁) |
财富五分位数(查询时筛选)
| 标记 | 含义 |
|---|---|
Q1 | 最低五分位数(最贫困的 20%) |
Q2、Q3、Q4 | 中间五分位数 |
Q5 | 最高五分位数(最富裕的 20%) |
B20 / B40 | 最低 20% / 最低 40% |
T20 | 最高 20% |
居住地(查询时筛选)
| 标记 | 含义 |
|---|---|
_T | 总计 |
U | 城市 |
R | 农村 |
人体测量 Z 分数阈值
这些标记出现在 NT_ANT_* 系列中。由于其约定不太直观,需要单独列表说明:
| 标记 | 含义 |
|---|---|
NE2 | 低于 -2 SD(“负向界限,2 SD”)——中度或重度形式 |
NE3 | 低于 -3 SD——重度形式 |
NE2_T_NE3 | 介于 -3 SD 与 -2 SD 之间——仅中度形式 |
PO2 | 高于 +2 SD——超重一侧 |
HAZ / WAZ / WHZ / BAZ | 年龄别身高/年龄别体重/身高别体重/年龄别 BMI 的 Z 分数 |
派生指标:TRGT_ / _ARR_ / _PRJ
三种特殊语法用于标记并非观测值、而是由观测值转换得出的数值。这些场景最能体现 v1.1.1 的查询感知型 CURATED_PREFERRED 评分的重要性。请注意,ARR 是中间段标记(例如 CME_ARR_U5MR、CME_ARR_SBR),而不是末尾后缀。
| 模式 | 含义 | 示例 |
|---|---|---|
TRGT_<year>_<indicator> | 指定指标在指定目标年份的国家目标值。TRGT_2030_IM_DTP3 是该国 2030 年的 DTP3 覆盖率目标,而非观测值。 | TRGT_2030_IM_DTP3 |
*_ARR_* | 年均降幅 — 根据底层序列推导出的年化百分比变化;作为中间段标记出现 | CME_ARR_U5MR、CME_ARR_SBR |
*_PRJ / *_PRJ_* | 预测值/预报值,而非观测值 | PT_F_20-24_MRD_U15_PRJ |
v1.1.1 查询感知型评分(提交 7112e1d):只有当自然语言查询中提到 target、goal、objective 或目标年份时,MCP 才会展示 TRGT_* 代码。单纯询问“巴西的 DTP3 覆盖率”会解析到观测序列;询问“巴西 2030 年的 DTP3 目标”则会解析到 TRGT_2030_IM_DTP3。此功能通过 differentiator.py 中 CURATED_PREFERRED 条目的提示字段实现,而非硬性排除 — 仍可通过直接查询找到目标代码,只是在查询未表明相关意图时,它在解析器排名中的优先级会降低。
同样的查询感知型降级也适用于 _MOD(建模)变体:查询中提到 survey、raw 或 observed 时,优先选择无后缀代码;提到 modelled、estimate 或 joint estimation 时,优先选择 _MOD。
教育阶段
在 ED_* 系列中,ISCED 阶段缩写为 L1 / L2 / L3:
| 标记 | ISCED 阶段 | 常用名称 |
|---|---|---|
L1 | ISCED 1 | 小学教育 |
L2 | ISCED 2 | 初中教育 |
L3 | ISCED 3 | 高中教育 |
例如:ED_ANAR_L1(调整后净入学率,小学)、ED_ANAR_L2
(初中)、ED_CR_L1(完成率,小学)。代码以 L1 结尾时,仅适用于小学;同时报告两个阶段时,会分别列出对应代码,而非将其拼接在一起。
范围说明。 L<n> = ISCED <n> 的对应关系仅适用于 ED_* 系列。在 ED_* 系列之外,L<n> 可能表示非 ISCED 阶段 — 例如,PV_CHLD_MPI_L1 和 PV_CHLD_MPI_L2 中的 L1 / L2 分别表示严重和中度多维贫困剥夺。部分 ED_* 代码也使用两位数形式 L01 / L02,表示低于 ISCED 1 的幼儿期或学前阶段。假定 L<n> 表示小学/初中/高中阶段之前,务必先查看指标名称。
在 MCP 中的编码位置
上文记录的约定并非传闻,而是编码在 MCP 源代码中,可直接审查:
src/unicefstats_mcp/differentiator.py是细分层级含义的权威参考。_SUFFIX_MEANINGS表将每个已识别的尾部标记映射为易懂的释义;explain_difference()并排遍历两个代码,并标注每个不同的细分层级;CURATED_PREFERRED表包含各指标的dimension_hint字符串,用于驱动 v1.1.1 中面向查询的评分。src/unicefstats_mcp/indicator_resolver.py将自然语言短语映射到规范代码。_SYNONYMS涵盖常见情况(“stunting”“under-5 mortality”“child marriage”);_AMBIGUOUS标记可能合理地映射到多个代码、需要用户消歧的短语;_DISAMBIGUATION_TIPS保存简短提示,这些提示会显示在 v1.1.0 中新增的assistant_guidance信封字段中。unicef://glossaryMCP 资源——在会话开始时加载资源的客户端,无需解析此 README,即可获取细分代码和指标前缀图例。
解析器选定代码时,流程如下:自然语言查询 → indicator_resolver 查找 → 如果存在歧义,则触发 _AMBIGUOUS 命中,并返回 v1.0.0 的 ambiguity_flag 和候选列表 → 如果匹配到 CURATED_PREFERRED 条目,则由 dimension_hint 对候选项重新排序 → 最后由 differentiator.py 为所选代码添加注释,填入 assistant_guidance 字段。每个步骤都可在源代码中审查;本节没有任何内容依赖 LLM 端的启发式方法。
演示
步骤 1:搜索指标
>>> search_indicators("stunting", limit=3)
{
"query": "stunting",
"total_matches": 11,
"showing": 3,
"results": [
{"code": "FD_STUNTING", "name": "Moderate and severe stunting (Functional difficulties)"},
{"code": "NT_ANT_HAZ_NE2", "name": "Height-for-age <-2 SD (stunting)"},
{"code": "NT_ANT_HAZ_NE3", "name": "Height-for-age <-3 SD (severe stunting)"}
],
"tip": "Use get_indicator_info('FD_STUNTING') for full details including available disaggregations."
}
步骤 2:获取指标元数据
>>> get_indicator_info("CME_MRY0T4")
{
"code": "CME_MRY0T4",
"name": "Under-five mortality rate",
"description": "Probability of dying between birth and exactly 5 years of age, expressed per 1,000 live births",
"dataflow": "GLOBAL_DATAFLOW",
"sdmx_api": "https://sdmx.data.unicef.org/ws/public/sdmxapi/rest/data/UNICEF,GLOBAL_DATAFLOW,1.0/.CME_MRY0T4?format=csv",
"disaggregation_filters": {
"sex": ["_T (Total)", "M (Male)", "F (Female)"],
"wealth_quintile": ["Q1 (Lowest)", "Q2", "Q3", "Q4", "Q5 (Highest)"],
"residence": ["_T (Total)", "U (Urban)", "R (Rural)"]
}
}
步骤 3:检查时间覆盖范围
>>> get_temporal_coverage("CME_MRY0T4")
{
"code": "CME_MRY0T4",
"start_year": 1931,
"end_year": 2024,
"latest_year": 2024,
"countries_with_data": 249,
"note": "Not all countries have data for all years. Coverage varies by country."
}
步骤 4:获取数据
>>> get_data("CME_MRY0T4", ["BRA", "IND", "NGA"], start_year=2018, end_year=2023)
{
"indicator": "CME_MRY0T4",
"countries_requested": ["BRA", "IND", "NGA"],
"total_rows_available": 18,
"rows_returned": 18,
"rows_truncated": false,
"format": "compact",
"summary": {
"value_range": {"min": 14.42, "max": 117.56, "mean": 54.78},
"year_range": {"earliest": 2018, "latest": 2023},
"countries_in_result": 3
},
"data": [
{"iso3": "BRA", "country": "Brazil", "period": 2018, "indicator": "CME_MRY0T4", "value": 15.22},
{"iso3": "BRA", "country": "Brazil", "period": 2019, "indicator": "CME_MRY0T4", "value": 15.03},
{"iso3": "BRA", "country": "Brazil", "period": 2020, "indicator": "CME_MRY0T4", "value": 14.87},
{"iso3": "BRA", "country": "Brazil", "period": 2021, "indicator": "CME_MRY0T4", "value": 14.72},
{"iso3": "BRA", "country": "Brazil", "period": 2022, "indicator": "CME_MRY0T4", "value": 14.59},
{"iso3": "BRA", "country": "Brazil", "period": 2023, "indicator": "CME_MRY0T4", "value": 14.42},
{"iso3": "IND", "country": "India", "period": 2018, "indicator": "CME_MRY0T4", "value": 36.87},
{"iso3": "IND", "country": "India", "period": 2019, "indicator": "CME_MRY0T4", "value": 34.86},
{"iso3": "IND", "country": "India", "period": 2020, "indicator": "CME_MRY0T4", "value": 32.98},
{"iso3": "IND", "country": "India", "period": 2021, "indicator": "CME_MRY0T4", "value": 31.19},
{"iso3": "IND", "country": "India", "period": 2022, "indicator": "CME_MRY0T4", "value": 29.53},
{"iso3": "IND", "country": "India", "period": 2023, "indicator": "CME_MRY0T4", "value": 27.99},
{"iso3": "NGA", "country": "Nigeria", "period": 2018, "indicator": "CME_MRY0T4", "value": 117.19},
{"iso3": "NGA", "country": "Nigeria", "period": 2019, "indicator": "CME_MRY0T4", "value": 117.37},
{"iso3": "NGA", "country": "Nigeria", "period": 2020, "indicator": "CME_MRY0T4", "value": 117.42},
{"iso3": "NGA", "country": "Nigeria", "period": 2021, "indicator": "CME_MRY0T4", "value": 117.56},
{"iso3": "NGA", "country": "Nigeria", "period": 2022, "indicator": "CME_MRY0T4", "value": 117.46},
{"iso3": "NGA", "country": "Nigeria", "period": 2023, "indicator": "CME_MRY0T4", "value": 116.82}
]
}
AI 助手会从中提取的关键洞见:
- 巴西:每 1,000 人中有 14.4 人——稳步下降,有望达到 SDG 3.2 目标(≤25)
- 印度:每 1,000 人中有 28.0 人——快速改善(5 年内从 37 降至 28),近期已达到 SDG 目标
- 尼日利亚:每 1,000 人中有 117 人——基本持平,是 SDG 目标的 4.7 倍,负担最高
步骤 5:获取代码模板,以便在脚本中继续操作
>>> get_api_reference("r", "unicefData")
{
"language": "r",
"install": "install.packages(\"unicefdata\")",
"import": "library(unicefdata)",
"function": "unicefData",
"signature": "unicefData(\n indicator = NULL, # character — indicator code(s)\n countries = NULL, # character vector — ISO3 codes, NULL = all\n year = NULL, # numeric, character (\"2015:2023\"), or vector\n sex = \"_T\", # character — \"_T\", \"M\", \"F\"\n totals = FALSE, # logical — only return aggregate totals\n tidy = TRUE, # logical — standardize column names\n country_names = TRUE, # logical — add country name column\n format = \"long\", # character — \"long\", \"wide\", \"wide_indicators\"\n latest = FALSE, # logical — most recent value per country\n circa = FALSE, # logical — closest available year\n add_metadata = NULL, # character vector — e.g. c('region', 'income_group')\n dropna = FALSE, # logical — drop rows with missing values\n simplify = FALSE, # logical — minimal columns\n mrv = NULL, # integer — most recent N values per country\n raw = FALSE, # logical — all disaggregations, no filtering\n)",
"returns": "tibble with columns: indicator_code, iso3, country, period, value, sex, age, wealth_quintile, residence, ...",
"examples": [
{"description": "Under-5 mortality for Brazil, India, Nigeria (2015–2023)", "code": "df <- unicefData(\"CME_MRY0T4\", countries = c(\"BRA\", \"IND\", \"NGA\"), year = \"2015:2023\")"},
{"description": "Latest stunting data for all countries", "code": "df <- unicefData(\"NT_ANT_HAZ_NE2\", latest = TRUE)"},
{"description": "Wide format with region metadata", "code": "df <- unicefData(\"CME_MRY0T4\", format = \"wide\", add_metadata = c(\"region\", \"income_group\"))"}
]
}
这样,AI 就能使用准确的参数名称和语法生成正确的 R/Python/Stata 代码,无需根据训练数据猜测。
get_data 参数
| 参数 | 类型 | 默认值 | 描述 |
|---|---|---|---|
indicator | str | 必填 | 指标代码 |
countries | list[str] | 必填 | ISO3 代码(最多 30 个) |
start_year | int | None | 年份范围的起始年份 |
end_year | int | None | 年份范围的结束年份 |
sex | str | "_T" | "_T"(总计)、"M"(男性)、"F"(女性) |
wealth_quintile | str | None | "Q1"–"Q5"、"B20"、"B40"、"T20" |
residence | str | None | "U"(城市)、"R"(农村)、"_T"(总计) |
format | str | "compact" | "compact"(5 列)或 "full"(所有列) |
limit | int | 200 | 最大行数(1–500) |
响应特性
summary:数值范围(最小值/最大值/平均值)、年份范围、国家数量disaggregations_in_data:具有非平凡变化的维度total_rows_available与rows_returned:分页元数据tip:针对下一步操作或缩小结果范围的情境化指导
提示词
compare_indicators
预构建的分析工作流:获取指标元数据和数据,然后生成结构化对比。
compare_indicators(indicator="CME_MRY0T4", countries="BRA,IND,NGA", start_year="2015", end_year="2023")
write_unicefdata_code
使用 unicefdata 包生成可运行的 Python、R 或 Stata 代码。AI 会调用 get_api_reference() 获取准确的函数签名,然后编写符合用户任务需求的代码。
write_unicefdata_code(
task="Compare under-5 mortality for Brazil and India, 2015-2023, then plot the trends",
language="r"
)
这弥合了对话式探索(通过 MCP 工具)与可复现分析脚本(通过 unicefdata 包)之间的差距。
基准测试结果
我们使用 EQA 指标(Azevedo,2025)对 MCP 与裸大模型(Claude Sonnet 4,不使用工具)进行了基准测试。测试包含 300 个查询,覆盖 10 项指标、20 个国家、2 种提示词类型和 2 类幻觉测试。
基准测试的两大支柱
此代码库维护两份实证记分榜:
- 300 个查询的 EQA 测试(10 项指标 × 20 个国家 × 2 种提示词 × 2 类幻觉)——原始的 Azevedo(2025)基准测试,应用于 v1.0.x / v1.1.x。下方标注为“v0.7.3 + 修复”。
- v9 Arm B 1484 单元配对基准测试——规模更大、粒度更细,在 v1.5.x 精选默认值周期中引入。逐单元对比每个 MCP 版本与 v1.2.4 Jun 1 基线。v1.5.5 测得 EQA 均值为 0.749(+29.1 个百分点,p = 2×10⁻¹⁰⁵)。
两者使用不同样本和不同评分规则,因此相辅相成,不能直接比较。
当前规范数据——300 个查询的 EQA 测试(v0.7.3 + 修复,2026 年 5 月)
以下为当前规范记分榜。这些结果反映了 (a) v0.7.3 周期中的四项工程修复(参见 CHANGELOG),以及 (b) v1.4 提取器进行的评分修正,该修正会考虑拒绝措辞。两个样本(mcp060:40 个国家;mcp073:不重叠的 20 个国家验证样本)均按相同的 v1.4 规则评分。
| 指标 | 仅使用大模型(不使用工具) | 大模型 + MCP(v0.7.3 + 修复) | 样本 |
|---|---|---|---|
| POS EQA 均值 | 0.121 | 0.891 | mcp060(40 个国家) |
| POS EQA 均值 | 0.121 | 0.909 | mcp073(不重叠的 20 个国家) |
| hall_b 合计(T1+T2) | 2.50%(hall_a) | 1.00% | mcp060 |
| hall_b 合计(T1+T2) | 2.50%(hall_a) | 2.25% | mcp073 |
| MCP 是否提升模型安全性(hall_b < hall_a) | — | 是——两个样本均如此 | 两者 |
v0.7.3 + 修复是首个经证明确实能在数据缺失查询中,让 MCP 比不使用工具的基线更安全的版本。 在 v0.7.2 及之前的版本中,hall_b ≥ hall_a——安全层降低了幻觉的程度,却未改变其方向。以下四项修复扭转了这一结果:
server.py:_seed_data_frontier_cache——使用单调最大值而非无条件覆盖(探测导致缓存的前沿值回退,从而让大模型误以为当前数据不可用)。server.py:get_data异常处理器——将unicefdata级联耗尽重新归类为no_data(而非error),使大模型将其视为权威的缺失数据结果,而不是工具故障。benchmark_eqa_batch.py——将工具的result_str持久化到state.tool_calls,使 v1.4 提取器能够识别拒绝内容。benchmark_eqa_batch.py——使拒绝处理与同步运行器保持一致。
规范记分榜:请参阅 CHANGELOG.md 顶部的 [Unreleased] §Fixed 部分,其中包含完整的跨版本对照表,以及四项修复后的修正和 mcp073 第二样本验证。每次运行的完整说明位于开发代码库(jpazvd/unicefstats-mcp-dev,仅供开发使用,且不会同步到此公开镜像)的 internal/v0_7_3_validation.md 和 internal/v0_7_3_second_sample_validation.md 中。
历史数据:v0.3.0(n=600,2025)和 v0.7.2(同日 n=500,2026-05-08)
原始 v0.3.0 基准测试报告的 POS EQA 从 0.147 升至 0.990(6.7×),T2 幻觉率从 11% 升至 37%。此后有两项修正:
- “37%”这一醒目数据在很大程度上是 v1.3 提取器的评分伪差:提取器把回复中提到的任何数值都算作“声明”,包括在明确拒绝中引用
no_data工具结果里的数值。v1.4 提取器(_detect_refusal)会将这些重新归类为恰当的拒绝。我们没有使用 v1.4 重新评分 v0.3.0 的 parquet 文件(它们已归档);“37%”对应的 v1.4 等效数据未知,但要低得多。 - v0.7.2 复现测试(n=500,2026-05-08)采用 v1.3 评分,报告的 POS EQA 为 0.897,T1+T2 合计幻觉率为 13%。使用 v1.4 评分时,同一批 parquet 文件的 POS EQA 为 0.793,hall_b 为 3.75%。
准确率提升约 7 倍这一醒目数据在每次重新评分中都经得起检验。要让 MCP 真正将幻觉率降至无工具基线以下,幻觉率这一醒目数据则需要同时进行评分修正(v1.4 提取器)和服务端修正(v0.7.3 缓存与级联修复)。
EQA 分解(baseline_latest 提示词)
| 组成部分 | 仅 LLM | LLM + MCP | 提升 |
|---|---|---|---|
| ER(提取率) | 0.50 | 1.00 | +0.50 |
| YA(年份准确率) | 0.24 | 0.99 | +0.75 |
| VA(数值准确率) | 0.37 | 1.00 | +0.63 |
| EQA = ER × YA × VA | 0.147 | 0.990 | +0.843 |
主要发现
-
使用 MCP 时,全部 10 项指标的 EQA 均 >= 0.95,并在 40 个国家/地区重复验证(R1 + R2,零重叠)。其中 10 项有 7 项的 EQA 达到完美的 1.000。
-
年份准确率是纯 LLM 最大的弱项(YA = 0.24)。当 IGME 已有 2024 年估算值时,它仍会将 2021-2022 年称为“最新”。MCP 会查询 API 并返回实际的最新年份。
-
直接提示词显示 MCP 带来的提升更大(+0.722 对比 +0.613),因为它消除了 YA 的影响,单独衡量纯检索准确率。
-
T2 幻觉率(约 37%)被真实值误分类所抬高:SDMX API 中有微型国家的 IGME 死亡率数据,但真实值处理流程遗漏了这些数据。修正后:MCP 约为 10%,仅 LLM 约为 5%。剩余幻觉由置信度效应驱动——当 Claude 对领域先验有较强信心时,会推翻工具错误。
-
置信度效应:当 MCP 工具返回“无数据”,而 LLM 对领域先验(例如知名国家的儿童死亡率)有较强信心时,它会推翻工具结果,仍然编造答案。这是 LLM 的固有行为,并非 MCP 特有。
三方对比(与 sdmx-mcp 对比)
| 指标 | 仅 LLM | unicefstats-mcp(v0.7.3 + 修复) | sdmx-mcp |
|---|---|---|---|
| EQA(POS) | 0.121 | 0.891 | 0.074 |
| hall_b 合计(T1+T2) | hall_a 2.50% | 1.00%(mcp060)/ 2.25%(mcp073) | 0% |
| MCP 是否比不使用工具更安全? | — | 是 | 是(通过设计实现零幻觉) |
| 每次查询成本 | ~$0.003 | ~$0.04 | $0.087 |
| 平均延迟 | ~5s | ~10s | 60s |
sdmx-mcp 的原始 SDMX-JSON 输出难以供 LLM 解析(VA ≈ 0.11),但其防幻觉护栏效果显著(0% 编造)。详情请参阅与 sdmx-mcp 的关系。
v9 Arm B 配对基准测试(1484 个单元格,2026 年 6 月)
v1.5.x 周期引入了第二个规模更大的基准测试——v9 Arm B,包含 1484 个单元格,master_seed=42,逐单元格将每个 MCP 版本与固定的 v1.2.4 基线进行比较。与 300 个查询的 EQA 测试(评估指标、年份和值的提取质量)不同,v9 Arm B 衡量的是配对 ΔEQA,因此可以单独评估每个版本变更的贡献。
| 版本 | 日期 | 平均 EQA | Δ(相较于 v1.2.4) | p 值 |
|---|---|---|---|---|
| v1.2.4 | 2026 年 6 月 1 日 | 0.458 | — | — |
| v1.4.0 | 2026 年 6 月 4 日 | 0.481 | +2.3pp | 0.0003 |
| v1.5.1 | 2026 年 6 月 6 日 | 0.681 | +22.3pp | 7×10⁻⁷⁶ |
| v1.5.5 | 2026 年 6 月 7 日 | 0.749 | +29.1pp | 2×10⁻¹⁰⁵ |
- v1.5.5 的 5 项决策规则门槛中有 4 项通过
- 430 个 FIRE_RECOVERABLE 单元格的 EQA 均提升 +0.97
- 丢失:挽回比例为 0.03(v1.4.0 为 0.41)
- 可归因于级联的 FIRE_ALTERED 提升:+0.80 [+0.77, +0.83]
此基准测试验证了 +29.1pp 的说法。上文的 300 个查询 EQA 测试仍然适用,并继续作为衡量幻觉率的权威参考。
完整分析、按指标分解及方法说明:examples/RESULTS.md
基准测试数据(包含完整大模型响应的 parquet 文件):examples/results/
基准测试设计原理:examples/DESIGN_ISSUES.md
重现基准测试
# Build ground truth from UNICEF SDMX API
python examples/00_build_ground_truth.py
# Run 200-query benchmark (requires ANTHROPIC_API_KEY, ~$6)
python examples/benchmark_eqa.py
# Add 100 direct-prompt queries to existing run (~$3)
python examples/01_run_direct_supplement.py
引用
此基准测试使用了以下文献中的 EQA 指标:
Azevedo, J.P. (2025). “AI Reliability for Official Statistics: Benchmarking Large Language Models with the UNICEF Data Warehouse.” UNICEF Chief Statistician Office. github.com/jpazvd/unicef-sdg-llm-benchmark-dev
部署
本地(stdio)
unicefstats-mcp
远程(SSE)
unicefstats-mcp --transport sse --port 8000
Docker
docker build -t unicefstats-mcp .
docker run -p 8000:8000 unicefstats-mcp
环境变量
MCP 无需任何必需配置即可运行。两个可选环境变量(v1.5.5+)有助于大批量任务/基准测试应对 UNICEF SDMX 的 WAF/按 IP 限速器:
| 变量 | 默认值 | 设置后的效果 |
|---|---|---|
UNICEFSTATS_SDMX_THROTTLE_MS | 0(关闭) | 此进程中 SDMX unicefData() 调用之间的最小间隔(毫秒)。批量使用时建议设为 200–500,使请求速率低于根据经验观察到的 WAF 触发阈值(约 50–100 次调用/分钟)。 |
UNICEFSTATS_SDMX_RETRY_403 | 未设置 | 设置为 1 / true / yes / on 时,对 SDMXForbiddenError(HTTP 403)进行指数退避重试(30 秒、60 秒、120 秒;最多重试 3 次),而不是立即失败。这有助于长时间运行的批量任务应对短暂的 WAF 请求突增。 |
对于正常的交互式 MCP 服务使用(通过 Claude / Cursor / 等执行单次查询对话任务),请保持两者未设置——默认值会保留快速失败行为。
对于基准测试/批量使用(来自同一 IP 的 1000 次以上连续查询):
export UNICEFSTATS_SDMX_THROTTLE_MS=300
export UNICEFSTATS_SDMX_RETRY_403=1
开发
pip install -e ".[dev]"
pytest tests/ -v
ruff check src/ tests/
mypy src/unicefstats_mcp/
贡献
欢迎贡献。
贡献方式
- 错误报告:提交 issue,并附上复现步骤
- 功能请求:通过 issue 提出新的工具、指标或输出格式
- 代码:Fork 项目、创建分支并提交 PR——请参阅下方的开发环境设置
- 基准测试:在不同模型上运行 EQA 基准测试并分享结果
- 文档:改进示例、修正拼写错误、添加使用案例
开发环境设置
git clone https://github.com/jpazvd/unicefstats-mcp.git
cd unicefstats-mcp
pip install -e ".[dev,benchmark]"
pytest tests/ -v
ruff check src/ tests/
mypy src/unicefstats_mcp/
拉取请求指南
- 每个 PR 只处理一项内容——让变更聚焦且易于审核
- 为新工具或错误修复添加测试
- 提交前运行代码检查工具(
ruff check)和类型检查工具(mypy) - 如果更改了工具签名或添加了新功能,请更新 README
- 不要提交 API 密钥,也不要提交大于 500KB 的基准测试结果 parquet 文件
优先领域
已知问题请参阅审计发现。影响较大的领域:
- MNCH 数据流 Bug:由于
unicefdata包中的数据流解析问题,MNCH_CSEC和MNCH_BIRTH18返回的 EQA 为 0 - 降低 T2 幻觉:进一步减少 API 未返回结果时的编造情况(目前约为 10%;参见限制与幻觉风险)
限制与幻觉风险
数据限制
- 各指标、国家和年份的数据覆盖并不均衡。基于调查的指标(营养、教育、保护)按设计会有 3-5 年的数据点间隔。
- 死亡率指标(CME_*)是联合国机构间儿童死亡率估算小组(IGME)的模型估算值,精简输出中不会显示不确定性区间。
- 并非所有指标都支持所有细分维度;
get_indicator_info()会列出每个指标可用的维度。 - 每次调用中,
get_data()最多返回 500 行。
幻觉风险
对多个国家样本进行基准测试(v0.7.3 + 修复,2026 年 5 月):
| 类型 | 说明 | 比率(仅 LLM,hall_a) | 比率(LLM + MCP,hall_b) | 备注 |
|---|---|---|---|---|
| T1(年份缺口) | LLM 在指标有数据、但特定年份没有数据时引用该年份的数值 | ~1.0% | 0.00%(mcp060)/ 0.50%(mcp073) | 低于无工具时的比率 |
| T2(超出数据前沿) | LLM 编造数据前沿之后某一年的数值 | ~3.5% | 2.00%(mcp060)/ 4.00%(mcp073) | 低于无工具时的比率 |
| 合计 | T1 + T2 | hall_a 2.50% | 1.00%(mcp060)/ 2.25%(mcp073) | hall_b < hall_a — MCP 更安全 |
v0.7.3 + 修复是首个让 MCP 比无工具基线更安全的版本。 在 v0.7.2(v1.4 评分)及之前,hall_b ≥ hall_a — 安全层相较于无安全层基线降低了幻觉幅度,但始终不足以让 MCP 低于无工具时的水平。
变更内容:
_seed_data_frontier_cache中的缓存污染 — 一个探测例程会用恰好返回的年份覆盖指标的缓存最大年份,有时该年份低于缓存值。于是,LLM 得知数据前沿是 2018 年,而相关指标的实际前沿是 2023 年,随后便根据参数记忆回答 2023 年的数据。修复方式:只使用单调递增的max()。- 将
unicefdata级联失败归类为no_data,而非error— 底层封装的备用数据流耗尽错误会作为工具异常泄漏,LLM 会将其理解为“工具失败,改用自己的知识”。现在,该情况会被归类为明确的no_data信号,再由安全层将其转换为“不要估算”。已提交unicefdata-dev#74,请求上游修复。 - v1.4 提取器(
_detect_refusal)— 修正了一项长期存在的评分偏差:响应中的任何数值都会被算作“断言”,包括 LLM 在明确拒绝回答时引用no_data工具结果中的数值。这使 v0.7.3 PRE-FIX 重新评分中的 hall_b 从约 37% 降至 2.25% — 过去大多数“MCP 让情况更糟”的发现源于提取器,而非模型行为。 - 批处理运行器一致性 — 在异步批处理运行器中持久化
result_str并尊重拒绝回答。
这一发现仍为关于工具增强型 LLM 文献中一个更广泛的问题留下了讨论空间:为模型提供可生成答案的路径所带来的结构性代价。
- The Reasoning Trap: How Enhancing LLM Reasoning Amplifies Tool Hallucination(ICLR 2025)——表明这种关系具有因果性:随着模型的工具使用能力提升,工具幻觉也会随能力成比例增加。
- Reducing Tool Hallucination via Reliability Alignment(Cao 等,2024,arXiv:2412.04141)——将这类失败形式化为工具选择错误(工具选错、未能拒答)和工具使用错误(捏造参数)。
- ReDeEP: Detecting Hallucination in Retrieval-Augmented Generation via Mechanistic Interpretability(Sun 等,2024)——从机制层面表明,大模型的参数化知识可能在残差流中覆盖检索到的上下文。
这些结果表明,这种结构性倾向确实存在;v0.7.3 + 修复的结果则表明,可以通过 (a) 安全层架构、(b) 服务端规范(不使用过时的前沿数据缓存,不将无数据情况泄露为工具错误)和 (c) 诚实评分,逆转特定数据领域中的这种倾向。
给用户的建议:
- 在会话开始时加载
unicef://system-prompt和unicef://context资源(用于处理前沿数据以外内容的捏造)。 - 将 MCP 结果视为尽力检索的结果,而非绝对可靠的事实——引用前,请对照 UNICEF Data Warehouse 核实关键数值。
- 优先使用包含明确年份的查询(“2023 年尼日利亚的五岁以下儿童死亡率”),而非开放式查询(“尼日利亚最新的五岁以下儿童死亡率”)——数据缺失时,前者更容易触发拒答。
- 1.00% / 2.25% 的残余误差仅在 Sonnet 4 上测得。跨模型泛化是下一项基准测试。
完整基准测试方法:examples/RESULTS.md
来源与所有权
此 MCP 提供的所有数据均来自 UNICEF Data Warehouse,通过公开的 SDMX REST API 实时获取。系统不会存储或缓存任何观测数据——每次 get_data() 调用都会发起实时 SDMX 请求。为提升性能,指标和国家注册表会在首次访问时缓存在内存中;这些属于目录元数据,而非统计值。MCP 会重新整理输出以供大模型使用,但不会更改数值。
所有版本均通过 PyPI Trusted Publishing(OIDC)从 GitHub Actions 发布。系统不存在长期有效的 API 令牌。可通过 PyPI attestations 验证发布来源。
有关数据来源、所有权、分发流程和解读注意事项的完整详情,请参阅 PROVENANCE.md。
如何验证此 MCP
| 检查项 | 方法 |
|---|---|
| 来源 | GitHub 上的仓库为 jpazvd/unicefstats-mcp |
| 软件包 | pip show unicefstats-mcp——确认 Home-page 指向规范仓库 |
| 版本 | python -c "import unicefstats_mcp; print(unicefstats_mcp.__version__)"——与 server.json 和 PyPI 上的信息进行比较 |
| 来源证明 | PyPI attestations 会将每个版本关联到一个 GitHub Actions 工作流 |
| 运行时 | 调用 get_server_metadata()——返回规范名称、版本、发布者和数据来源 |
许可证
MIT
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。