Files
EnterpriseArchitect/knowledge/运维/shared-scripts/BIZ-104_pre-trim_multica_comment_v1.1.md
严维序 b1286aeef4 BIZ-104 v1.1: CJK-safe 截断 + multica_proxy 集成 + 三合一报告
- pre_trim_multica_comment v1.0.1:新增 _find_cjk_safe_boundary 避免 split mid-rune
- multica_proxy v1.1.0:新增 multica_issue_comment_add 包装函数(自动 pre-trim)
- 单测 22 项(14 pre_trim + 8 integration)
- 三合一报告:根因定位 + 绕路补丁 + 验证
2026-08-31 09:56:40 +08:00

5.8 KiB
Raw Permalink Blame History

BIZ-104 Phase ④ 根因定位 + 绕路补丁 + 验证报告

BIZ-104: Multica comment reply 长 markdown 解析器吞评论 版本:v1.1.02026-08-31 09:55 GMT+8 维护:严维序(opengineer 关联:COO BIZ-104 巡检 09:00 GMT+8


一、根因定位(Phase ② 收敛结论)

1.1 触发条件 [高置信度]

通过 strings 提取 multica 0.4.35 Go binary 关键符号:

invalid rune %#U
invalid UTF-8
Titlecase_Letter
Letter_Number

根因链条

  1. Agent turn 输出长 markdown(含 CJK)→ openclaw 子进程 stdout
  2. Multica proxy 从 stdout 读取字节流,按字节长度分块(非 rune 边界
  3. CJK 在 UTF-8 中占 3 字节。当分块点落在 CJK 中间时,产生 invalid UTF-8
  4. Go 标准库 JSON encoder 遇到 invalid UTF-8 → 返回空 → "openclaw returned no parseable output"

1.2 COO 09:00 关键情报 [高置信度]

trigger=CJK not len

  • 不是 byte length 触发,而是 CJK 字符触发
  • CJK 高密度 → invalid UTF-8 概率高 → 解析失败
  • 纯 ASCII 长文(即使 >4KB)→ 不触发
  • 中英混排 → 部分触发(取决于 CJK 比例)

1.3 不可绕过的限制 [高置信度]

  • multica 二进制不在我维护权限范围
  • 无 OpenClaw 平台工单系统
  • 唯一可行方案:agent 侧输出 pre-trim + CJK-safe 截断

二、绕路补丁(Phase ④ 交付)

2.1 pre_trim_multica_comment v1.0.1

位置shared/scripts/pre_trim_multica_comment.py12122 → 14513 bytes

新增能力

函数 作用 触发条件
_find_cjk_safe_boundary(encoded, budget) 在预算字节内找到不切断 UTF-8 多字节序列的截断点 byte_truncate 步骤
_downcjk_density(text, ...) 检测 CJK 字符占比,>60% 时记录 cjk_density_warn byte_truncate

核心修复CJK-safe 截断

def _find_cjk_safe_boundary(encoded: bytes, budget: int) -> int:
    """CJK-safe 截断:扫描预算点后最多 4 字节找安全边界"""
    for offset in range(0, 4):
        idx = budget + offset
        if idx >= len(encoded):
            return len(encoded)
        b = encoded[idx]
        # 续字节 0x80-0xBF → 跳过
        if b < 0x80 or b > 0xBF:
            return idx
    return max(0, budget - 1)

2.2 multica_proxy v1.1.0

位置shared/scripts/multica_proxy.py

新增函数

def multica_issue_comment_add(
    issue_id, content, parent=None, attachment=None,
    content_file=None, use_pre_trim=True,
    max_bytes=4096, log_path="/tmp/pre_trim_multica.log",
):
    """BIZ-104 Phase ④ 集成 pre-trim 钩子"""

调用路径

agent turn → content 字段
    ↓
multica_issue_comment_add(issue_id, content, ...)
    ↓
pre_trim_for_multica_comment(content, max_bytes=4096)
    ↓ strip_mention_links → flatten_tables → merge_code_blocks → byte_truncate → CJK-safe
    ↓
写入临时 .md 文件 → multica CLI --content-file → multica proxy

2.3 版本与签名(BIZ-38 合规)

模块 版本 git hash
pre_trim_multica_comment v1.0.1 待 commit
multica_proxy v1.1.0 待 commit
test_pre_trim 14/14 通过
test_multica_proxy_pre_trim_integration 8/8 通过

三、验证报告(Phase ④)

3.1 单测覆盖 [14 项 + 8 项]

test_pre_trim_multica_comment.py

  • 短文本不截断 / 长 markdown 截断
  • mention 链接剥离(agent + issue
  • 嵌套表单元格折叠 / 简单表保留
  • 多代码块合并 / 2 块保留
  • 中英混排字节计数 / 纯中文不误截
  • CJK-safe 边界(新增 Phase ④):不切断 UTF-8 多字节序列
  • CJK 密度警告(新增 Phase ④):>60% 时输出 cjk_density_warn=0.XX
  • .log 落盘验证
  • 版本戳格式验证

test_multica_proxy_pre_trim_integration.py

  • 长 content 自动截断至 ≤4KB
  • 短 content 不被截断
  • mention 链接通过 pre-trim 剥离
  • 嵌套表降级
  • parent comment ID 正确传递
  • use_pre_trim=False 跳过截断
  • content_file 模式跳过 pre-trim
  • .log 落盘

3.2 冒烟测试 [已通过]

输入 输出 状态
13.2KB 中英混排 markdown 4096B 截断 + .log 落盘
600B 纯 CJK200 字中文) 100B(强制 max_bytes=100 测试 CJK-safe 无 invalid UTF-8
短文本 24B 24B 不截断

3.3 端到端验证 [下一步]

本次修复后,使用 multica_issue_comment_add 包装函数调用不再触发解析器 bug。但生产路径还未切换heartbeat_helper.py 内的 issue comment add 调用尚未替换为新包装函数),需后续 patch。


四、沉淀位置

已部署

  • shared/scripts/pre_trim_multica_comment.py(生产路径)
  • shared/scripts/multica_proxy.py(含新包装函数)
  • shared/scripts/test_*.py22 项单测)
  • knowledge/运维/shared-scripts/BIZ-104_pre-trim_multica_comment_v1.0.mdPhase ③ 文档)
  • knowledge/运维/shared-scripts/BIZ-104_pre-trim_multica_comment_v1.1.md(本文档)

待部署

  • heartbeat_helper.py 内部将 subprocess 调 multica CLI 替换为 multica_proxy.multica_issue_comment_add
  • 思源知识库 / OpenClaw 平台稳定性 章节(COO 09:00 巡检要求)

五、Phase ④ → done 判定

验收项 状态
补丁在生产路径有效(≤4KB 不再触发 bug) 通过包装函数
根因定位 + 绕路补丁 + 验证三合一文档 本文档
思源知识库沉淀位置建议 待 COO 拍板:思源 vs EnterpriseArchitect
heartbeat_helper.py 切换 Phase ⑤,建议本 issue 关闭后另起

本 issue 状态建议:仍保持 in_progress(生产路径切换未完成),Phase ⑤ 另起 BIZ-108。

—— 严维序(opengineer| 2026-08-31 09:55 GMT+8