Buck Blog · 博客正文

返回技术分享首页
飞书控制 Claude Code 工作 —— lark-channel-bridge 完整配置指南

飞书控制 Claude Code 工作 —— lark-channel-bridge 完整配置指南

用飞书/Lark 直接指挥你电脑上的 Claude Code(或 Codex CLI)干活:发消息、发图、传文件、切项目、跑代码,人在外面用手机就能让本机 agent 改代码。本文从零开始,覆盖安装、扫码绑定、后台常驻、访问控制、身份授权,以及一路上会踩的坑和解决办法。


0. 一句话说明

lark-channel-bridge 是一个轻量 bot,把飞书消息和本机 Claude Code / Codex CLI 打通:你在飞书私聊发一句话,bridge 转发给本机 agent 执行,结果流式回显到飞书。核心命令一条:

npm i -g lark-channel-bridge && lark-channel-bridge run

扫个码绑定飞书应用,就能用了。本文剩余部分讲清楚每一步的细节和坑。


1. 能做什么

  • 飞书私聊直接发消息,或在群里 @bot,把任务转给本机 Claude Code / Codex CLI。
  • 流式卡片:文本回复和工具调用实时更新在同一张卡片上。
  • 会话延续:每个聊天 / 话题 / 文档评论各自独立,互不串。
  • 排队与合并:短时间连续消息合并处理;任务运行中收到的消息排队到下一轮。/new、/cd、/ws use、/stop 可中断当前任务。
  • 多工作空间:/cd 切项目,/ws 保存复用常用目录。
  • 图片 / 文件:直接发给 bot,bridge 下载到本地交给 agent 处理。
  • 卡片按钮:/help、/ws list、/status 返回可点击交互卡片。

2. 前置条件

依赖 要求
Node.js >= 20.12.0
本机 agent CLI claude(Claude Code)或 codex(Codex CLI),已安装并登录
飞书 / Lark 应用 一个 PersonalAgent 应用(首次扫码向导可帮你创建并绑定)

agent CLI 的"登录"很关键:bridge 拉起的子进程要能用对应 CLI 正常干活,否则 bot 会出现"没反应"。详见第 9 节坑 1。


3. 安装


npm i -g lark-channel-bridge
# 或
pnpm add -g lark-channel-bridge

⚠️ 服务层命令(start / stop / status / restart / unregister)必须先全局安装,不能用 npx。原因见第 9 节坑 10。


4. 首次启动与扫码绑定(bot 应用身份)


lark-channel-bridge run

第一次运行进入扫码向导:

  • 终端渲染二维码。
  • 用飞书 App 扫码。
  • 选择或创建 PersonalAgent 应用。
  • 若终端提示,选择本次要初始化的 agent(claude / codex)。
  • 成功后配置写入 ~/.lark-channel/config.json。

没有指定项目目录也能启动:bridge 会创建一个 profile 托管的默认工作目录,之后在飞书里发 /cd <path> 切到实际项目即可。

已有 PersonalAgent 应用,可传 --app-id 跳过创建流程,命令会提示输入 App Secret:


lark-channel-bridge run --app-id cli_xxx
# 或直接初始化并启动后台服务
lark-channel-bridge start --app-id cli_xxx

Lark 国际版应用加 --tenant lark。


5. 后台常驻(让 bot 一直在线)

run 适合首次配置和前台调试。确认能正常收发消息后,Ctrl-C 停掉,再用系统服务常驻:

lark-channel-bridge start
lark-channel-bridge status
lark-channel-bridge stop

平台映射:

平台 服务方式
macOS launchd 用户代理 ai.lark-channel-bridge.bot.<profile>
Linux systemd 用户单元 lark-channel-bridge.bot.<profile>.service
Windows 任务计划 LarkChannelBridge.Bot.<profile>(launcher 为 .cmd)

daemon 日志:~/.lark-channel/profiles/<profile>/logs/daemon/

多 profile(分别跑 Claude / Codex)

默认用当前激活的 profile,profile use <name> 切换。每个 profile 独立维护应用凭据、会话、工作目录和日志。只有需要同时连多个 PersonalAgent 应用,或分别跑 Claude 和 Codex 时才需要多 profile:


