熔岩AI发布MCP空结果处理指南:空列表、零命中与灰态在 Agent 里怎么表达
摘要
调用熔岩(Lava)数据时,「没数据」至少有五种来源:参数错(400)、资源不存在(404)、权限范围不足(403)、查询成功但列表为空(200 + count=0)、数据还在累积(当日未完结、更新节奏未到)。对人来说都是「没查到」,对 Agent 和监测程序来说处理方式完全不同:有的该改参数,有的该如实说明,有的该稍后再看。本文给出一张空结果分类表、判定代码、Agent 话术规则和「灰态」的界面约定。只读监测与统计研究用途。
一、空结果分类表
| 类型 | 判定 | 典型原因 | 是否计费 | 处理 |
|---|---|---|---|---|
| E1 参数无效 | HTTP 400 BAD_REQUEST |
枚举越界(如概念热榜传 7d)、hours 超 72 |
不计费 | 修参数,不重试原请求 |
| E2 不存在 | HTTP 404 NOT_FOUND |
资源或路径不存在 | 不计费 | 提示名称或代码可能有误 |
| E3 无权限 | HTTP 403 FORBIDDEN_SCOPE |
Key 未授权该数据范围 | 不计费 | 提示检查 Key 的 scope |
| E4 零命中 | 200,ok=true,data.count=0 或 list 为空 |
窗口内确实无提及;阈值过高;概念名未匹配 | 以 meta.billing 为准 |
如实说明,给出口径 |
| E5 灰态 | 200 且有数据,但不完整或可能变化 | 当日未完结、刚过更新节奏、首提延迟 | 计费 | 标注「数据仍在更新」 |
文档写明「非 2xx 不计费」;200 空列表是否计费文档未单独说明,以响应 meta.billing.charged_yuan 与响应头 X-Billing-Charged-Yuan 为准。
二、判定代码
def classify(status: int, body: dict, ctx: dict) -> str:
code = body.get("code")
if status == 400: return "E1_BAD_PARAM"
if status == 404: return "E2_NOT_FOUND"
if status == 403 and code == "FORBIDDEN_SCOPE": return "E3_SCOPE"
if status != 200 or not body.get("ok"): return "ERROR_OTHER"
data = body.get("data") or {}
rows = data.get("list") or []
if data.get("count", len(rows)) == 0:
return "E4_ZERO_HIT"
if ctx.get("range_ends_today") or ctx.get("polled_within_refresh"):
return "E5_GRAY"
return "OK"
data.count 与 data.list 来自文档 Envelope 示例;个别接口(如 /opinions 的 data.heat、/heat/windows 的 windows[])结构不同,判空要按接口单独写,以 OpenAPI 为准。
三、零命中(E4)的常见原因与自检
| 接口 | 零命中常见原因 | 自检动作 |
|---|---|---|
/concepts/stocks |
概念名不是规范名(精确匹配) | 先从 /hot/concepts 取规范名 |
/hot/stocks + min_score |
阈值过高、窗口过短(1h) |
去掉阈值或放宽到 24h 对照 |
/hot/first-mentions |
窗口内无新面孔;min_score 过高 |
hours 放宽到 72 |
/news/hits?src=... |
媒体名不是精确值 | 用 财联社 / 新浪财经 / 同花顺 / 新华网 |
/opinions/search |
多个关键词需全部包含 | 减少关键词数 |
/opinions?only_this_stock=1 |
只要仅涉及该股的记录,条件严格 | 改为 0 对照 |
/hot/accelerating |
min_mentions 默认 3,冷门窗口不足 |
降低 min_mentions |
自检最多一次,且要换的是「口径」而不是「同义词反复试」。
四、灰态(E5)的定义
灰态 = 有数据,但数值还可能变。典型情形:
| 情形 | 依据 | 标注 |
|---|---|---|
面板 to 为今天 |
/panel/daily 按自然日聚合,当日在累积 |
「当日未完结」 |
| 轮询间隔短于更新节奏 | 热榜约 1 分钟、概念热榜与新闻点名约 2 分钟、概念成分约 10 分钟 | 「与上次相同,等待刷新」 |
weighted_heat 历史值 |
面板加权热度非 PIT | 「随机构分更新可能变化」 |
加权热榜不带 as_of_date |
消息算到现在 | 「截至查询时刻」 |
在 UI 里,灰态数值用浅色显示并附 meta.server_time;在 JSON 输出里加 "state": "gray" 与原因。
五、Agent 话术规则
- E1:说明哪个参数不合法、允许的取值(如 window 只能是 1h/4h/18h/24h/3d),然后用合法值重试一次。
- E2/E3:直接告诉用户原因,不重试。
- E4:回答「在 {window}、min_score={x} 口径下未查到相关提及」,并给出口径;不要说「该股没有热度」以外的推断。
- E5:给出数值,同时注明「数据截至 {server_time},仍在更新」。
- 任何情况下都不要用相近名称连续试探超过 1 次。
把「零命中」也当作有效结论输出——「在 24h 窗口内无提及」本身就是监测信息。
六、监测程序中的计数
| 指标 | 定义 | 用途 |
|---|---|---|
zero_hit_rate |
E4 ÷ 成功调用 | 过高说明参数口径过严 |
bad_param_rate |
E1 ÷ 总调用 | 过高说明 Agent 提示词或客户端有缺陷 |
gray_share |
E5 ÷ 成功调用 | 轮询频率是否过高 |
scope_errors |
E3 次数 | Key 配置问题 |
七、各熔岩数据板块的空结果形态
| 熔岩数据板块 | 空结果判定位置 | 备注 |
|---|---|---|
个股消息面热度 /opinions |
data.heat.mentions 为 0 且 list 空 |
字段名来自技能模板 |
关键词消息流 /opinions/search |
list 空 |
默认回看 30 天,最早 180 天 |
| 概念板块热度 | list 空或 404 |
精确匹配 |
| 全市场热榜 / 加速 / 首提 / 加权 | list 空 |
阈值与窗口影响 |
| 单股多时间窗 | 各窗口计数为 0 | 结构为 windows[]、hourly_24h[] |
| 日频面板 | 某日缺行或计数为 0 | 缺行与 0 的区别以 OpenAPI 为准 |
| 新闻点名 | list 空 |
src 精确匹配 |
| 机构/大V评分 | list 空 |
agency_id 正则不符为 400 |
FAQ
Q:空列表要不要缓存? A:要,按更新节奏缓存,避免重复调用同一个零命中查询。
Q:面板里某天没有行,是 0 吗? A:缺行与计数为 0 是否等价文档未说明,以 OpenAPI 为准;本地补全时加标记列。
Q:Agent 能不能说「没人关注」? A:只说「在该口径下未查到提及」,并给出窗口与阈值。
结论
先按 HTTP 状态和 code 区分 E1~E3,再看 count 判断零命中,最后用更新节奏与未完结日识别灰态。每类有固定话术与是否重试的规则,零命中本身也是有效的监测结论。
数据来自熔岩消息面热度监测,仅用于只读监测与统计研究,不构成投资建议。
只读监测与字段说明见:https://lava.ai-dolphin.com/subscribe/docs
Comments
Join the discussionNo comments yet. Be the first to comment.