ARTICLE · INTELLIGENCE

战地情报 · 详情页

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

每日技术推荐:用 TypeScript 与 Agent 打通全栈、游戏与应用开发工作流

每日技术推荐:用 TypeScript 与 Agent 打通全栈、游戏与应用开发工作流 1. 从三个真实场景说起为什么 TypeScript Agent 值得认真搭一次如果你同时碰过全栈、游戏和应用开发这三类项目大概率有过这种体验前端一套 TS 配置后端一套 Node 服务游戏侧又冒出个 TypeScript 写的工具链或小游戏逻辑应用开发里还夹着 Electron 或 React Native。语言是统一的但工程结构、依赖管理、接口联调方式各玩各的Agent 想帮你自动化都找不到统一入口。这就是「用 TypeScript 与 Agent 打通全栈、游戏与应用开发工作流」这个场景要解决的问题。TypeScript 在这里不是单纯的语言选择而是把三类场景的类型契约统一起来全栈共享 DTO 类型游戏侧共享状态机与配置类型应用侧共享 IPC 与 API 类型。Agent 则是那个能读懂这些类型、按任务配置去执行初始化、生成代码、跑联调脚本的协作入口。适合谁适合已经会写 TypeScript、但项目一多就靠手工复制粘贴脚手架的人适合想让 AI 编程助手真正参与工程流程、而不是只当补全工具的人也适合团队里负责搭骨架、定规范的那位。我试过把三类项目塞进同一个 monorepo 后最大的收益不是代码复用而是 Agent 终于有了稳定的上下文——它知道类型从哪来、接口往哪调、任务配置长什么样。这篇会给出可复制的目录结构、依赖清单、Agent 任务配置以及本地启动和接口连通性验证步骤。核心检索词就三个TypeScript 统一语言、Agent 自动化协作、多端开发骨架。读完你应该能直接跑起来一个可运行的三端骨架而不是停留在概念层。先说清楚边界Agent 在这里是「按配置执行任务的协作方」不是替代你写业务逻辑的魔法。任务配置写得好它就能稳定产出配置含糊它就会自由发挥。所以下面的重点会放在配置的可复制性上。2. TaoToken 前置准备给 Agent 一个稳定的模型入口Agent 要跑起来第一步是让它能稳定调用模型。这里用 TaoToken 作为统一入口原因是它同时提供对话、编码计划、控制台和 API Key 管理Agent 任务配置里只需要填一个 Base URL 和一个 Key不用为每个工具单独折腾。官网地址是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 端点是 https://taotoken.net/api 这个不加 UTM。注意区分官网用于注册、看文档、进控制台API 端点用于代码和工具里配置 Base URL。你需要准备三样东西我把它叫「三件套」后面所有配置都围绕它配置项取值来源用途Base URLhttps://taotoken.net/api所有工具/代码里的请求根地址API Key控制台 API Keys 页面生成身份认证形如 sk- 开头Model ID模型列表里选一个编码向模型指定 Agent 用哪个模型生成 Key 的路径是控制台里的 API Keys 页面对应 deep link 是 https://taotoken.net/console/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite 。如果你还没决定用哪个模型可以先到模型对话页面试一下响应风格地址是 https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite 。长期做编码和 Agent 任务的话Coding Plan 页面值得看一眼 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite 。接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite 遇到参数不确定时以文档为准。Claude Code 相关的接入说明在 https://taotoken.net/claudecode-anthropic?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite 。注意Key 只存在本地环境变量或本地配置文件里不要提交到 Git。下面所有示例都用TAOTOKEN_API_KEY这个环境变量名你在自己机器上 export 一次即可。环境变量设置macOS/Linuxexport TAOTOKEN_API_KEYsk-你的key export TAOTOKEN_BASE_URLhttps://taotoken.net/apiWindows PowerShell$env:TAOTOKEN_API_KEYsk-你的key $env:TAOTOKEN_BASE_URLhttps://taotoken.net/api这一步做完Agent 和代码就都有了统一的模型入口。接下来才是工程骨架本身。3. 可复制配置monorepo 目录结构、依赖清单与 Agent 任务配置这一节是全文最需要你动手的部分。目标是一个 monorepo里面同时容纳全栈、游戏、应用三类子项目共享类型包并且带一份 Agent 任务配置。先看目录结构直接复制ts-agent-workspace/ ├── package.json ├── pnpm-workspace.yaml ├── tsconfig.base.json ├── .env.example ├── packages/ │ ├── shared-types/ # 三端共享类型 │ │ ├── package.json │ │ ├── tsconfig.json │ │ └── src/ │ │ ├── api.ts # 接口 DTO │ │ ├── game.ts # 游戏状态/配置类型 │ │ └── index.ts │ ├── web-fullstack/ # 全栈前端 BFF │ │ ├── package.json │ │ ├── tsconfig.json │ │ ├── vite.config.ts │ │ └── src/ │ │ ├── main.ts │ │ └── api-client.ts │ ├── game-client/ # 游戏TS 逻辑层 │ │ ├── package.json │ │ ├── tsconfig.json │ │ └── src/ │ │ ├── state-machine.ts │ │ └── index.ts │ └── app-desktop/ # 应用Electron 主进程 渲染层 │ ├── package.json │ ├── tsconfig.json │ └── src/ │ ├── main.ts │ └── ipc.ts └── agent/ ├── tasks.json # Agent 任务配置 └── README.mdpnpm-workspace.yamlpackages: - packages/*根package.json的依赖清单重点是 TypeScript 与构建工具链{ name: ts-agent-workspace, private: true, scripts: { dev:web: pnpm --filter web-fullstack dev, dev:game: pnpm --filter game-client dev, dev:app: pnpm --filter app-desktop dev, typecheck: tsc -b --pretty, agent:run: node agent/run.mjs }, devDependencies: { typescript: ^5.6.0, tsx: ^4.19.0, vite: ^5.4.0, vitest: ^2.1.0, types/node: ^22.0.0 } }tsconfig.base.json用 project references 把三端串起来这是让 Agent 能跨包理解类型的关键{ compilerOptions: { target: ES2022, module: ESNext, moduleResolution: Bundler, strict: true, declaration: true, composite: true, skipLibCheck: true, paths: { shared/*: [./packages/shared-types/src/*] } } }共享类型包packages/shared-types/src/api.ts三端都从这里取类型export interface ApiResponseT { code: number; message: string; data: T; } export interface HealthPayload { service: string; version: string; uptime: number; } export type HealthResponse ApiResponseHealthPayload;游戏侧packages/shared-types/src/game.tsexport type GameState idle | running | paused | over; export interface GameConfig { tickRate: number; maxPlayers: number; seed: number; }Agent 任务配置agent/tasks.json这是让 Agent 按流程干活的核心。注意 Base URL、Key、Model ID 三件套都在这里体现{ provider: { baseUrl: https://taotoken.net/api, apiKeyEnv: TAOTOKEN_API_KEY, model: 你的ModelID }, tasks: [ { name: init-shared-types, description: 根据 api.ts 与 game.ts 生成缺失的导出索引, target: packages/shared-types/src/index.ts, prompt: 读取同目录下所有 .ts 文件生成统一 re-export保持类型名不变。 }, { name: wire-api-client, description: 为 web-fullstack 生成基于 shared-types 的 api-client, target: packages/web-fullstack/src/api-client.ts, prompt: 使用 shared/api 中的 ApiResponse 与 HealthResponse生成 fetch 封装baseURL 从环境变量读取。 }, { name: verify-health, description: 生成并运行接口连通性验证脚本, target: scripts/verify-health.ts, prompt: 请求 /health校验返回结构符合 HealthResponse失败时打印状态码与响应体。 } ] }如果你用的是 Claude Code 或 Cline 这类工具把上面的 provider 段映射成它们的配置即可。以 Claude Code 为例接入时同样需要 Base URL、Key、Model ID 三件套具体字段名以接入文档为准。Cline 的 MCP 配置里也是这三样别漏 Model ID否则会走默认模型导致行为不一致。提示agent/tasks.json里的model字段填你在模型列表里选定的 Model ID不要留空。留空时部分工具会回退到内置默认值Agent 产出风格会漂移。到这里骨架和配置都齐了。下一节验证它真的能跑。4. 本地启动与接口连通性验证从 typecheck 到 /health 请求配置写完不代表能跑。这一节按顺序验证每一步都有明确的成功标志。第一步安装依赖并做类型检查。在仓库根目录执行pnpm install pnpm typecheck成功标志命令退出码为 0没有 TS 报错。如果shared-types没被其他包引用到检查各子包的tsconfig.json里是否加了references指向../shared-types。第二步启动全栈子项目pnpm dev:webVite 默认起在 5173。成功标志终端打印Local: http://localhost:5173/浏览器打开能看到页面。第三步写一个最小 BFF 健康检查接口。在packages/web-fullstack里加一个server.tsimport { createServer } from node:http; import type { HealthResponse } from shared/api; const server createServer((req, res) { if (req.url /health) { const body: HealthResponse { code: 0, message: ok, data: { service: web-fullstack, version: 0.1.0, uptime: process.uptime() } }; res.writeHead(200, { Content-Type: application/json }); res.end(JSON.stringify(body)); return; } res.writeHead(404); res.end(); }); server.listen(8787, () console.log(BFF on http://localhost:8787));用 tsx 启动pnpm --filter web-fullstack exec tsx server.ts第四步验证接口连通性。写scripts/verify-health.tsimport type { HealthResponse } from shared/api; const base process.env.BFF_BASE ?? http://localhost:8787; const res await fetch(${base}/health); const json (await res.json()) as HealthResponse; if (res.status ! 200 || json.code ! 0) { console.error(health check failed, res.status, json); process.exit(1); } console.log(health ok:, json.data.service, json.data.version);运行BFF_BASEhttp://localhost:8787 pnpm exec tsx scripts/verify-health.ts成功标志终端输出health ok: web-fullstack 0.1.0。第五步验证 Agent 能调用模型。用 tasks.json 里的 provider 段发一个最小请求curl -s https://taotoken.net/api/chat/completions \ -H Authorization: Bearer $TAOTOKEN_API_KEY \ -H Content-Type: application/json \ -d { model: 你的ModelID, messages: [{role: user, content: 只回复 ok}] }成功标志返回 JSON 里choices[0].message.content包含ok。这一步通了说明三件套配置正确Agent 任务才有执行基础。第六步跑一次 Agent 任务。以init-shared-types为例让 Agent 读取shared-types/src下的文件并生成index.ts。执行后检查index.ts是否包含export * from ./api和export * from ./game。成功标志pnpm typecheck依然通过。游戏侧和应用侧的验证同理pnpm dev:game起逻辑层测试pnpm dev:app起 Electron 窗口各自确认能加载shared类型即可。三类场景共用一套类型和一套模型入口这就是「打通」的实际含义。5. 本篇常见错排查401、local proxy failed、reading choices、OAuth配置和验证过程中下面这几类报错出现频率最高。逐个对照。401 Unauthorized。最常见的原因是 Key 没生效或环境变量名写错。检查TAOTOKEN_API_KEY是否在当前 shell 里 export 成功用echo $TAOTOKEN_API_KEY确认非空。如果 Key 是在控制台刚生成的确认复制完整、没有多余空格。还有一种情况是工具配置里写死了旧 Key而环境变量换了新的两者不一致。排查顺序先确认环境变量再确认工具配置读取的是哪个变量名。local proxy failed / connection refused。这类报错通常出现在本地 BFF 或 Agent 工具尝试连本地端口时。先确认server.ts是否真的在 8787 上监听用curl http://localhost:8787/health直接打一次。如果本地通了但工具报 proxy failed检查工具配置里的 Base URL 是不是被误填成了http://localhost:xxxx正确值应该是https://taotoken.net/api。本地服务和模型入口是两个不同的地址别混。reading choices of undefined。这个报错说明代码在解析响应时choices字段不存在。原因通常是请求体里model字段为空或写错服务端返回了错误结构而不是标准补全结构。修复方式在解析前先打印完整响应体确认model用的是有效 Model ID。另外如果请求被中间层拦截返回了 HTML 错误页json()解析也会失败先看res.status和res.text()。OAuth 相关报错。部分工具默认走 OAuth 登录流程如果你用的是 API Key 模式需要在配置里显式切换到 key 认证否则工具会尝试拉起浏览器授权并失败。检查工具配置里是否有authType或类似字段设为apiKey并填入 Base URL、Key、Model ID 三件套。Claude Code 接入时尤其注意这点字段名以接入文档为准。类型找不到 shared/。这是 tsconfig 的 paths 没生效。确认根tsconfig.base.json里配了paths且各子包tsconfig.json里extends了它。如果用了 project references还要确认references指向了shared-types并且先跑一次tsc -b生成声明文件。Agent 产出风格漂移。任务配置里model留空或 prompt 太模糊都会导致这个现象。修复明确 Model IDprompt 里写清输入文件、输出文件、约束条件。任务配置越具体Agent 越稳定。注意排障时优先看完整响应体和状态码不要只看工具抛出的那行错误。多数问题在原始响应里一目了然。6. 把骨架用起来下一步的接入与验证入口骨架跑通之后接下来就是把它变成日常工具。如果你要继续调模型、试不同 Model ID 的编码表现直接到模型对话页面验证 https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite 。如果你要管理多个项目的 Key或者给团队分配不同的 Key控制台 API Keys 页面是入口 https://taotoken.net/console/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite 。长期跑编码和 Agent 任务的话Coding Plan 页面值得配置一次 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite 。接入细节和参数以文档为准 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite 。Claude Code 用户看这个 https://taotoken.net/claudecode-anthropic?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite 。最后给一个实用技巧把agent/tasks.json里的任务按「生成类」和「验证类」分开。生成类任务让 Agent 产出代码验证类任务让 Agent 跑 typecheck 和 health check。每次生成后立刻跑验证问题会在最小范围内暴露而不是等到三端联调时才发现类型对不上。这套流程跑顺之后全栈、游戏、应用三类项目的初始化时间会明显缩短Agent 也真正成了工程流程的一部分而不只是一个补全框。
RELATED READING

延伸阅读

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