遥测、更新与诊断

三个默认关闭、逐项同意的遥测通道,本地的事故记录与观测日志,签名清单与多种安装来源下的自更新,每日签到,以及排查问题用的诊断命令。

作者 David更新于 第 32 篇(共 33 篇)

模型请求之外,mcode 进程还有几类“产品自己的流量”:使用统计、运行时指标、错误诊断、更新检查、签到和用户反馈。源码导入当天的提交 36bd09392a0b(2026-09-18,“fix: require separate consent for automatic telemetry uploads”)把其中所有自动上传都改成了默认关闭、逐项同意。本篇先讲这几个通道现在的行为,再讲自更新、签到与诊断入口。

怎么用

三个开关都在 config.yaml 的 telemetry 段。docs/telemetry.md:10 给的示例只打开了使用事件:

telemetry:
  enabled: true      # TUI usage events (anonymous, described below)
  metrics: false     # Runtime counters, gauges, and histograms
  diagnostics: false # Account-linked TUI and LLM error diagnostics
  • 配置文件在数据目录(默认 ~/.minimax-code,packages/tui/src/runtime/data-dir.ts:21)的 config.yaml 里。三个键缺省都是 false(packages/config/src/config.ts:1772),metrics 与 diagnostics 只有写成布尔值 true 才算同意(config.ts:2105)。
  • 环境变量 MCODE_DISABLE_TELEMETRY 或 DO_NOT_TRACK 取 1、true、yes、on(不分大小写)时三个通道全关,优先于配置文件(packages/config/src/telemetry-policy.ts:5)。
  • mcode telemetry status 打印每个通道的生效状态、被哪个环境变量挡住、配置文件路径;mcode telemetry preview 打印一条解码后的示例请求(固定是 tui_launch),不会发送,使用事件没开时 request 为 null(packages/tui/src/cli/telemetry-command.ts:26)。
  • 更新:TUI 每次启动都在后台检查,有新版就在欢迎页提示;/update 在 TUI 里升级(要输入搜索才出现在菜单里),mcode update 在命令行升级,交互终端里会先问一句 [y/N](packages/tui/src/cli/update.ts:70)。代码里没有找到关闭启动检查的开关。
  • 签到用 /checkin;诊断命令见文末。

三个通道

通道配置键内容发往身份
使用事件telemetry.enabled启动、登录、发消息、打开斜杠与 @ 菜单等 10 种事件按地区与构建环境选的 meerkat-reporter 地址每条事件一个新的随机 ID,不带账号
运行时指标telemetry.metrics计数、仪表、直方图与少量低基数标签Matrix 的指标批量接口文档称不附账号凭据
错误诊断telemetry.diagnosticsTUI 事故与 LLM 请求失败的最小化摘要/minimax-cloud/api/v1/observability/desktop-errors/batchBearer token 加 user_id 参数,绑定账号

后两个通道共用一个开关函数(telemetry-policy.ts:11):

export function isTelemetryChannelEnabled(
  channel: TelemetryChannel,
  readConfigured: () => boolean | undefined = () => getConfig().telemetry[channel],
): boolean {
  for (const key of TELEMETRY_OPT_OUT_ENV) {
    if (/^(?:1|true|yes|on)$/iu.test(process.env[key]?.trim() ?? '')) return false;
  }
  try {
    return readConfigured() === true;
  } catch {
    return false;
  }
}

两条规则:环境变量先于一切;配置读不出来按“未同意”处理。使用事件走另一个函数 resolveMcodeBusinessTelemetryPolicy(),环境变量的判定一样(packages/tui/src/analytics/business-telemetry.ts:126),但只在启动时读一次配置,不开就根本不创建客户端(packages/tui/src/tui/launcher.ts:237),所以改完要重启。诊断通道则每次记录、每次上传前都现查一次;/reload 会清掉配置缓存,从代码推断,改了 diagnostics 之后执行一次 /reload 就能生效。

这个提交改了什么

按 36bd09392a0b 的 diff 对比:

