每个 WorldMonitor MCP 工具都接受一个可选的 jmespath 字符串参数。服务端会在任意工具级过滤器和 summary 参数之后应用该表达式,然后在序列化之前投影响应。一个选得好的投影通常能把载荷大小削减 80–95%——这是你在保持长 agent 循环不超出上下文窗口方面最有效的手段。
本页是实用参考:先给出快速概览,然后针对三份真实抓取的工具响应给出十二个实例解析。至于语法本身,请依赖规范——jmespath.org/specification.html。回来看这里比重读规范更快。
快速概览
-
在任意
tools/call 上把表达式作为 jmespath 参数传入。表达式的根是完整响应信封——缓存工具的 { cached_at, stale, data: { … } }——所以大多数表达式以 data.<key> 开头以触达载荷,而当你需要时,cached_at / stale 也能从同一根寻址。
-
带连字符的键必须用双引号引用。 大多数 WorldMonitor 工具都有带连字符的缓存键(
stocks-bootstrap、ucdp-events、etf-flows、fear-greed、transit-summaries)。使用 data."stocks-bootstrap".quotes[*].symbol,而不是 data.stocks-bootstrap.…。
-
数字和 JSON 字面量放在反引号里,字符串放在单引号里。
[?deathsBest > \5`](数字),[?country == ‘Iraq’]`(字符串)。混用会静默地把值解析成别的什么东西。
-
两个服务端限制保持 edge function 健康:
- 表达式本身:≤ 1024 字节。
- 投影输出:≤ 256 KB。
失败会在正常结果信封内返回 { _jmespath_error, original_keys, ... }——工具调用在 JSON-RPC 层仍然成功(不会 isError: true),而 original_keys 回显未投影响应的顶层键名,让模型能在下一次调用中自我修正。
下面用到的三种响应结构是 tests/fixtures/jmespath-samples/ 下抓取的固件(会定期对生产 MCP 端点重新抓取)。它们是故意挑选的——大(~100 KB,使用 limit: 0)、中(~30 KB)、小(~10 KB)——以覆盖你实际会投影的各种大小档位。
REST API(?jmespath=)
同样的投影在 REST API 上也可用:每个 GET 端点都接受一个可选的 jmespath 查询参数,网关在返回前于服务端将其应用到 JSON 响应上。复用你已从 MCP 熟知的表达式即可,但有两点不同:
- 表达式根是原始响应体,而非 MCP 的
{ cached_at, stale, data } 信封——因此你直接投影载荷(compositeScore、keys(@)),无需 data. 前缀。
- 一个错误、过长或过度展开的表达式返回
HTTP 400,并携带相同的 { _jmespath_error, original_keys } 主体(MCP 传输则是在 200 result 内软失败)。≤ 1024 字节表达式限制与 256 KB 投影输出上限完全一致。
十二个示例
1. 钻取单个嵌套对象
意图。 跳过股票列表,只从 get_market_data 取 WorldMonitor 恐慌贪婪综合得分。
工具调用:
未投影响应(~100 KB,使用 limit: 0)。 数百条股票报价、每个板块、全部加密货币、每个海湾 ticker、完整的恐慌贪婪明细:
投影后响应:
为什么有效。 钻取就是点号路径导航。data."fear-greed" 引用了带连字符的键,然后 .composite 摘取嵌套对象。载荷里的其它所有内容——那 100 KB 的报价——根本不会经过网络传输。
普通使用时省略 limit: 0:当省略 limit 时,缓存工具会把列表型和映射型字段默认封顶在 30 项。
2. 把每条记录精简到几个字段(multiselect-hash)
意图。 从 get_market_data 取一份默认封顶股票报价的三行紧凑表:代码、价格、百分比变化。
工具调用:
未投影响应(相关切片)。 每条报价还携带 name、display 和一个 sparkline 数组——这些对模型回答”今天什么动了”这类问题通常都用不到:
投影后响应:
为什么有效。 [*] 投影跨每个数组元素;{s:symbol, p:price, chg:change} 是 multiselect-hash——它按你列出的字段为每个元素构造一个新对象。更短的输出键(s、p、chg)能再省几个字节;标准键(symbol、price、change)也行,如果你想要可读性的话。
3. 按数值比较器过滤
意图。 从 get_conflict_events 只保留至少有一例确认死亡的 UCDP 事件。
工具调用:
未投影响应(相关切片)。 许多 UCDP 条目记录的是 deathsBest: 0 的遭遇——政治事件、被拦截的袭击、未遂:
投影后响应: deathsBest: 0 的条目被丢弃。
为什么有效。 [?expr] 是过滤投影;> 是数值比较器。反引号包裹字面量很关键——[?deathsBest > 0](没有反引号)会把 0 当作标识符,JMESPath 会解析它但随后求值成 null,比较静默地返回零行。始终用反引号包裹数字和布尔字面量。
4. 按字符串相等过滤
意图。 从 get_conflict_events 取每个 country 恰好为 "Iraq" 的 UCDP 事件。
工具调用:
投影后响应:
为什么有效。 字符串字面量用单引号,不是双引号。双引号在 JMESPath 里表示”标识符”(与用来转义带连字符键如 "stocks-bootstrap" 的语法相同)。一个常见的初学者错误是 [?country == "Iraq"],JMESPath 会把它解析为”把 country 与一个字面上名为 Iraq 的字段比较”,把右侧求值成 null,然后返回零行。
5. 数组投影——单字段的扁平列表
意图。 从 get_market_data 取一份板块 ETF ticker 的扁平列表。
工具调用:
未投影响应(相关切片):
投影后响应:
为什么有效。 [*] 投影跨每个数组元素,.symbol 依次应用到每个元素上。结果是一个仅含 symbol 字符串的数组——没有外层对象。
6. 切片——前 N 个元素
意图。 从 get_conflict_events 只返回前五个 UCDP 事件。
工具调用:
投影后响应: 一个五元素数组,结构与未投影的 events[] 相同。
为什么有效。 [start:stop] 是切片投影(stop 不含)。也支持负索引和步长——[-5:] 取最后五个,[::-1] 反转,[::2] 隔一个取一个。切片在流水线里位于过滤之后——要切片过滤后的集合,用管道(见示例 12)。
limit 与切片。 缓存工具接受工具级 limit 参数,它会在投影之前给列表或映射型切片封顶(暴露列表 / 映射字段的缓存工具默认为 30)。limit 与 JMESPath 可组合:工具级封顶收窄候选集,然后你的 [0:N] 切片取前缀。当你想要全部数据并打算用 JMESPath 进一步投影时,传 limit: 0 来禁用工具级封顶。
7. length() 用于计数
意图。 默认封顶的最新一批里有多少个 UCDP 事件?
工具调用:
投影后响应:
为什么有效。 length() 是 JMESPath 内置函数之一;它作用于数组、字符串和对象(对对象返回键数)。适合在更长的调用之前做一次健全性检查——一次 length() 投影返回单个整数,不耗 token,能让模型在决定接下来投影什么之前先判断这批数据是否为空。
因为本次调用省略了 limit,工具级默认封顶会在 JMESPath 之前应用,因此计数是封顶后的候选集(30)。当你需要改为计数完整底层批次时,请传入 limit: 0。
8. sort_by + 反转 + 切片——Top-N
意图。 从 get_conflict_events 给我死亡数最高的三个 UCDP 事件,只要国家 + 死亡数。
工具调用:
投影后响应:
为什么有效。 用 | 串起三个阶段:
sort_by(events, &deathsBest)——JMESPath 按升序排序;&expr 是表达式引用(排序键)。
reverse(@)——把升序翻成降序。@ 是当前节点。
[0:3].{...}——切片取前三,再用 multiselect-hash 精简每行。
这是”按某指标给我 Top-N”的主力写法。同样的写法适用于按百分比变化取 Top-N 市场、按 CII 得分取 Top-N 国家、按事件数取 Top-N 咽喉点。
9. 按枚举字符串字段过滤
意图。 从 get_conflict_events 返回前五个被归类为国家间暴力(state-based violence)的 UCDP 事件——最高严重度档位。
工具调用:
投影后响应: 默认封顶固件中 14 条国家间暴力行里的前五条:
为什么有效。 过滤和 multiselect-hash 在同一投影里从左到右组合——[?...].{a:..., b:...} 先过滤,再精简每个幸存行。大多数 WorldMonitor 响应使用大写下划线枚举字符串(SEVERITY_LEVEL_HIGH、TREND_DIRECTION_STABLE、UCDP_VIOLENCE_TYPE_*);用 == 和单引号按原样搜索它们。
10. 对象即映射的导航
意图。 从 get_chokepoint_status 只取霍尔木兹海峡的风险等级 + 7 天事件数。
工具调用:
未投影响应(相关切片)。 注意 summaries 是以咽喉点名为键(对象映射),而不是一个 {name, ...} 记录的数组:
投影后响应:
为什么有效。 对象即映射的结构在这个服务里随处可见——咽喉点、fear-greed.categories 内的权重、get_eu_housing_cycle 里以欧盟成员国为键的序列。把它们当作点号路径导航:已知键 → 直接用该键。如果你不知道键名,见下一个示例。
11. 对象即映射的投影——* 和 keys()
意图。 从 get_chokepoint_status 列出每个当前评级为 “critical” 的咽喉点及其事件数。
工具调用:
投影后响应:
为什么有效。 summaries.* 把映射的值扁平化成数组——于是 suez、hormuz_strait、bab_el_mandeb 等变成可索引的数组元素。然后套用普通的 [?…] 过滤和 multiselect-hash。
扁平化会丢掉原映射键(咽喉点名)。如果你也需要名字,用 keys(data."transit-summaries".summaries) 单独投影它们,或者接受这种结构错配并改用同级的 chokepoint_transits.transits 载荷——后者是以 {tanker, cargo, other, total} 为值、咽喉点名为键的映射——keys(data.chokepoint_transits.transits) 给你一份覆盖每个咽喉点的扁平列表。
12. 管道组合子——多阶段投影
意图。 从 get_conflict_events 给我死亡数最高的前五个有死亡事件,含国家、死亡数和暴力类型。
工具调用:
投影后响应:
为什么有效。 | 把上下文重置为”目前的结果”并开启一个新投影——于是过滤先跑,排序针对过滤后的集合(不是整个数组)跑,反转翻转它,切片取前五,multiselect-hash 精简每行。每当你需要在过滤之后(而非跨原数组)应用投影(比如 sort_by)时,管道就是对的工具。
逃生舱
取完整载荷(无投影)
完全省略 jmespath 参数。当省略 limit 时,缓存工具会把列表或映射型字段默认封顶在 30 项;当你确实想要整批数据时,传 limit: 0 禁用该封顶:
当你在抓取固件、跑一次性审计,或把响应喂给一个表现力更强的下游过滤器(你自己的 jq、一个 notebook)时,这是对的选择。对于日常的模型上下文,投影几乎总是更胜一筹。
_budget_exceeded——载荷太大时
每个工具声明一个工具级输出预算(_outputBudgetBytes)。当某工具序列化后的响应在所有过滤、summary 和 JMESPath 都应用完之后仍超过该预算,服务端会返回这个信封而不是过大的载荷——仍在正常 MCP 结果里、仍是 HTTP 200、仍是 isError: false:
恢复方式始终相同:让投影更具选择性,或在它之下叠加一层工具级过滤器(country、since、limit)。当这个信封触发时,Pro 每日配额槽保持已扣除——工具在测量输出大小之前已经完成了完整的上游获取/计算,成本已经发生(如果在这里退款,调用方就能通过总是超出预算来无限消耗真实成本)。请先通过 describe_tool 的 outputSchema 规划投影,而不是依赖重试。
_jmespath_error——投影本身失败时
JMESPath 表达式可能以三种方式失败:表达式本身超过 1024 字节、语法非法,或一个失控的 multiselect-hash 撑爆 256 KB 输出上限。三种情况下你都会拿到这个信封——注意 _jmespath_error 是字符串(<kind>: <details>),不是对象:
original_keys 是未投影响应的顶层键——足以让模型在多一次调用里用修正后的表达式重试。一个坏表达式在适用该配额路径时确实每次尝试消耗一个每日配额槽;回显的 original_keys 正是为了让重试能自我修正而非瞎猜。三种类型(expression_too_long、invalid_expression、projection_too_large)及其精确判别字符串见 MCP 错误目录。
投影的互补项
summary: true 标志
每个缓存工具还接受一个通用的 summary: true 参数,它返回一个服务端构造的摘要而非完整载荷。数组变为 { count, sample },最多 3 个样本项;键数超过 5 的对象字段被视为实体映射,变为 { count, sample_keys },最多 3 个样本键。在以下情况使用:
- 你想在设计投影之前快速核对一下这批数据里有什么——
summary: true 用少量字段返回结构和档位计数。
- 模型只需要聚合计数(“多少场活跃冲突?”、“多少个关键咽喉点?“)而非底层行。
summary: true 与 jmespath 可组合:摘要先构造,投影再叠加其上。当你想要摘要的预聚合计数但只取其中部分类别时,把两者结合起来。
当 tools/list 返回的压缩描述对某工具的响应结构含糊不清时,调用 describe_tool({ tool_name: "get_market_data" }) 取完整未压缩定义。describe_tool 仅含元数据且不计入 Pro 每日配额——编写投影时尽管放心用。如果名字错了,响应是 { error: "unknown_tool", available: [...] },同样无配额成本。
另请参阅