ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Codex 跑 Chrome 扩展自动化任务:Key 用 TaoToken

Codex 跑 Chrome 扩展自动化任务:Key 用 TaoToken 1. 先复现问题Chrome 开关灰色Codex 调度不了浏览器在 Codex 桌面端里准备跑 Chrome 扩展自动化任务最大的拦路虎不是任务本身而是那个一直灰着的「Google Chrome」开关。由于应用商店区域不可达扩展只能靠「开发者模式 → 加载已解压的扩展程序」装进去Chrome 随手分配一个路径派生 ID桌面端的 Native Messaging 握手直接失败。要修这个问题得走 CRX 离线包 manifest key 注入修好之后Codex 还需要一把能调模型的 Key——打开 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_end 创建 KeyTaoToken 会给你一个统一的兼容通道让模型请求从 Codex 顺畅发出去。1.1 从「扩展已加载」到「开关灰色」只差一个 ID第一次遇到这个问题的人大概率和我一样先怀疑扩展本身。明明chrome://extensions里能看到扩展卡片开关也打开了甚至浏览器里已经出现了扩展的图标但 Codex 桌面端设置里的「Google Chrome」开关就是灰色点不动。边栏里那些「打开网页」「读取页面内容」「在页面上执行 JS」的浏览器任务按钮点了也没有任何反应。问题不在扩展能否弹出而在桌面端根本认不出这个扩展。Codex 桌面端通过 Native Messaging 和 Chrome 扩展通信。Native Messaging host 在安装时会把一条通道注册到系统里通道名称里写死了官方扩展 ID。浏览器侧加载的扩展如果 ID 对不上桌面端向这条通道发消息时握手会静默失败于是界面就停留在「扩展未安装」的状态。1.2 这条路绕不过官方扩展 ID所以核心结论是手动安装的关键不是把扩展文件塞进 Chrome而是让加载后的扩展拥有和商店版一模一样的扩展 ID。Chrome 对「有没有 key 字段」的扩展用了完全不同的 ID 派生方式。带 key 的扩展Chrome 用 key 里的公钥做 SHA-256取前 16 字节再按 0-9a-f 到 a-p 的映射表换成 32 个字母得到稳定的扩展 ID。不带 key 的扩展Chrome 直接对加载路径算哈希路径一换 ID 就变。桌面端只认前者。明白了这一层后面的 CRX 离线包 公钥注入方案就顺理成章了。2. 修复思路用官方 CRX 的公钥把扩展 ID 固定下来既然要得到官方 ID最干净的办法就是拿到官方签名的 CRX 包从里面把开发者的公钥提取出来写进manifest.json的key字段。这样 Chrome 加载解压目录时会按公钥重新计算 ID计算结果正好等于官方商店版的 ID。2.1 两种扩展 ID 派生方式对照应用商店版扩展下载时会携带开发者的公钥信息Chrome 安装后按公钥推导出一个固定 ID。路径派生版扩展没有key字段Chrome 只能根据当前文件夹的绝对路径做哈希路径一变 ID 就变。加载方式是否携带 keyID 稳定性桌面端能否识别商店安装是固定不变能开发者模式加载解压目录否随路径变化不能注入 key 后再加载解压目录是固定为官方 ID能这也解释了为什么直接把manifest.json里的name改成官方名字没用。ID 由公钥算出和显示名称没有关系。2.2 修复扩展 ID 只是第一步模型通道也得接上扩展 ID 修好之后Codex 桌面端的开关会亮起但这只代表 Native Messaging 握手成功。真正跑一条「打开某网页并把内容存下来」的自动化任务时Codex 还需要把任务拆解成步骤、生成要执行的指令这一步要调用大模型。模型请求从哪里发出去同样需要配置。这时可以把 Key 换成 TaoToken 的打开 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_end 注册并创建 API Key把 Codex 的 Base URL 指向 https://taotoken.net/api。TaoToken 在这个场景里充当的是「统一接入」的兼容通道Codex 负责调度浏览器自动化任务模型请求走这条通道发出去两边各管一摊。3. 准备材料Python、Chrome SxS、TaoToken 的 API Key动手之前把材料备齐后面每一步才不会卡壳。以下是本文环境对应的清单Windows 11 / Chrome SxS (Canary) / Codex 桌面端 / Python 3.13。3.1 本机需要准备的软件清单Python 3 用来解析 CRX3 文件、改写manifest.json。Chrome 浏览器用 SxS、Canary 或 Stable 都可以本文以 SxS 为例但后面会提到 Stable 在 Native Messaging 注册上更稳。Codex 桌面端需要提前安装并登录。另外下载 CRX 时网络需要能访问到clients2.google.com这个 Google 官方扩展更新接口如果下载失败可以让能正常访问该接口的机器把codex.crx文件下载好再带回本机后续解压、注入、加载这几个步骤都不需要再访问外网。3.2 到 TaoToken 创建 API Key分清官网和接口两个地址准备材料里最重要的一步是拿到 API Key。打开 TaoToken注册账号后在控制台创建 Key创建好之后会得到一串形如sk-...的字符串本文统一用YOUR_API_KEY占位。复制后立刻存好关闭页面可能就看不到了。这里要特别注意区分两个地址在浏览器里打开官网页面、创建 Key、看模型广场用的是https://taotoken.net/?utm_sourcetaotoken_aicg_blog_end而填进 Codex 配置文件的 Base URL是https://taotoken.net/api。后者末尾不带/v1更不要带utm_source之类的追踪参数那只是给人点链接用的。4. 完整操作从下载 CRX 到 Codex 走 TaoToken 的兼容通道4.1 确认官方扩展 ID先确认目标扩展的官方 IDCodex 浏览器扩展的官方 ID 是hehggadaopoacecdllhhajmbjkdcmajg。你可以在 Codex 官方文档里找到对应链接确认也可以直接看 Chrome 应用商店地址中/detail/后面那一段。这个 ID 稍后会在多个环节用到下载 CRX 的请求参数、公钥算完后的校验值、以及最后chrome://extensions里核对扩展卡片。4.2 用 curl.exe 从 Google 官方更新接口拉取 CRXGoogle 的扩展更新接口是公开的Chrome 浏览器自己更新扩展时走的就是这条通道。手动构造一个请求就能拿到带官方签名的 CRX 安装包。Windows 11 自带curl.exe在 PowerShell 里执行时最好写成curl.exe避免和Invoke-WebRequest的别名冲突curl.exe -sSL -o codex.crx https://clients2.google.com/service/update2/crx?responseredirectprodversion154.0.8016.0acceptformatcrx3xid%3Dhehggadaopoacecdllhhajmbjkdcmajg%26uc参数说明prodversion填你当前 Chrome 的版本号acceptformatcrx3要求返回 CRX3 格式xid%3D...%26uc是扩展 ID 加uc标志。下载后可以用Format-Hex确认文件头是Cr24Format-Hex -Path codex.crx | Select-Object -First 1看到输出前四个字节是43 72 32 34也就是 ASCII 的Cr24说明文件结构正确。4.3 用 Python 解压 CRX3CRX3 文件的结构是固定 12 字节文件头加上一段 protobuf 编码的 header最后面跟着一个标准 ZIP 包。先写一个解析函数把 ZIP payload 取出来import struct import zipfile import io from pathlib import Path def unpack_crx_payload(crx_path: str, out_dir: str): data Path(crx_path).read_bytes() magic, version, header_len struct.unpack(4sII, data[:12]) assert magic bCr24, 不是预期 CRX 文件 assert version 3, 当前只处理 CRX3 格式 zip_start 12 header_len with zipfile.ZipFile(io.BytesIO(data[zip_start:])) as zf: zf.extractall(out_dir) print(解压完成输出目录:, out_dir) unpack_crx_payload(codex.crx, codex-chrome-extension)这段代码只做解压不影响原文件。执行后会在当前目录生成codex-chrome-extension文件夹里面就是完整的扩展源码。4.4 提取公钥并注入 manifest.json 的 key 字段这是整个修复流程的关键一步。CRX3 的 header 里有一段 protobuf 结构其中包含开发者的SubjectPublicKeyInfoDER 格式。要把这段二进制公钥提取出来base64 编码后写进manifest.json的key字段Chrome 就会据此重新计算扩展 ID。import base64 import hashlib import json import struct from pathlib import Path EXPECTED_ID hehggadaopoacecdllhhajmbjkdcmajg def read_varint(buf: bytes, pos: int): result 0 shift 0 while True: byte buf[pos] result | (byte 0x7F) shift pos 1 if not (byte 0x80): break shift 7 return result, pos def walk_fields(buf: bytes): fields {} pos 0 end len(buf) while pos end: tag, pos read_varint(buf, pos) field_no tag 3 wire tag 0x7 if wire 2: length, pos read_varint(buf, pos) fields[field_no] buf[pos:pos length] pos length elif wire 0: _, pos read_varint(buf, pos) elif wire 1: pos 8 elif wire 5: pos 4 else: raise ValueError(f不支持的 wire type: {wire}) return fields def compute_id_from_pubkey(pubkey_der: bytes) - str: digest hashlib.sha256(pubkey_der).hexdigest()[:32] table str.maketrans(0123456789abcdef, abcdefghijklmnop) return digest.translate(table) data Path(codex.crx).read_bytes() header_len struct.unpack(I, data[8:12])[0] header data[12:12 header_len] top_fields walk_fields(header) proof top_fields[2] proof_fields walk_fields(proof) pubkey_der proof_fields[1] computed_id compute_id_from_pubkey(pubkey_der) assert computed_id EXPECTED_ID, f公钥算出的 ID 是 {computed_id}与预期不符 print(扩展 ID 校验通过:, computed_id) manifest_path Path(codex-chrome-extension/manifest.json) manifest json.loads(manifest_path.read_text(encodingutf-8)) manifest { update_url: manifest.pop(update_url, https://clients2.google.com/service/update2/crx), key: base64.b64encode(pubkey_der).decode(ascii), **manifest, } manifest_path.write_text( json.dumps(manifest, indent2, ensure_asciiFalse) \n, encodingutf-8, ) print(manifest.json 已注入 key)脚本最后一步做了断言如果公钥算出来的 ID 和官方 ID 不一致直接报错避免把错误的扩展加载进浏览器。执行成功后打开manifest.json能看到顶部多了key字段值是一长串MIIBIjAN...开头的 base64 字符串。4.5 在 Chrome 里侧载扩展并核对 ID打开 Chrome地址栏输入chrome://extensions右上角开启「开发者模式」点击「加载已解压的扩展程序」选择codex-chrome-extension文件夹。加载后扩展卡片上会显示 ID这时要核对它是不是hehggadaopoacecdllhhajmbjkdcmajg。如果 ID 不对最大的嫌疑是key字段没写对。移除扩展重新执行 4.4 步骤确认公钥提取无误后再加载。ID 正确后先不要急着跑任务重启一次 Codex 桌面端让 Native Messaging 通道重新初始化。4.6 重启 Codex 后把模型请求指向 TaoToken 的 Base URL扩展侧修好桌面端的「Google Chrome」开关应该已经亮了。此时 Codex 已经能操控浏览器但它还需要一个模型后端来解析你的指令、编排自动化步骤。打开 Codex 的配置文件~/.codex/config.toml把模型提供方切成 TaoToken# ~/.codex/config.toml model_provider taotoken [model_providers.taotoken] name TaoToken base_url https://taotoken.net/api env_key TAOTOKEN_API_KEY wire_api chat然后在系统环境变量里配置 API Key。PowerShell 里运行临时生效$env:TAOTOKEN_API_KEY YOUR_API_KEY想永久写入用户环境变量用setxsetx TAOTOKEN_API_KEY YOUR_API_KEY设置完环境变量后完全退出并重启 Codex 桌面端。模型 ID 不要凭空猜打开 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_end 的模型广场看当前列表选一个对应模型 ID 填进 Codex 的model配置。base_url不要加/v1也不要填官网首页地址两处用途不同。4.7 发一条浏览器自动化任务做冒烟测试配置全部就位后在 Codex 里发一条最简单的浏览器任务例如打开 https://example.com 把页面标题写到 D:\codex-browser-test.txt正常路径下Codex 会先调用模型理解任务再通过 Native Messaging 指挥扩展打开指定网页读取页面标题最后在本地生成文件。观察两个位置桌面端设置里的「Google Chrome」开关是否保持开启边栏里的浏览器任务按钮是否从灰色变成可点击。两者都正常就说明扩展 ID 修复和模型通道配置都成功了。5. 踩坑对照这几处最容易翻车5.1 扩展 ID 明明对了开关依然灰色最常见的原因是 Native Messaging host 没有重新注册。修改扩展后桌面端和浏览器之间旧握手状态可能还残留在内存里。Solution关掉所有 Chrome 窗口托盘里也完全退出 Codex再重新打开两侧。另一个可能性是桌面端只在 Stable Chrome 的注册表路径下注册了 Native Messaging hostSxS 里扩展 ID 正确但通道不在注册表内这时需要在 Stable Chrome 里也加载一次同一份解压目录。5.2 SxS 能加载Stable 反而没反应部分桌面端对浏览器的检测只写死在 Stable 版 Chrome 的注册表位置。SxS 或 Canary 虽然能手动加载扩展但 Native Messaging host 配置里没有对应的浏览器路径握手仍会失败。最省事的做法是两个浏览器都加载一次解压目录哪一个开关亮了就用哪一个。5.3 开发者模式加载的扩展不会自动更新通过 Load unpacked 加载的扩展不会走应用商店的自动更新通道。官方发布新版本后你需要重新下载 CRX、重新解压、重新注入 key然后在chrome://extensions里点「刷新」按钮。建议把原始codex.crx文件留档每次更新时重复 4.2 到 4.4 的步骤即可。5.4 模型请求报 401 或 404Codex 配置好 TaoToken 后如果任务在第一步就报401 Unauthorized多半是TAOTOKEN_API_KEY环境变量没生效或者 Key 复制时少了字符。如果报错接近路由不存在检查base_url正确的写法是https://taotoken.net/api末尾没有/v1。模型 ID 也要和模型广场上的标识完全一致别用文章里看到的过期名字。6. 验证清单从扩展 ID 到模型账单逐条对照6.1 chrome://extensions 逐项核对打开chrome://extensions确认三件事扩展 ID 是hehggadaopoacecdllhhajmbjkdcmajg扩展版本和官方版本一致「已加载」状态正常。任何一项不符合回到第 4 步重新走一遍。6.2 在 Codex 里跑通一条完整任务冒烟测试的任务越简单越好能覆盖「打开页面、读取内容、写文件」三个动作就可以。跑通后可以尝试稍微复杂的任务比如打开一个带表单的页面、填写输入框、点击提交按钮确认扩展的自动化能力是完整的。6.3 回 TaoToken 控制台对一下这次调用配置保存后先在 TaoToken 模型对话 里用同一把 Key 发一条测试消息确认模型 ID 和 Base URL 没填错。若要长期跑浏览器自动化任务可以打开 Coding Plan 看套餐是否够用Key 的创建和管理在 控制台 API Keys 里完成。跑完几轮任务后回控制台看用量记录能查到对应调用才算整条链路闭环。
返回列表