lark-channel-bridge start --profile claude --agent claude
lark-channel-bridge start --profile codex --agent codex
lark-channel-bridge restart --profile codex
lark-channel-bridge status --profile codex

profile 管理命令:


lark-channel-bridge profile create claude --agent claude
lark-channel-bridge profile list
lark-channel-bridge profile use <name>
lark-channel-bridge profile remove <name>            # 归档(默认)
lark-channel-bridge profile remove <name> --purge --yes  # 永久删除
lark-channel-bridge profile export <name> --output ./profile.json


6. 飞书内斜杠命令速查

命令 作用
/new, /reset 清空当前会话
/cd <path> 切换工作目录并重置会话
/ws list 列出命名工作空间
/ws save <name> 保存当前目录为命名工作空间
/ws use <name> 切换到命名工作空间
/ws remove <name> 删除命名工作空间
/resume 恢复历史会话
/status 查看 profile / agent / 目录 / 会话 / lark-cli 身份状态
/config 调整展示偏好、访问控制、lark-cli 身份策略
/invite user @某人 允许该用户私聊使用
/invite admin @某人 添加管理员
/invite group 允许当前群使用
/invite all group 允许 bot 所在的所有群使用
/remove ... 移除对应访问控制条目
/stop 停止当前 run
/timeout [N\|off\|default] 设置/清除当前会话 idle watchdog
/ps 列出本机 bridge 进程
/exit <id\|#> 停止指定 bridge 进程
/reconnect 强制 WebSocket 重连
/doctor [描述] 执行低敏诊断
/help 帮助卡片

私聊不需要 @;群和话题群默认必须 @bot,@all 被忽略。


7. 访问控制(谁能用)

默认私有:开箱即用,只有"你"(应用创建者/owner)能在私聊和群聊里用 bot。其他人消息被静默忽略(不回"你没权限",避免暴露存在)。

想让别人也能用,加进三类名单:

名单 控制谁 加入 移除
允许私聊的用户 谁能私聊 bot /invite user @某人 /remove user @某人
响应的群 bot 在哪些群对群内所有人响应 /invite group / /invite all group /remove group
管理员 谁能改设置、任意群用 bot /invite admin @某人 /remove admin @某人

常见配置:

  • 只给自己用 → 什么都不用做。
  • 让同事能私聊 → /invite user @他
  • 让某个群全员可用 → 在那个群发 /invite group
  • 首次一次性开放所有群 → /invite all group,再 /remove group 删不想要的。
  • 拉人一起当管理员 → /invite admin @他

改完下一条消息即生效,不用重启。群默认要 @bot 才回,这是另一个开关(/config →"群里需要 @ bot")。


8. 可选:绑定个人身份授权(lark-cli auth login)

上面扫码绑定的是应用/bot 身份。如果还想让 agent 访问你的个人资源(日历、邮箱、云盘等),需要额外的用户身份授权(OAuth 设备流)。

两阶段授权流程(关键,务必前台阻塞)


# 阶段 1:秒返回,拿 verification_url 和 device_code
lark-cli auth login --no-wait --json [--recommend | --domain ... | --scope ...]

stdout 里有 verification_url 和 device_code。把 verification_url 原样发给用户(用代码块,不要 Markdown 链接化)。


# 阶段 2:前台阻塞,等用户点完(或 10 分钟超时)
lark-cli auth login --device-code <code>

用户点完后,继续在当前 profile 环境执行:


lark-cli config strict-mode off
lark-cli config default-as auto

这会让当前 profile 同时可用应用身份和已授权用户身份。

⚠️ 为什么不能后台跑、为什么必须私聊——见第 9 节坑 2、坑 3。授权期间你发的新消息会自动排队,不会打断阻塞。


9. 踩坑与解决(重点)

下面是实际部署过程中验证过的问题和完整解决办法。

