1. 结果摘要

今日页的文字输入已通过 RecordUnderstandingGateway 调用 record-understanding-v2,由 CloudBase hy3 生成未确认候选。生产函数运行在 Nodejs20.19,超时 60 秒,开启云端依赖安装;旧的 record-understanding 保留为短期回退,不再接收客户端新请求。

本次故障不是模型排队繁忙。云函数在约 10ms 内失败,最终从云端日志确认根因是 AI SDK 将 cloudbase.SYMBOL_DEFAULT_ENV 当作普通环境 ID 拼接,触发:

```text

TypeError: Cannot convert a Symbol value to a string

```

修复方式是使用 AI 请求路径支持的 cloudbase.SYMBOL_CURRENT_ENV,并将生产调用迁移到 Node 20 新函数。

2. 用户侧现象

- 今日页发送文字后只显示“AI 服务暂时繁忙,尚未生成记录”。

- 客户端只能看到 UNDERSTANDING_MODEL_FAILED 和业务 requestId。

- 开发者工具同时出现 TDesign t.woff 的 ERR_CACHE_MISS,但该警告只影响图标字体缓存,与 AI 云函数失败无关。

- 早期还出现过候选组件路径找不到、文字输入每输入一个字符就失焦等独立问题,均已分别修复,不能与模型故障混为一谈。

## 3. 排查过程

### 3.1 先按层隔离

1. 确认文字消息已进入今日页处理函数,排除输入组件和发送事件问题。

2. 使用客户端返回的业务 requestId 查询 CloudBase 函数日志。

3. 对比函数执行耗时:约 10ms 即失败,说明不是模型生成超时或排队。

4. 增加脱敏诊断日志,分别捕获模型创建、请求抛错、空响应和错误响应。

5. 核对仓库配置与云端真实配置,发现仓库要求 Node 20,但旧函数实际仍运行 Node 16。

### 3.2 处理运行时漂移

- cloudbaserc.json 已声明 Nodejs20.19,但旧函数创建时固定为 Nodejs16.13。

- CLI 的配置更新提示成功,云端详情仍显示 Node 16;底层 SCF 接口进一步明确返回“函数 Runtime 不支持修改”。

- 为避免删除函数和中断服务,新建 record-understanding-v2,复用同一源码目录,首次创建时指定 Node 20。

- 客户端网关切换到 v2,旧函数暂时保留为回退。

### 3.3 定位 SDK 根因

迁移 Node 20 后,脱敏日志终于保留了原始异常类型:

```text

TypeError: Cannot convert a Symbol value to a string

```

检查当前锁定版本的 @cloudbase/node-sdk 源码发现:

- 普通请求路径会分别处理 SYMBOL_CURRENT_ENV 与 SYMBOL_DEFAULT_ENV。

- AI 请求适配器只识别 SYMBOL_CURRENT_ENV。

- 传入 SYMBOL_DEFAULT_ENV 时,AI 路径会把 Symbol 当作字符串环境 ID 使用。

因此最终将模型初始化改为:

```ts

const app = cloudbase.init({

env: cloudbase.SYMBOL_CURRENT_ENV,

timeout: 60_000,

});

```

## 4. 同期完成的会话修正

- 本地今日会话升级为 schema v2。

- 存储键按稳定 userId 与 Asia/Shanghai 自然日隔离。

- 跨日创建空会话,不继续展示昨天的对话或草稿。

- 当天每个用户最多保留最近 80 条消息。

- 页面停留跨午夜时,在下一次输入前切换到当天会话。

## 5. 最终工程边界

- 小程序只通过 RecordUnderstandingGateway 请求业务结果,不直接依赖模型 SDK。

- AI 云函数只生成未确认候选,不写健康记录。

- 用户确认后才由 records 云函数写入正式数据。

- 日志只记录错误码、请求标识、输入长度、候选数量和 token 汇总,不记录健康原文。

- CloudBase 是过渡适配层,接口契约继续为未来自有服务器迁移保留。

## 6. 验证清单

每次修改 AI 云函数后至少完成:

1. 执行 npm run check,保证类型、领域规则、网关契约和云函数构建全部通过。

2. 执行 tcb config diff fn <function>,核对仓库配置和云端配置。

3. 执行 tcb fn detail <function>,确认实际运行时、超时、代码大小、依赖安装和部署状态。

4. 在开发者工具或真机使用可信微信上下文发送一条真实文字记录。

5. 成功时确认返回候选;失败时按业务 requestId 查询函数日志。

6. 确认日志没有原始健康文本、OpenID、密钥或完整模型提示词。

## 7. 可复用经验

1. 前端的通用错误文案不能作为根因。必须保留稳定错误码和可关联的请求标识。

2. “部署成功”只代表代码包上传完成,不代表运行时、依赖和真实调用链正确。

3. 仓库配置不是云端事实。配置漂移必须通过云端详情和底层接口核验。

4. 对不可原地升级的运行时,优先使用版本化新函数迁移,验证后再决定旧函数下线时间。

5. 第三方 SDK 的同名环境常量不一定适用于所有模块;出现类型异常时应检查当前锁定版本源码,而不是继续猜测额度或网络问题。

6. 日志诊断要覆盖对象创建、请求抛错、错误响应和无效输出四个阶段,同时保持健康数据最小披露。

7. 浏览器、渲染层和业务云函数的错误要分层判断。TDesign 字体缓存警告不能解释服务端 AI 失败。

## 8. 相关提交

- 8dc1703:绑定云函数环境并修正候选组件路径。

- a8fdd51:修正文字输入焦点。

- 0113e60:按自然日隔离今日会话并补充 AI 响应诊断。

- ca801c9:记录模型请求异常。

- d130935:覆盖模型初始化异常。

- 6282aa7:切换 Node 20 的 record-understanding-v2。

- 246952e:使用 SYMBOL_CURRENT_ENV 初始化 AI 模型。