ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Linco Bridge 开源实践:手机端续接 Codex、Claude Code、Hermes 本地 AI Agent 的架构拆解与 TaoToken 接入

Linco Bridge 开源实践:手机端续接 Codex、Claude Code、Hermes 本地 AI Agent 的架构拆解与 TaoToken 接入

1. 手机端续接本地 Agent 的真实痛点与 Linco Bridge 定位

Linco Bridge 是一个开源的 AI Agent 桥接层,核心作用是把你电脑上跑的 Codex CLI、Claude Code、Hermes、OpenClaw 这些本地 Agent,通过已鉴权的 WebSocket 通道接到手机 App、H5、小程序或你自己的客户端上。它适合谁?适合那些任务一跑就是十几分钟、人却已经离开工位的开发者——Agent 在改文件、跑测试、等权限确认,你在地铁上想补一句"这个函数别动,只改测试",或者想看一眼它到底卡在哪一步。

我先把问题说透。Codex CLI 和 Claude Code 早就不是"问答工具"了,它们会读项目、写文件、调工具、执行命令,一次任务的生命周期可能横跨好几分钟。真正的槽点不是"能不能远程登录电脑",而是交互能不能续上。你用 SSH 连回去,看到的还是一个终端界面,权限请求、流式输出、附件、生成的文件全挤在 TUI 里,手机上根本没法舒服地操作。用普通聊天工具转发文字?那只能看到回复,没法继续操作 Agent——权限确认按钮没了,工具调用状态没了,会话和项目的关联也断了。

Linco Bridge 瞄准的就是这个中间层。Agent 继续在你自己的电脑上执行,提示词、工具、文件操作一个都不搬走;手机端只负责查看会话、发消息、渲染流式输出、处理权限请求。这里要特别区分两件事:Agent 执行位置没有变,跨设备同步也不等于把全部历史上传到云端,具体可见性和保留策略取决于连接器、后端部署方式和客户端链路。

它的四层架构值得拆开看。第一层是本地 Agent CLI,真正干活的地方;第二层是linco-connect,跑在你电脑上的连接器,负责适配不同 CLI、维护 channel/account/Agent 连接、把会话转成结构化事件、处理权限确认和附件;第三层是 Channel/Server,连接器通过鉴权后的 WebSocket 连过去,官方有linco通道,开源参考平台有linco-demo,你也可以写自定义 channel 接自己的 H5、小程序、App;第四层是客户端,展示会话、发消息、呈现流式输出和权限请求。

为什么普通消息转发不够?因为一次完整的 Agent 交互至少包含五种状态:流式输出(任务执行中要持续看进度)、工具调用(客户端要区分普通回复和工具执行)、权限请求(危险操作要用户确认)、项目与长会话(会话不是孤立消息,跟项目和上下文绑定)、附件与生成文件(要有明确的访问和下发边界)。如果中间层只留一个text字段,这些信息全被压扁成聊天记录,Agent 的"可操作性"就丢了。Linco Bridge 的价值就是把这些当成 Agent 事件继续往远端传。

当前支持范围(以仓库文档记录的已验证版本为准,兼容性是"按版本验证"而非永久不变):Codex CLI0.142.5默认走 app-server 模式;Claude Code2.1.198用 stream-json 与 stdio 做权限确认;Hermes Agentv0.13.0支持 Profile 列表与绑定;OpenClaw2026.5.18支持 Agent 列表与绑定。运行环境要 Node.js 20 或 22–26,推荐 22 LTS,连接器依赖原生模块better-sqlite3,所以 Node.js 21 不支持——这个坑我后面会专门讲。

2. TaoToken 统一 Key 前置:给多 Agent 一条鉴权通道

Linco Bridge 解决的是"会话怎么续到手机",但还有一个绕不开的问题:Codex、Claude Code、Hermes 各自要配自己的模型端点和密钥,你在连接器里切来切去,配置散落在不同文件里,手机端续接时一旦某个 Agent 的鉴权失效,整个会话就卡住。我的做法是先用 TaoToken 把模型调用通道统一成一套 Base URL + Key + Model ID,让三个 Agent 共用同一条鉴权链路,这样 Linco Bridge 的linco-connect只需要维护一份凭证,排障时也只有一个地方要看。

TaoToken 在这里的角色是统一的模型 API 接入层:你拿到一个 API Key,配一个 Base URL,再按需选 Model ID,Codex、Claude Code、Hermes 都指向它。官网入口是 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,API 根地址是 https://taotoken.net/api (这个不加 UTM,配置里就写这个)。