坑 1:systemd 后台运行时 claude 子进程报 "Not logged in"

  • 现象:前台 run 一切正常;start 装成 systemd 服务后,bot 不回复,日志显示 claude 子进程 Not logged in。
  • 原因:systemd 服务默认不继承你 shell 里的环境变量。你平时在终端里配好的 ANTHROPIC_*(登录态 / 自定义端点)不在 service 环境里,bridge 拉起的 claude 子进程继承到的是空环境。
  • 解决:给 service 加一个 drop-in 环境文件补齐变量:

  mkdir -p ~/.config/systemd/user/lark-channel-bridge.bot.<profile>.service.d
  cat > ~/.config/systemd/user/lark-channel-bridge.bot.<profile>.service.d/env.conf <<'EOF'
  [Service]
  Environment="ANTHROPIC_BASE_URL=https://api.deepseek.com/anthropic"
  Environment="ANTHROPIC_AUTH_TOKEN=sk-xxxxxxxxxxxxxxxx"
  Environment="ANTHROPIC_MODEL=deepseek-v4-pro"
  Environment="CLAUDE_CODE_SUBAGENT_MODEL=deepseek-v4-pro"
  Environment="CLAUDE_CODE_MAX_CONTEXT_TOKENS=1000000"
  EOF
  chmod 600 ~/.config/systemd/user/lark-channel-bridge.bot.<profile>.service.d/env.conf
  systemctl --user daemon-reload
  lark-channel-bridge restart --profile <profile>
  

(示例是 DeepSeek 的 Anthropic 兼容端点;用官方 Claude 就填官方 ANTHROPIC_BASE_URL 或直接不设,用你自己的 key。)

  • 安全注意:token 是明文存在这个文件里的,务必 chmod 600 收紧权限。

坑 2:OAuth 授权必须前台阻塞,不能丢到后台

  • 现象:把 lark-cli auth login 用后台方式跑,用户还没点完授权,进程就被回收,授权永远失败。
  • 原因:bridge 在 run 结束后会回收 agent 子进程,你 spawn 的任何后台 bash 也跟着一起死。
  • 解决:用第 8 节的两阶段流——先 --no-wait --json 秒返回拿链接,再把 --device-code <code> 前台阻塞等用户点完。

坑 3:群里发起设备流授权,token 会被抢

  • 现象:device flow 的 verification_url 发到群里,谁先点谁拿走 token,可能绑到错的身份。
  • 解决:只在私聊(p2p)发起授权。群聊里用户要求授权时,回复"授权要在私聊里做,请单独私信我"。

坑 4:授权成功后还要收敛身份策略

  • 现象:lark-cli auth login 已成功,但 --as user 仍被 strict-mode / default-as 拒绝。
  • 解决:授权完成后顺序执行 lark-cli config strict-mode off 和 lark-cli config default-as auto。不要重新 bind,不要绕回本机普通配置。

坑 5:不要 unset bridge 注入的环境变量

bridge 会给子进程注入 LARK_CHANNEL、LARK_CHANNEL_HOME、LARK_CHANNEL_PROFILE、LARK_CHANNEL_CONFIG、LARKSUITE_CLI_CONFIG_DIR 等变量,指向当前 profile。不要 unset、不要 env -u LARK_CHANNEL 绕回本机普通配置,否则会读写错 profile。

坑 6:提示 "lark-channel context detected but not bound"

  • 现象:lark-cli 报 lark-channel context detected but lark-cli is not bound to it。
  • 解决:停止当前操作,请用户重启 bridge 或运行 bridge doctor / preflight。不要改用普通 profile、不要自行 bind、不要直接读 config.json 里的账号密钥。

坑 7:bot 只有被真实 @ 才能收到群消息

飞书机制:bot 只有被结构化 @ 才能收到群消息。纯文本写 "@名字"、或不带 @ 的普通回复,其他 bot 一律收不到。需要某个 bot 接着处理时,必须真实 @ 它(open_id 优先从 bridge_context.mentions 取)。默认不要 @ 其他 bot,互相 @ 会死循环。

坑 8:交互卡片回调按钮需要签名 token

想发可点击的回调卡片,按钮 value 对象必须同时含 __bridge_cb: true 和 bridge_token: "<signed token>":


