【Agent】【OpenCode】项目配置(Catalogs):把 package.json 与 workspaces 改到 TaoToken
发布时间:2026/9/29 21:49:07来源:尧图网络
1. OpenCode Agent 项目里 Catalogs 到底解决什么问题如果你正在用 OpenCode 这类 Agent 框架做多包仓库开发大概率会遇到一个很烦的场景根目录一个package.jsonpackages/下面十几个子包各自还有一份package.json每个子包里都写着zod: 4.1.8、typescript: 5.8.2。某天要统一升一个版本你得挨个文件改漏掉一个包管理器就给你多装一份旧版本磁盘里躺着两份甚至三份同一个库。Catalogs目录就是干这个的。它只出现在根目录的package.json里通过workspaces.catalog字段集中声明整个仓库所有公共依赖的精确版本号。子包不再写具体版本只写catalog:这个占位符包管理器解析时自动去根目录的字典里查。你可以把它理解成一份“依赖菜单”根目录负责定标准子包负责点菜。这套机制对 OpenCode Agent 项目尤其重要因为 Agent 项目通常会把模型调用、工具执行、UI 渲染拆成多个子包每个子包都可能依赖同一批基础库。如果版本不统一运行时很容易出现“子包 A 用 TS 5.0 编译、子包 B 用 TS 4.9 编译”的诡异冲突。而当我们把统一 Key、统一 API 通道的接入位置也纳入 Catalogs 管理时整个仓库的依赖和配置就真正做到了“一处改、处处生效”。这篇就围绕package.json与workspaces两个切入点把 OpenCode Agent 项目在 Catalogs 配置环节的实操讲清楚目录结构怎么摆、字段怎么写、统一 API 通道放在哪、怎么用一条命令验证配置生效且请求走通。适合正在搭 Monorepo 的 Agent 开发者、需要统一管理多子包依赖的团队以及想把模型调用配置收敛到根目录的同学。2. 接入前的准备TaoToken 通道与项目结构梳理在动package.json之前先把两件事理清楚一是统一 API 通道从哪来二是 OpenCode 项目的 workspaces 目录长什么样。统一 API 通道我用的是 TaoToken它的 API 地址是https://taotoken.net/api兼容 OpenAI 风格的请求格式所以 OpenCode Agent 里那些走baseURL的模型客户端可以直接对接。你需要先在控制台创建一个 API Key这个 Key 后面会作为环境变量注入到各个子包而不是硬编码在代码里。控制台入口在https://taotoken.net/console创建 Key 的页面在https://taotoken.net/api-keys。如果你还没决定用哪个模型可以先去模型对话页面https://taotoken.net/model-chat试一下请求格式确认返回结构符合预期再往下配。然后是项目结构。OpenCode 这类 Agent 项目的典型 workspaces 布局是这样的opencode-agent/ ├── package.json # 根目录含 workspaces catalog ├── pnpm-workspace.yaml # 如果用 pnpm工作区声明在这里 ├── packages/ │ ├── core/ # Agent 核心逻辑 │ │ └── package.json │ ├── tools/ # 工具执行层 │ │ └── package.json │ ├── console/ # 控制台/UI │ │ └── package.json │ └── shared/ # 公共工具 │ └── package.json └── .env # 统一环境变量不提交根目录的package.json里workspaces字段告诉包管理器“仓库里有这些子包”catalog字段则集中声明公共依赖版本。子包的package.json里依赖版本写成catalog:内部包引用写成workspace:*。这里要区分两个词根目录的workspaces带 s是物理集合代表工作区结构子包里的workspace不带 s是本地链接协议通知包管理器走内部通道拿包不用上外网。统一 API 通道的接入位置我建议放在根目录的.env加一个共享配置包packages/shared。.env里放TAOTOKEN_API_KEY和TAOTOKEN_BASE_URLpackages/shared导出一个读取配置的函数其他子包通过opencode/shared: workspace:*引用它。这样 Key 只在一个地方维护子包不碰敏感信息。3. 可复制的 package.json 与 workspaces 配置片段这一节直接给可复制的配置。先看根目录package.json重点是workspaces和catalog两个字段{ name: opencode-agent, private: true, packageManager: pnpm9.0.0, workspaces: { packages: [ packages/* ], catalog: { typescript: 5.8.2, zod: 4.1.8, hono: 4.6.3, solid-js: 1.9.3, solidjs/router: 0.15.1, openai: 4.77.0, dotenv: 16.4.7 } }, scripts: { verify:catalog: node scripts/verify-catalog.mjs } }注意catalog是写在workspaces对象内部的不是和workspaces平级。这是很多同学第一次配容易写错的地方。openai这个包之所以放进 catalog是因为 OpenCode Agent 里多个子包都要用它构造模型客户端统一版本能避免请求格式不一致。如果你用的是 pnpm工作区声明通常在pnpm-workspace.yaml但 catalog 依然可以放在根package.json的workspaces.catalog里两者不冲突packages: - packages/*再看子包packages/core/package.json依赖版本全部用catalog:占位{ name: opencode/core, version: 0.1.0, type: module, dependencies: { opencode/shared: workspace:*, openai: catalog:, zod: catalog:, dotenv: catalog: }, devDependencies: { typescript: catalog: } }opencode/shared用workspace:*表示走本地软链接openai、zod用catalog:表示去根目录字典查版本。子包完全不需要知道openai是 4.77.0 还是别的升级时只改根目录一处。接着是统一 API 通道的配置包packages/shared/src/config.tsimport dotenv/config; export interface TaoTokenConfig { apiKey: string; baseURL: string; defaultModel: string; } export function loadTaoTokenConfig(): TaoTokenConfig { const apiKey process.env.TAOTOKEN_API_KEY; if (!apiKey) { throw new Error(TAOTOKEN_API_KEY 未设置请检查根目录 .env); } return { apiKey, baseURL: process.env.TAOTOKEN_BASE_URL ?? https://taotoken.net/api, defaultModel: process.env.TAOTOKEN_MODEL ?? gpt-4o-mini, }; }根目录.env内容TAOTOKEN_API_KEYsk-你的Key TAOTOKEN_BASE_URLhttps://taotoken.net/api TAOTOKEN_MODELgpt-4o-mini这样packages/core里构造客户端时直接import { loadTaoTokenConfig } from opencode/shared拿到的就是统一通道。Key 只在.env里出现一次子包代码里没有任何硬编码。4. 验证配置生效一条命令确认请求走通配置写完怎么确认 catalog 真的生效、请求真的走通分两步。第一步验证 catalog 解析。在根目录执行pnpm install --frozen-lockfile如果 catalog 配置有误比如子包写了catalog:但根目录字典里没有对应条目pnpm 会直接报错类似No catalog entry found for xxx。安装成功后检查node_modules/.pnpm里对应包的版本应该和根目录 catalog 声明的一致。你也可以用一条更直接的命令pnpm why openai输出会显示openai被哪些子包引用、解析到哪个版本。如果多个子包都引用它版本应该只有一个这就是 catalog 起作用的证据。第二步验证 API 请求走通。在packages/core里写一个最小验证脚本scripts/verify-request.mjsimport OpenAI from openai; import { loadTaoTokenConfig } from opencode/shared; const config loadTaoTokenConfig(); const client new OpenAI({ apiKey: config.apiKey, baseURL: config.baseURL, }); const res await client.chat.completions.create({ model: config.defaultModel, messages: [{ role: user, content: 回复 OK 两个字母即可 }], }); console.log(baseURL:, config.baseURL); console.log(model:, res.model); console.log(content:, res.choices[0].message.content);在根目录执行node packages/core/scripts/verify-request.mjs预期输出类似baseURL: https://taotoken.net/api model: gpt-4o-mini content: OK看到content: OK说明三件事都对了catalog 把openai版本统一解析了、opencode/shared的 workspace 软链接生效了、API 请求通过统一通道走通了。如果baseURL打印出来是undefined或者默认值不对回去检查.env是否被dotenv正确加载以及packages/shared是否在子包依赖里声明了workspace:*。5. 常见报错排查401、local proxy failed、reading choices配置过程中最容易撞上的几个报错我按实际遇到的频率排一下。401 Unauthorized。这个最常见通常是TAOTOKEN_API_KEY没读到或者 Key 失效。先确认.env在根目录而不是子包目录dotenv/config默认从当前工作目录找.env。如果你在子包目录里直接跑脚本工作目录不对.env就加载不到。解决办法是在根目录跑或者在脚本里显式指定路径dotenv.config({ path: ../../.env })。另外确认 Key 是从https://taotoken.net/api-keys创建的没有多余空格。local proxy failed。这个报错一般出现在请求根本没发出去的时候比如baseURL写成了https://taotoken.net少了/api或者环境变量里混入了其他代理配置。检查TAOTOKEN_BASE_URL是否精确等于https://taotoken.net/api以及 shell 里有没有残留的HTTP_PROXY之类变量干扰。清掉后重跑验证脚本。reading choices。典型报错是Cannot read properties of undefined (reading choices)说明res是 undefined请求返回了非预期结构。常见原因是模型名写错或者请求体格式不对。先打印完整响应console.log(JSON.stringify(res, null, 2))看返回里有没有error字段。如果模型名不在可用列表里换成TAOTOKEN_MODEL里确认过的值。还有一种情况是openai包版本和请求格式不匹配这时候回去检查 catalog 里openai的版本是否被正确解析用pnpm why openai确认。OAuth 相关报错。如果你在 OpenCode 里用了需要 OAuth 的模型客户端报错可能提示 token 过期或回调失败。这类问题通常和 catalog 无关而是认证流程本身。确认你用的是 API Key 模式而不是 OAuth 模式loadTaoTokenConfig返回的是apiKey字段直接传给new OpenAI({ apiKey })即可不需要走 OAuth 回调。排查时记住一个原则先确认配置读到了打印config再确认请求发出去了打印baseURL最后确认响应结构对打印完整res。三步定位基本不会卡太久。6. 把统一通道固化进工作流配置跑通之后建议把验证脚本挂到 CI 或者 pre-commit 钩子里。根目录package.json里已经加了verify:catalog脚本你可以再补一个verify:request在每次改完 catalog 或.env结构后跑一遍。这样团队里任何人升级依赖版本都不会悄悄破坏 API 通道。长期做 Agent 编码和工具链开发的话可以考虑把模型调用收敛到packages/shared里统一封装子包只调用封装后的函数不直接碰openai客户端。这样以后换模型、换通道只改一个文件。如果你需要更稳定的长期编码额度可以了解一下 Coding Planhttps://taotoken.net/coding-plan。接入文档在https://taotoken.net/doc里面有针对不同语言和框架的示例配合这篇的 catalog 配置一起看基本能把 OpenCode Agent 项目的依赖和通道一次性理顺。
网站建设高端定制企业官网