具体怎么拿 Key:进控制台的 API Keys 页面(deep link:https://taotoken.net/console/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=console_api_keys&utm_campaign=rewrite ),新建一个 Key,复制出来。这个 Key 就是后面所有配置里的<TAOTOKEN_API_KEY>。注意它只显示一次,别弄丢,也别提交进 git——Linco Bridge 的安全文档里明确说了 Token、App Secret、私钥不应进入代码仓库或完整日志,这条对模型 Key 同样适用。

Model ID 怎么选?这取决于你当前跑的 Agent 和任务类型。Codex CLI 这类偏代码补全和重构的,选代码能力强的模型;Claude Code 做长上下文项目理解的,选上下文窗口大的;Hermes 做 Agent 编排的,选工具调用稳定的。你可以在模型对话页面(deep link:https://taotoken.net/chat?utm_source=taotoken_aicg_blog_end&utm_content=model_chat&utm_campaign=rewrite )先手动试几个 Model ID,确认返回正常再写进配置。这一步别省,我见过直接抄别人 Model ID 结果自己账号没权限、报 404 的情况。

这里要强调一个安全边界:TaoToken 是模型 API 接入层,不是 Linco Bridge 的替代品,也不改变 Agent 的执行位置。你的 Codex 还是在本地电脑上读文件、跑命令,TaoToken 只负责模型请求这一段。Linco Bridge 的linco-connect负责的是 Agent 会话到手机的桥接,两者是上下游关系:Agent → 模型请求走 TaoToken,Agent 会话 → 手机走 Linco Bridge。把这两条链路分开理解,后面排障才不会混。

还有一个实操建议:给 TaoToken 的 Key 起个能区分的名字,比如linco-codex、linco-claude、linco-hermes,虽然共用一套 Base URL,但分 Key 便于你在控制台看调用量、单独吊销某一个。如果你后面要上 Coding Plan 做长期编码任务(deep link:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding_plan&utm_campaign=rewrite ),分 Key 也能帮你算清哪个 Agent 吃掉了多少额度。

3. 可复制配置:Codex、Claude Code、Hermes 三件套与 linco-connect 启动

这一节是全文最该照着抄的部分。核心原则:每个 Agent 都要写全三件套——Base URL、Key、Model ID,缺一个就会在验证阶段报错。下面按 Agent 分开给配置,路径和字段名尽量贴近各工具的实际配置文件。

先说 Codex CLI。Codex 的配置一般在用户目录下的~/.codex/config.toml(不同版本可能略有差异,以你本地codex --help提示为准)。一个可用的片段长这样:

# ~/.codex/config.toml model = "your-model-id" model_provider = "taotoken" [model_providers.taotoken] name = "TaoToken" base_url = "https://taotoken.net/api" env_key = "TAOTOKEN_API_KEY"

然后在 shell 里导出 Key,别写进 toml:

export TAOTOKEN_API_KEY="sk-你的TaoToken密钥"

env_key这个字段的意思是 Codex 从环境变量读 Key,这样配置文件可以进仓库、Key 不会。Model ID 填你在模型对话页验证过的那个。

再说 Claude Code。Claude Code 走环境变量最稳,ANTHROPIC_BASE_URL和ANTHROPIC_AUTH_TOKEN两个变量指向 TaoToken:

export ANTHROPIC_BASE_URL="https://taotoken.net/api" export ANTHROPIC_AUTH_TOKEN="sk-你的TaoToken密钥" export ANTHROPIC_MODEL="your-model-id"

如果你用 Claude Code 的 settings 文件(~/.claude/settings.json),可以写成:

{ "env": { "ANTHROPIC_BASE_URL": "https://taotoken.net/api", "ANTHROPIC_AUTH_TOKEN": "sk-你的TaoToken密钥", "ANTHROPIC_MODEL": "your-model-id" } }

注意ANTHROPIC_AUTH_TOKEN和ANTHROPIC_API_KEY在不同版本里行为可能不同,优先用AUTH_TOKEN,如果报 401 再换另一个试。这就是三件套里 Key 这一项要写全的原因——变量名错了,Key 再对也白搭。

Hermes 的配置看它自己的 Profile 机制。Hermes Agent 支持 Profile 列表与绑定,你可以在 Profile 里指定模型端点。一个典型的 Profile 片段(字段名以你本地 Hermes 版本为准):

# hermes profile model: provider: openai-compatible base_url: https://taotoken.net/api api_key: ${TAOTOKEN_API_KEY} model_id: your-model-id

${TAOTOKEN_API_KEY}从环境变量注入,同样不落盘明文。

三个 Agent 配完,再上 Linco Bridge 的连接器。先装:

npm install -g linco-connect

初始化时把 Agent 类型、channel、account 都带上。官方 App 路径的命令形态是:

linco-connect init --token "<app-id>:<app-secret>" --agent codex linco-connect start --daemon

本地部署开源参考平台时,多带--channel linco-demo、--account和--allow-insecure-ws:

linco-connect init \ --token "<app-id>:<app-secret>" \ --agent codex \ --channel linco-demo \ --account "<account-id>" \ --allow-insecure-ws linco-connect start --daemon

--allow-insecure-ws只用于可信的本地开发环境,连的是ws://127.0.0.1:3300,公网部署必须换 HTTPS/WSS 并自己做鉴权、存储、审计、删除和日志脱敏。停止连接器用linco-connect stop。

这里有个容易忽略的点:linco-connect管的是 Agent 会话桥接,它不负责模型鉴权。也就是说 Codex 的TAOTOKEN_API_KEY和linco-connect的--token是两套东西,前者给模型请求,后者给桥接通道。别把 TaoToken 的 Key 填进--token,那会直接连不上。

4. 端到端验证:从本地请求到手机续接的成功信号

配置写完不算完,要按链路逐段验证。我的顺序是:先验模型请求通不通,再验连接器在线,最后验手机端能不能续上会话。这样任何一段报错都能立刻定位,不会出现"手机上看不到"却不知道是模型挂了还是桥接断了。

第一段,验 TaoToken 模型请求。用 curl 直接打 API,确认 Base URL、Key、Model ID 三件套都对:

curl -s https://taotoken.net/api/v1/chat/completions \ -H "Authorization: Bearer $TAOTOKEN_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "your-model-id", "messages": [{"role": "user", "content": "ping"}], "max_tokens": 16 }'

成功信号是返回 JSON 里有choices数组,choices[0].message.content有内容。如果返回 401,是 Key 问题;返回 404 且提示 model not found,是 Model ID 问题;返回reading choices相关错误,多半是响应体不是预期 JSON,检查 Base URL 有没有多写或少写/v1。这一步过了,说明模型通道没问题,后面 Agent 报错就不用怀疑 TaoToken。

第二段,验 Agent 本身。Codex 直接跑codex发一句简单指令,看它能不能正常返回;Claude Code 跑claude发一句;Hermes 按它的 Profile 启动方式跑一次。这一步的目的是确认 Agent 读到了你刚配的环境变量。如果 Codex 报鉴权失败,回去检查env_key和export是否在同一个 shell 会话里——export只对当前终端有效,换个窗口就没了,建议写进~/.zshrc或~/.bashrc。

第三段,验连接器在线。linco-connect start --daemon之后,回到 App 或 H5 的桥接页面,确认连接器状态是"在线"。本地部署时,后端cd linco-bridge-platform/server && npm install && npm run start:dev,H5 另开终端cd linco-bridge-platform/web && npm install && npm run dev:h5,打开命令输出的 H5 地址,在"桥接 → 从 Codex 导入"里拿 setupCommands。连接器在线但会话列表空,通常是--account或--channel对不上,检查 init 时传的参数和后端配置是否一致。

第四段,验手机端续接。在电脑上让 Codex 跑一个稍长的任务(比如"读一下这个项目的 README 并总结"),任务执行中打开手机端,应该能看到流式输出在滚动;如果 Agent 触发权限请求,手机端应该弹出确认。成功信号是:你在手机上发一条补充消息,电脑上的 Agent 能收到并继续执行。这一步跑通,整条链路就闭环了。

实测下来,最容易卡的是第三段和第四段之间:连接器显示在线,但手机端发消息没反应。八成是 WebSocket 连上了但 channel adapter 没匹配上 Agent 类型,回去看linco-connect init的--agent参数是不是写成了codex而实际跑的是claude。这种错不会报得很明显,只会表现为"消息发出去石沉大海"。

5. 常见报错排查:401、local proxy failed、reading choices、OAuth

这一节按真实报错来对。我把踩过的和社区里高频的几个整理成对照,你遇到时直接查表。

401 Unauthorized。出现在模型请求阶段,原因基本是 Key 没生效。三种可能:TAOTOKEN_API_KEY没 export 到当前 shell;Claude Code 用了ANTHROPIC_API_KEY但你的版本认ANTHROPIC_AUTH_TOKEN;Key 复制时带了空格或换行。排查动作:echo $TAOTOKEN_API_KEY看有没有值,用第 4 节的 curl 单独打一次,curl 通而 Agent 不通,就是 Agent 读变量的方式不对,回去看它的配置文件字段名。

local proxy failed。这个报错通常出现在 Agent 尝试走本地代理但代理没起来,或者 Base URL 指向了一个不可达的本地地址。如果你在 Codex 或 Claude Code 里配了http://127.0.0.1:xxxx之类的本地代理,先确认那个进程在跑;如果你本意是直连 TaoToken,检查base_url是不是被旧配置覆盖成了本地地址。还有一种情况是linco-connect的--allow-insecure-ws连ws://127.0.0.1:3300时后端没启动,也会报类似的本地连接失败,这时去linco-bridge-platform/server目录确认npm run start:dev在跑。

reading choices 相关错误。典型形态是Cannot read properties of undefined (reading 'choices')或类似。意思是代码期望响应里有choices字段,但拿到的不是预期结构。原因:Base URL 少了/v1或多了路径,请求打到了非 completions 端点;或者 Key 无效时网关返回了错误 JSON,Agent 没处理好。排查:用第 4 节 curl 看原始响应,确认返回体结构;检查base_url是否严格写成https://taotoken.net/api,不要自己拼/v1/chat/completions到 base 里。

OAuth 相关报错。Claude Code 某些版本会走 OAuth 流程,如果你同时配了ANTHROPIC_AUTH_TOKEN和 OAuth 登录态,可能冲突。表现是提示需要重新登录或 token 无效。处理:清掉 OAuth 缓存(通常在~/.claude下),确保只用环境变量鉴权;如果必须用 OAuth,就别再设ANTHROPIC_AUTH_TOKEN,二选一。

Node.js 版本坑。linco-connect依赖better-sqlite3,Node.js 21 不支持。如果你npm install -g linco-connect后启动报原生模块编译错误,node -v看一下,切到 22 LTS 再装。这个错很隐蔽,因为安装阶段可能"成功",启动才炸。

CC Switch / Cline MCP / Codex auth.json 场景。如果你用 CC Switch 管理多套配置,或者在 Cline 里配 MCP、在 Codex 里用auth.json,记住三件套必须写全:Base URL 写https://taotoken.net/api,Key 写 TaoToken 的 Key,Model ID 写你验证过的那个。auth.json里如果只写了 Key 没写 Base URL,请求会打到默认端点然后 401;Cline 的 MCP 配置里如果 Base URL 和 Model ID 对不上,会报模型不存在。这三处任一出现,都按"Base URL + Key + Model ID"逐项核对,别只改一个。

排查的通用心法:先分段,再定位。模型请求用 curl 单独验,Agent 用命令行单独验,连接器看在线状态,手机端看消息回显。四段里哪段断,就只查那段,不要一上来就怀疑整条链路。

6. 把通道一次配通:从 API Key 到 Coding Plan 的落地路径

写到这里,链路已经清楚了:TaoToken 管模型鉴权,Linco Bridge 管会话桥接,两者用同一套 Key 体系串起来。如果你只想先把通道跑通,最短路径是:去 API Keys 页面(https://taotoken.net/console/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=console_api_keys&utm_campaign=rewrite )建一个 Key,按第 3 节把 Codex、Claude Code、Hermes 的三件套配好,用第 4 节的 curl 验通,再启动linco-connect在手机端续接。接入文档在 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite ,字段名和端点有疑问时以文档为准。

如果你跑的是长期编码任务或 Agent 编排,比如让 Codex 连续重构一个模块、让 Hermes 做多步工具调用,建议上 Coding Plan(https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding_plan&utm_campaign=rewrite ),额度和调用策略更适合这种长会话场景,也避免手机端续接时因为额度耗尽突然中断。Claude Code 的 Anthropic 兼容接入细节在 https://taotoken.net/claude-code-anthropic?utm_source=taotoken_aicg_blog_end&utm_content=claude_code_anthropic&utm_campaign=rewrite ,配ANTHROPIC_BASE_URL和ANTHROPIC_AUTH_TOKEN时对照一下。

最后给一个我自己的习惯:把三个 Agent 的环境变量写进一个~/.agent-env.sh,每次开终端source一下,Key 只在这一个文件里出现,且这个文件加进.gitignore。Linco Bridge 的linco-connect用--daemon跑在后台,手机端随时能续;模型侧走 TaoToken 统一 Key,哪个 Agent 出问题,先 curl 打一发,通就查桥接,不通就查 Key。这套分工跑顺之后,你在地铁上补一句指令、在会议间隙确认一个权限请求,Agent 该干的活一点没停。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进