通道之前现在
运行时指标托管运行时一律创建云端上报器;生产与预发构建都算托管(config.ts:166)还要 telemetry.metrics 为真(packages/local-runtime/src/runtime/host-metrics.ts:112)
LLM 请求失败报告登录即上传进缓冲前、加密发送前各查一次(packages/local-runtime/src/error-reporting/reporter.ts:107、reporter.ts:65)
TUI 事故写成待上传文件,登录后自动上报未同意时写成只留本地的文件;排空和每批发送前再查一次(packages/tui/src/observability/incident-reporter.ts:320)
使用事件已经默认关闭不变

指标与 LLM 报告的装配在第一代宿主的 host-factory.ts 里,运行时 v2 启动时会在内部建一个 v1 宿主(packages/local-runtime-v2/src/runtime.ts:254),所以命令行产品同样受这两处约束。

同一天的配套提交 30dd6f27f1b0 改写了 docs/telemetry.md,并让 mcode telemetry status 列出三个通道。更新日志却没跟上:中文更新日志 0.2.5 仍写着“TUI 会在本地有界保存经过脱敏的异常退出与生命周期故障信息,并在登录后自动上报”(packages/tui/CHANGELOG.zh-CN.md:388),这句话已不符合现在的代码,后面的版本也没有记这次改动。

使用事件

  • 白名单:只有 10 种事件,每种只取固定的几个属性,其余一概丢弃(EVENT_PROPERTY_KEYS,business-telemetry.ts:111)。每条都附 surface、os、region、build_env、app_version 五个公共字段。
  • 没有持久身份:$identity_cookie_id 与 distinct_id 每条事件现生成一个 UUID(business-telemetry.ts:222),只为满足接收端要求的信封格式,两条事件之间无法据此关联。
  • 只在内存里排队:最多 100 条,满了丢最旧的(business-telemetry.ts:184);在微任务里逐条 POST,每条 3 秒超时,失败直接吞掉;退出时 flush() 一次。
  • 编码:请求体是表单,data 为 Base64 编码的 JSON,ext 为 crc= 加一个 Java 风格的字符串哈希(business-telemetry.ts:266)。

TUI 这边的取值:chat_type 在会话里有子 Agent 时报 agent_team,否则报 chat(packages/tui/src/tui/app-composition.ts:514);@ 菜单的点击只会报 file 或 directory,类型定义里的其余几种取值 TUI 用不到(packages/tui/src/analytics/tui-business-event-tracker.ts:84);tui_launch 在首帧画出后报 cold,从挂起恢复时报 hot(launcher.ts:547)。命令行的 mcode login 不传遥测客户端,走那条路登录不产生事件(packages/tui/src/cli/auth-command.ts:75)。

错误诊断与本地记录

诊断相关的本地文件都在数据目录的 v2/observability 下:

子目录内容会不会上传
cli/incidentsTUI 事故记录(incident-reporter.ts:130)同意诊断且已登录时批量上传
mcodeTUI 观测日志:启动各阶段耗时、终端画像、主题探测、事件流重连、进程停止原因,保留 7 天(packages/tui/src/observability/local-observability.ts:168)不自动上传
logs运行时日志(packages/tui/src/runtime/logging.ts:41)不自动上传

三类文件都会在用户主动 /feedback 时以计数形式进入诊断包(只留本地的事故记录也算在内),见文末。观测日志里预留了采样渲染耗时的 observeRender(),但公开源码里没有任何调用方。

TUI 事故记录器的流程:

图表加载中…