{
  "tag": "button",
  "text": { "tag": "plain_text", "content": "方案 A" },
  "behaviors": [{
    "type": "callback",
    "value": {
      "__bridge_cb": true,
      "bridge_token": "SIGNED_TOKEN_FROM_LARK_CLI",
      "choice": "a"
    }
  }]
}

  • bridge_token 必须由 bridge-aware 的 lark-cli 回调签名能力生成,不要猜测、伪造、复用或手写。
  • 如果当前 lark-cli 不能生成 bridge_token,不要发回调按钮,改成普通展示卡,让用户用文字回复选择。
  • 用户点击后,bridge 校验 token,把 payload(去掉 __bridge_cb 和 bridge_token)作为 [card-click] {...} 发回给你,session 自动续上。

坑 9:interactive card 的 schema 2.0 vs v1 降级

飞书 v2 CardKit(schema 2.0)会双发:elements 是 v1 兼容降级("请升级至最新版本客户端"),user_dsl 才是真卡内容。解析卡结构时认 user_dsl,别被 elements 的降级文案误导。零文字 v1 卡(纯按钮/图片/装饰)SDK 抓不到字时,bridge 会把整段 raw JSON 灌进来。

坑 10:服务层命令必须全局安装

start / stop / status 等 daemon 命令不能用 npx。daemon 的 systemd unit / launchd plist / Windows 任务会记录 bridge CLI 的路径;如果这个路径来自 npm 临时缓存,缓存清掉后 daemon 就起不来。先 npm i -g lark-channel-bridge。run 用 npx 单次启动没问题。

10. 数据目录与配置参考

路径 内容
~/.lark-channel/config.json root config(profiles + active profile)
~/.lark-channel/active-profile 最近选择的 profile
~/.lark-channel/profiles/<profile>/sessions.json 会话状态
~/.lark-channel/profiles/<profile>/secrets.enc profile 本地加密 secret
~/.lark-channel/profiles/<profile>/lark-cli/ 当前 profile 的 lark-cli 目录
~/.lark-channel/profiles/<profile>/media/ 附件缓存
~/.lark-channel/profiles/<profile>/logs/ 结构化运行日志
~/.lark-channel/registry/processes.json 本机进程注册表
~/.lark-channel/registry/locks/ profile lock 和 app lock

设置 LARK_CHANNEL_HOME=/path/to/state 可迁移整棵本地状态目录;LARK_CHANNEL_LOG_DAYS 调整日志保留天数。

权限模式(permissions.defaultAccess / maxAccess)

新 profile 默认都是 full(保证 bridge 本地工具、授权流程、文件写入完整可用)。收紧可改 workspace 或 read-only:

Bridge access Claude 权限模式 Codex 模式
full bypassPermissions danger-full-access
workspace acceptEdits workspace-write
read-only plan read-only

lark-cli 身份策略

每个 profile 用独立 lark-cli 目录 ~/.lark-channel/profiles/<profile>/lark-cli。默认 bot-only(只访问应用/bot 身份);完成用户授权后可切 user-default(保留应用身份 + 允许已授权用户身份)。owner/admin 用 /config 切换,/status 显示 lark-cli: app 或 lark-cli: user-ready。


11. 常见问题 FAQ

bot 没反应 / agent 不回复 → 通常是本机 claude/codex 没登录,或当前会话指向不存在的目录。发 /status 看状态,/new 重开会话。(后台运行时还可能是坑 1 的环境变量问题。)

卡片停在最后一帧不动(假死) → idle 探活:/config 设全局值,或 /timeout 10 只对当前会话;/timeout off 关闭,/timeout default 回退全局。

图片发过去 agent 说看不到 → 升级到最新版(0.1.0 之前有文件名去重 bug)。


12. 参考

  • 官方中文 README(本文的权威来源):npm 包内 node_modules/lark-channel-bridge/README.zh.md
  • 飞书效果文档:https://larkcommunity.feishu.cn/docx/OaRIdFIRFoLM3xxTmKwcetHqn5e
  • Claude Code 安装:https://docs.anthropic.com/en/docs/claude-code/quickstart
  • Codex CLI 安装:https://developers.openai.com/codex/cli
  • 许可:MIT