CNB CodeBuddy 远程操控
通过 SSH + PTY 远程控制 CNB 云原生环境中的 CodeBuddy CLI,实现非交互式任务下发和结果回收。
前置条件
- CNB 云原生环境已创建,可通过 SSH 访问
- CodeBuddy 已登录(OAuth 中国站扫码,token 持久化)
- 本地机器有 SSH access 和 expect 工具
环境信息模板
每个 CNB 云原生环境需要记录:
SSH_HOST=<环境ID>@cnb.space
WORK_DIR=/workspace
WEBIDE=https://cnb-<env-id>.cnb.space
工作流程
阶段一:环境准备(首次)
1. SSH 连接验证
ssh -o ConnectTimeout=10 -o ServerAliveInterval=5 -o ServerAliveCountMax=12 <SSH_HOST> 'echo OK'
2. 检查 CodeBuddy 状态
ssh <SSH_HOST> 'which codebuddy; codebuddy --version'
ssh <SSH_HOST> 'tcb ai --config'
3. CodeBuddy 登录(如未登录)
必须走中国站 OAuth,CLI 硬编码认证目标为 codebuddy.ai,API KEY 方案不可行(cn 站 key 全部 401)。
推荐方式:用户在 WebIDE 手动登录
1. 打开 WebIDE,在终端运行 tcb ai -a codebuddy
2. 选「Log in via Chinese Site」
3. 扫描 copilot.tencent.com/login?platform=CLI&state=<uuid> 二维码
4. 登录成功后 token 自动持久化到 ~/.codebuddy/
自动登录脚本(需用户配合扫码):
expect << 'EOF'
set timeout 180
spawn tcb ai -a codebuddy
expect -re {Do you trust}
send "\r"
expect -re {Enter to confirm}
send "\r"
expect -re {copilot.tencent.com/login}
# 提取 URL 通知用户扫码,等待回调
expect eof
EOF
4. 信任工作目录
首次启动 CodeBuddy 会询问是否信任目录,选「Trust folder and all subdirectories」。
阶段二:远程任务下发(日常使用)
方法 A:PTY 交互(推荐,实时可控)
步骤:
- 启动 CodeBuddy(PTY 模式保持连接):
ssh -o ConnectTimeout=10 -o ServerAliveInterval=5 -o ServerAliveCountMax=12 -t <SSH_HOST> 'cd <WORK_DIR> && tcb ai'
-
等待启动完成(约 15-20 秒),确认看到
GLM-5.1和? for shortcuts -
用
process write发送指令文本(纯文本,不含回车):
process write sessionId="<id>" data="read README.md and summarize it"
- 用
process send-keys发送回车(必须用 hex,不能用 write 发 \r):
process send-keys sessionId="<id>" hex=["0d"]
-
等待 CodeBuddy 处理(状态变化:
waiting for model→streaming→mixing→ 完成)
- 简单文本回复:10-20 秒
- 需要执行命令的:20-60 秒
- 看到状态栏从streaming · ↓ N tokens恢复到 idle 表示完成 -
如遇工具确认提示(
Do you want to proceed?),自动选 "Yes, and don't ask again":
process send-keys sessionId="<id>" hex=["1b","5b","42"] # Down arrow
# 等待 0.3 秒
process send-keys sessionId="<id>" hex=["0d"] # Enter
- 读取结果:从 session log 中提取,清除 ANSI 码后即为纯文本
关键交互对照表:
| 操作 | hex 值 | 说明 |
|---|---|---|
| 回车(Enter) | ["0d"] |
提交 prompt / 确认选项 |
| 下箭头(Down) | ["1b","5b","42"] |
切换选项 |
| 上箭头(Up) | ["1b","5b","41"] |
切换选项 |
| Tab | ["09"] |
切换模式/选项 |
| Escape | ["1b"] |
取消/退出 |
状态栏含义:
| 状态 | 含义 | 等待时间 |
|---|---|---|
waiting for model |
排队/冷启动 | 5-15 秒 |
Thinking on |
模型推理中 | 5-15 秒 |
streaming · ↓ N tokens |
正在输出 | 持续 |
mixing |
整合工具调用结果 | 5-20 秒 |
swiping |
生成回复 | 5-15 秒 |
| 空闲(无状态) | 完成,可发下一条 | - |
方法 B:expect 脚本(无人值守)
使用 scripts/cb-remote.sh:
scp scripts/cb-remote.sh <SSH_HOST>:/tmp/cb-remote.sh
ssh <SSH_HOST> 'bash /tmp/cb-remote.sh "你的指令" [超时秒数]'
方法 C:nohup 后台(长时间任务)
ssh <SSH_HOST> 'cd <WORK_DIR> && nohup expect /tmp/cb.exp "指令" > /tmp/cb-output.txt 2>&1 &'
# 稍后读取
ssh <SSH_HOST> 'cat /tmp/cb-output.txt | sed "s/\x1b\[[0-9;]*[a-zA-Z]//g" | tail -30'
阶段三:结果回收
- PTY 模式:从 session log 提取,token 计数(↓ N tokens)表示输出量
- expect/nohup:SSH 读取输出文件
- ANSI 清理:
sed "s/\x1b\[[0-9;]*[a-zA-Z]//g; s/]8;;[^]]*]//g"
故障排查
| 症状 | 原因 | 解决 |
|---|---|---|
| 401 认证错误 | token 过期 | WebIDE 重新登录 |
| SSH 2分钟断连 | keepalive 不足 | 加 -o ServerAliveInterval=5 -o ServerAliveCountMax=12 |
| 回车变成文字 | write 发送 \r | 用 send-keys hex ["0d"] |
| Thinking 无响应 | prompt 没真正发送 | 确认用 hex 发回车 |
| 信任目录卡住 | expect 没处理 | 脚本加 exp_continue |
| API KEY 401 | CLI 硬编码 codebuddy.ai | 必须走 OAuth |
| waiting for model 久 | 排队/冷启动 | 等 10-15 秒 |
| 多个 tcb 进程 | WebIDE 残留 | pkill -f tcb 清理 |
| 首次 prompt 自动触发 | 历史残留 | 等 idle 后再发 |
注意事项
- 一次只能一个 CodeBuddy session,多实例会冲突
- SSH 有超时,keepalive 必须 5 秒一次
- CodeBuddy 基于 ink 框架,键盘事件必须用 hex 精确控制
- 必须走中国站(codebuddy.cn/copilot.tencent.com)
- CNB AI Chat API 不可替代:只做聊天补全,不能执行 shell
- Token 持久化:OAuth 登录后 token 存在
~/.codebuddy/,重启环境不丢失