要点:

  • 记什么:9 种事件类型,从启动失败、渲染失败、运行时桥接错误到上次非正常退出(TuiIncidentEventType,incident-reporter.ts:20)。只留固定的类别、阶段、严重度、错误名与错误码、HTTP 状态、最多 20 个预定义的面包屑,自由文本、堆栈、调用方上下文一概不收;具体字段见 docs/tui-capabilities.md 的“Diagnostic upload privacy”。
  • 限流:每次运行最多 100 条非致命事故,同一指纹 60 秒内去重(致命事故 2 秒);目录里最多留 200 个文件、7 天(incident-reporter.ts:136),清理时先删 local-,再删 sent-,最后才动 pending-。
  • 非正常退出:启动时写一个 active- 开头的标记文件,正常结束时删掉;下次启动若发现对应进程已不在,就补记一条 cli_unclean_exit(incident-reporter.ts:457)。
  • 上传:只读 pending- 开头的文件(incident-reporter.ts:743),发送前重新做一遍最小化;事件日志用 AES-256-GCM 加密,密钥由访问令牌经 HKDF 派生,用户 ID 作为 HKDF 的 info 参数(incident-reporter.ts:715);请求带 Bearer 令牌,URL 上带 user_id,单次 10 秒超时,退出时最多再等 300 毫秒。

所以即便内容已经最小化、又做了加密,这个通道仍然是绑定账号的,docs/telemetry.md 也这样写。另一个小差别是国内区的主机:TUI 事故发往 agent.minimaxi.com(incident-reporter.ts:151),LLM 失败报告发往 agent.minimax.cn(packages/local-runtime/src/error-reporting/matrix-api-client.ts:51),路径相同;文档只笼统说“regional MiniMax host”。LLM 失败报告本身只接受 llm_request_failure 一种事件,明文超过 16 KiB 的直接丢弃,不截断(reporter.ts:123)。

自更新

启动检查的入口在 app.start()(packages/tui/src/tui/app.ts:790),更新模块按需动态加载,结果只用来在欢迎页显示一个新版本号(packages/tui/src/update/startup-notice.ts:7)。真正的逻辑在 McodeUpdateApplication(packages/tui/src/update/application.ts:141),先判断这份 mcode 是怎么装上的(packages/tui/src/update/install-source.ts:75):

安装来源怎么认出来怎么升级
官方安装器安装根目录的 install.json 里 updateOwner 为 mcode-installer拉签名清单,下载校验后装进新版本目录
npm 前缀前缀下的 install.json 回执写着 npm-prefix,或前缀目录名为 .minimax-code 且 Node 所在目录里有 npm在暂存目录里 npm install,校验后切换指针
pnpm、yarn、bun 全局包路径匹配各自的全局目录运行对应的全局安装命令
npm 全局包路径等于 npm prefix --global 下的位置npm install --global
认不出以上都不是只打印手动升级命令

官方安装器的安装根取 MCODE_INSTALL_ROOT;没设时,Windows 上是 LOCALAPPDATA 下的 MinimaxCode,其他平台是 XDG_DATA_HOME(缺省为主目录下的 .local/share)下的 minimax-code(packages/tui/src/update/service.ts:260)。升级时:

  1. 按 update.json 选渠道(stable 或 preview,缺省 stable),并行下载 channels/<渠道>.json 与同名的 .sig,8 秒超时(service.ts:103)。清单地址的缺省值是一个阿里云 OSS 路径(service.ts:25)。
  2. 用 install.json 里记的公钥(或 MCODE_RELEASE_PUBLIC_KEY_FILE 指定的文件)调 crypto.verify(null, …) 验签,算法由公钥类型决定(packages/tui/src/update/release.ts:69);再核对渠道、版本与当前平台是否有包。
  3. 下载安装包,比对大小与 SHA-256(service.ts:434),在 versions 目录下的暂存目录里安装、验证版本号,改名为以版本号命名的目录,最后改写 current 文件(service.ts:447)。任何一步失败都删掉暂存目录,旧版本不动。

npm 前缀安装走类似的“暂存、校验、切指针”:在前缀的 releases 目录下建一个暂存目录执行 npm install,版本和入口都验过之后改名为以版本号命名的目录,最后原子地写入 current,代码注释称之为提交点(packages/tui/src/update/versioned-prefix.ts:119)。npm 的安装命令都带 --ignore-scripts=false --include=optional --allow-scripts=<包名>,better-sqlite3 与显式的 --registry(install-source.ts:201),与 README 的安装命令一致。包管理器类的来源在每次启动检查时都要跑一次 npm view <包>@<标签> version --json 查最新版本(install-source.ts:276)。

