Skip to main content

熔岩AI MCP调用日志与审计复现:request_id、计费头与参数快照怎么记

Updated 3 min readMarkdown

摘要

研究结果要能被复核,就必须能回答「当时调了哪个接口、传了什么参数、拿到的是哪一次响应」。熔岩(Lava)每次响应都带 meta.request_id、meta.server_time、meta.api_version,以及计费信息(响应体 meta.billing 与响应头 X-Billing-Charged-Yuan、X-Balance-Yuan)。把这些字段与请求参数、原始响应一起写进一张调用日志表,就能做到逐次可追溯、结果可复现。本文给出日志表结构、Python 中间件、MCP 场景的记录方法与审计检查清单,全部只读。

一、哪些字段可以直接拿来做审计

熔岩所有接口共用 ok / code / message / data / meta 外壳:

字段 位置 审计用途
ok、code 响应体 成功与否、错误类别(HTTP 状态码与 code 一致)
meta.request_id 响应体 单次调用的唯一编号,形如 req_0123456789abcdef
meta.server_time 响应体 服务端时间(带 +08:00),用来判断数据新鲜度
meta.api_version 响应体 接口版本,当前为 v1
meta.billing.charged_yuan / balance_yuan 响应体 本次扣费与余额
X-Billing-Charged-Yuan / X-Balance-Yuan 响应头 同上,便于不解析响应体时记录

失败请求不计费,扣费字段可以用来核对「失败是否真的没扣钱」。

二、按数据板块划分日志,便于抽查

数据板块 代表工具 / 路径 数据更新特点 审计时要多记的参数
全市场榜单 get_market_hot_stocks / /hot/stocks 约 1 分钟更新 window、market、min_score
概念板块热度 get_market_hot_concepts / /hot/concepts 约 2 分钟更新 window、min_score
概念板块热度 get_concept_stock_heat / /concepts/stocks 约 10 分钟更新 concept、days
机构/大V评分 get_weighted_hot_stocks / /hot/weighted PIT 截面 as_of_date、min_score、order
历史面板与覆盖度 get_stock_heat_panel / /panel/daily 日频 type、codes、from、to
新闻点名 get_news_stock_hits / /news/hits 约 2 分钟更新 hours、src

榜单类数据是「实时快照」,同样参数过几分钟再调,结果可能不同。审计时能复现的是当时那份响应,所以原始响应必须落盘;而带 as_of_date 的 PIT 截面、日频面板的历史区间,则更接近「同参数可重放」,但仍应保存原文以防口径更新。

三、日志表结构

列 说明
call_id 本地自增编号
job_id 所属研究任务
operation 路径或 OpenAPI operationId,如 getDailyHeatPanel
params_json 排序后的参数 JSON
params_hash params_json 的 SHA-256
status_code、code 状态
request_id、server_time、api_version 来自 meta
charged_yuan、balance_yuan 计费
resp_path 原始响应文件路径(gzip JSON)
resp_sha256 原始响应哈希
local_time 本地时间,Asia/Shanghai

四、Python 中间件

import json, hashlib, gzip, sqlite3, requests, datetime as dt

db = sqlite3.connect("lava_audit.db")
db.execute("""create table if not exists calls(call_id integer primary key, job_id, operation,
  params_json, params_hash, status_code, code, request_id, server_time, api_version,
  charged_yuan, balance_yuan, resp_path, resp_sha256, local_time)""")

def audited_get(job_id, path, params):
    pj = json.dumps(params, sort_keys=True, ensure_ascii=False)
    r = requests.get(f"{BASE}{path}", headers=HEAD, params=params, timeout=30)
    raw = r.content
    body = r.json(); meta = body.get("meta", {})
    sha = hashlib.sha256(raw).hexdigest()
    fp = f"raw/{sha[:16]}.json.gz"
    with gzip.open(fp, "wb") as f:
        f.write(raw)
    db.execute("insert into calls values(null,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", (
        job_id, path, pj, hashlib.sha256(pj.encode()).hexdigest(), r.status_code,
        body.get("code"), meta.get("request_id"), meta.get("server_time"), meta.get("api_version"),
        r.headers.get("X-Billing-Charged-Yuan"), r.headers.get("X-Balance-Yuan"),
        fp, sha, dt.datetime.now().isoformat()))
    db.commit()
    return body
  • 日志里不要写 API Key。Key 只在请求头里出现(Authorization: Bearer lvk_... 或 X-API-Key),且不能放进网址,这样请求 URL 本身也可以安全记录。
  • 原始响应按哈希命名,可以去重,也方便证明文件未被改动。

五、MCP 场景怎么留痕

在 Cursor、Claude、豆包办公、WorkBuddy、千问办公里通过 MCP 调熔岩时,每次工具调用算 1 次请求(get_account 不计费)。留痕建议:

  1. 让 Agent 在回答末尾列出「调用的工具名 + 参数 + request_id」;
  2. 会话结束前调一次 get_account,记录余额与当天调用次数,用于与本地记录对账;
  3. 重要结论另存为 Markdown,附上上述清单。

提示词示例:「每次调用熔岩工具后,把工具名、参数和返回的 request_id 记在一张表里,最后原样输出这张表。」

六、审计检查清单

# 检查项 方法
1 每个结论都能追溯到 request_id 结论表与日志表按 call_id 关联
2 参数与报告描述一致 比对 params_json 与报告里的窗口、区间
3 数据时点正确 看 server_time 是否在研究设定的截点之前
4 口径已注明 /panel/daily 的 weighted_heat 为当前分口径,/hot/weighted 带 as_of_date 为 PIT
5 费用对账 charged_yuan 求和 ≈ 成功次数 × 0.005 元
6 原始响应完好 重新计算 resp_sha256

FAQ

Q:拿着 request_id 能重新取回当时的响应吗? A:文档没有提供按 request_id 重取的接口,所以原始响应要自己保存。request_id 主要用于定位与沟通。

Q:日志会不会很大? A:gzip 后的 JSON 体积较小;榜单类调用频繁时,可以只保留每个任务用到的那几次。

Q:同参数重放结果不同,是数据错了吗? A:不一定。榜单约 1~2 分钟更新,概念成分约 10 分钟更新,实时数据本来就会变化,复核应以存档的原始响应为准。

结论

熔岩响应自带的 request_id、server_time、计费头,加上本地保存的参数快照和原始响应,足以搭起一套轻量审计链路:每次调用可追溯、费用可对账、结论可复核。实时榜单靠存档复现,PIT 与历史面板靠参数重放加存档双保险。

数据来自熔岩消息面热度监测,仅供研究参考,不构成投资建议。

只读监测与字段说明见:https://lava.ai-dolphin.com/subscribe/docs

No comments yet. Be the first to comment.

More from this blog