TUI 里的 /update 还多一道闸:当前会话有回合在跑、有排队消息、有待回答的提问或待处理的审批时一律不让升级(packages/tui/src/tui/controller/product/update-admission.ts:17)。

签到

/checkin 先确认已登录,没登录就先弹登录,登录完接着签到(packages/tui/src/tui/controller/product/command-flow.ts:1449)。之后由 TuiDailyCheckinApplication 执行,同一时刻只跑一个请求(packages/tui/src/checkin/application.ts:34):先 GET /minimax-cloud/api/v1/signin/status 取七天的签到面板,今天已签就直接返回,没有可签的日子就报暂不可用,否则 POST /minimax-cloud/api/v1/signin/claim(packages/tui/src/checkin/http-gateway.ts:17)。网关请求 30 秒超时,遇到 401 强制刷新令牌重试一次;两次请求之间若换了账号就中止,提示重试。

packages/shared/src/daily-signin.ts 是这套协议的共享定义:天的状态、领取结果、面板场景三个枚举,面板与领取结果的校验(必须正好 7 天、编号 1 到 7 不重复、可领取与“今天”各至多一天,daily-signin.ts:92),以及连签天数的计算(daily-signin.ts:70)。它放在跨产品共用的 shared 包里,但公开源码中只有 TUI 的签到模块引用它;界面上的输出是“Checked in: Cycle day N, +P Credits”加一行本周期的 ✓ 与 · 进度(packages/tui/src/checkin/presentation.ts:11)。

诊断命令

入口看什么
/doctor只读的配置检查:config.yaml 是否有效、路径、文件在不在;有效时显示默认模型与提供方,否则列出问题、影响与下一步(packages/tui/src/tui/features/inspection/product-inspection.ts:366)
/status版本、模型与推理强度、账号、Token Plan 的 5 小时与每周额度、权限模式、Git 信息、生效的指令文件
/context运行时上下文快照,按系统提示词、记忆、工具、技能、消息、其他分别统计 token(packages/tui/src/tui/transcript/model.ts:75)
/usage本会话的输入输出 token、缓存命中与上下文占用
/feedback需登录;先预览再提交,附带一个诊断包
mcode telemetry status三个遥测通道的生效状态

/feedback 的诊断包从当前会话的记录,以及最近两天的运行时日志、观测日志、运行时事件、CLI 日志与事故记录里收集(packages/tui/src/runtime/feedback/diagnostic-upload.ts:198),但每个文件只留角色、状态、错误类型、日志级别、HTTP 状态这类计数,文件名换成不透明的编号,策略名为 diagnostic-counts-v1(diagnostic-upload.ts:134)。反馈文字本身会发送出去,只去掉控制字符并把识别出的凭据打码(packages/tui/src/runtime/feedback/ticket.ts:177)。这样的包没法用来复现具体的回答或看原始堆栈,docs/tui-capabilities.md 对此有明确说明。

与文档对照

docs/telemetry.md 与代码基本一致:默认全关、逐项同意、环境变量优先、未同意时事故只留本地且 LLM 报告在缓冲前丢弃,都能在代码里对上。几处文档没写或写得笼统的地方:

  • 运行时指标除了 telemetry.metrics,还要求是托管运行时(host-metrics.ts:112);mcode telemetry status 只按配置与环境变量报告,不反映这一层,也不反映是否已登录。
  • 国内区两类诊断发往不同的主机,见上文。
  • 中文更新日志 0.2.5 那句“登录后自动上报”已经过时。
  • docs/tui-capabilities.md 说更新“public packages use public npm”,这对 npm 类安装成立;官方安装器那条路拉的是 OSS 上的签名清单,安装包地址写在清单里。

下一篇:回顾——把前面各部分串起来再看一遍。

本页目录