1. 为什么 TypeScript 老手都在折腾 Code Runner 的多模型调用
如果你写过一段时间 TypeScript,大概率装过 Code Runner 这个 VS Code 插件。它的定位很朴素:右键一个.ts文件,点一下 Run Code,终端里就把结果跑出来了。对于写算法题、验证一段类型体操、临时跑个脚本的场景,它比配ts-node、tsx再敲命令要顺手得多。
但真正高频用起来之后,问题会集中爆发在一个地方:当你的脚本里需要调用大模型 API 时,Key 和通道怎么管。我自己的习惯是,一个scratch目录下堆了几十个临时 TS 文件,有的测 Claude 的代码补全,有的测 GPT 系列的结构化输出,有的只是验证一下某个 SDK 的流式返回。如果每个文件里都硬编码一个baseURL和apiKey,改一次环境就要全局搜索替换,非常难受。
这篇就聚焦这个场景:在 VS Code 里用 Code Runner 跑 TypeScript 脚本,通过 TaoToken 统一 Key 和 API 通道来管理多模型调用。适合已经会写 TS、日常用 VS Code、想把手头零散脚本的模型调用收敛到一套配置里的人。下面给出settings.json和 Code Runner 的可复制配置骨架,再演示一次真实请求验证,最后把常见的坑列清楚。
2. TaoToken 前置:统一 Key 与 API 通道是什么
TaoToken 在这里扮演的角色,可以理解成一个统一的模型调用入口。你不需要为每个模型厂商分别记一套地址和密钥,而是用同一个 API Key,通过同一个 API 地址去请求不同的模型。官网是 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,API 入口是 https://taotoken.net/api (这个地址不加 UTM 参数)。
对 Code Runner 场景来说,它的价值在于三点:
第一,环境变量只维护一份。你的 TS 脚本里读的是process.env.TAOTOKEN_API_KEY和process.env.TAOTOKEN_BASE_URL,换模型只改请求体里的model字段,不动 Key。
第二,Code Runner 的executorMap可以统一注入环境变量。VS Code 的settings.json支持给 Code Runner 配置每种语言的执行命令,你可以在跑 TS 之前把环境变量带上,脚本里直接读,不用装dotenv。
第三,多模型切换成本低。同一份脚本骨架,改一个字符串就能从 Claude 换到别的模型,适合做对比验证。
需要先拿到 Key 的话,去控制台创建:https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_content=console&utm_campaign=rewrite ,然后在 API Keys 页面生成:https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api-keys&utm_campaign=rewrite 。接入细节可以对照文档:https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite 。
注意:Key 只放在本机环境变量或 VS Code 的用户级
settings.json里,不要提交到 Git 仓库。团队协作时用.env.example占位,真实值走本地。
3. 可复制配置:settings.json 与 Code Runner 骨架
先装依赖。在项目目录里执行:
npm init -y npm install openai npm install -D typescript ts-node @types/node这里用openai这个 SDK 作为客户端,因为它兼容 OpenAI 风格的接口,TaoToken 的 API 通道可以直接对接。ts-node负责让 Code Runner 能直接跑.ts文件。
接着配置 VS Code 的settings.json。按Ctrl+Shift+P(macOS 是Cmd+Shift+P),输入Open User Settings (JSON),在用户级配置里加上 Code Runner 的执行映射:
{ "code-runner.runInTerminal": true, "code-runner.clearPreviousOutput": true, "code-runner.executorMap": { "typescript": "cd $dir && TAOTOKEN_API_KEY=$TAOTOKEN_API_KEY TAOTOKEN_BASE_URL=https://taotoken.net/api npx ts-node $fullFileName" }, "code-runner.executorMapByFileExtension": { ".ts": "cd $dir && TAOTOKEN_API_KEY=$TAOTOKEN_API_KEY TAOTOKEN_BASE_URL=https://taotoken.net/api npx ts-node $fullFileName" } }几个关键点解释一下。runInTerminal设为true,是因为流式输出在终端里看更直观,也方便你中途Ctrl+C。clearPreviousOutput让每次运行前清屏,避免几十次运行后输出糊成一片。executorMap里的$dir是当前文件所在目录,$fullFileName是完整文件路径,这两个是 Code Runner 的内置变量。
环境变量TAOTOKEN_API_KEY建议在系统层面设置,而不是写死在settings.json里。macOS 或 Linux 可以在~/.zshrc或~/.bashrc里加:
export TAOTOKEN_API_KEY="你的Key"Windows 则在「系统属性 → 环境变量」里新建用户变量。这样settings.json里只做透传,配置本身可以安全地同步到多台机器。
然后写一个测试脚本hello-model.ts:
import OpenAI from "openai"; const client = new OpenAI({ apiKey: process.env.TAOTOKEN_API_KEY, baseURL: process.env.TAOTOKEN_BASE_URL, }); async function main() { const res = await client.chat.completions.create({ model: "claude-3-5-sonnet-latest", messages: [ { role: "user", content: "用一句话说明 TypeScript 的类型收窄是什么" }, ], }); console.log(res.choices[0].message.content); } main().catch((err) => { console.error("请求失败:", err.message); process.exit(1); });这段代码里,baseURL和apiKey全部来自环境变量,脚本本身不含任何敏感信息。换模型只需要改model字段。
4. 验证请求:一次真实运行与成功结果
把上面的hello-model.ts保存好,在编辑器里右键,选择Run Code,或者用快捷键Ctrl+Alt+N(macOS 是Ctrl+Option+N)。终端里会先执行cd到文件目录,再用ts-node跑起来。
如果一切正常,你会看到类似这样的输出:
TypeScript 的类型收窄是指通过类型守卫、字面量判断或控制流分析,把联合类型在特定分支里缩小为更具体的类型。这说明三件事都通了:Code Runner 正确注入了环境变量,ts-node正确解析了 TS 文件,TaoToken 的 API 通道正确返回了模型结果。
想验证流式输出,把脚本改成:
const stream = await client.chat.completions.create({ model: "claude-3-5-sonnet-latest", messages: [{ role: "user", content: "数一下从 1 到 5" }], stream: true, }); for await (const chunk of stream) { process.stdout.write(chunk.choices[0]?.delta?.content ?? ""); }在终端里能看到逐字打印的效果。这一步验证通过后,你手头所有零散的 TS 脚本都可以套用同一套环境变量和客户端初始化逻辑。
如果你更想先在网页里确认模型是否可用,可以直接用模型对话页面发一条消息:https://taotoken.net/chat?utm_source=taotoken_aicg_blog_end&utm_content=model_chat&utm_campaign=rewrite ,确认通道没问题再回到本地配 Code Runner,能省掉不少排查时间。
5. 本篇常见错排查
报错一:401 Unauthorized或invalid api key。九成是环境变量没生效。先在终端里单独执行echo $TAOTOKEN_API_KEY(Windows 用echo %TAOTOKEN_API_KEY%),确认有值。如果为空,说明系统环境变量没配好,或者 VS Code 是在配置环境变量之前启动的,重启 VS Code 即可。注意 Code Runner 的executorMap里透传的变量名要和系统里的一致。
报错二:Cannot find module 'openai'。这是ts-node在错误的目录下找依赖。检查executorMap里的cd $dir是否生效,以及node_modules是否装在当前项目根目录。如果脚本在子目录里,而依赖装在父目录,ts-node会找不到。解决办法是在项目根目录运行,或者用npx ts-node时指定--project指向正确的tsconfig.json。
报错三:baseURL拼错导致连接超时。常见的是把https://taotoken.net/api写成了带路径后缀的形式,或者漏了https。建议在脚本里加一行console.log(process.env.TAOTOKEN_BASE_URL)做自检,确认打印出来的地址和文档一致。
报错四:Code Runner 输出乱码或没有输出。检查code-runner.runInTerminal是否为true。如果设为false,输出会走 VS Code 的输出面板,流式内容可能显示不全。另外clearPreviousOutput在终端模式下不生效,这是正常的,终端本身可以用clear命令手动清。
报错五:模型名写错返回model not found。不同模型的标识符不一样,别凭记忆写。先在模型对话页面确认可用的模型名,再填到脚本里。这一步用网页验证比在本地反复改脚本快得多。
6. 长期编码与 Agent 场景的下一步
上面这套配置解决的是「临时脚本快速跑」的问题。如果你的使用场景从零散脚本升级到长期编码、批量重构、或者接 Agent 工作流,单靠 Code Runner 就不够了,需要更稳定的调用配额和更完整的工程结构。这种场景可以看下 Coding Plan:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding_plan&utm_campaign=rewrite ,它更适合持续性的编码任务。
如果你用的是 Claude Code 这类命令行工具,接入方式在文档里有专门说明:https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=claudecode&utm_campaign=rewrite 。核心思路和上面一样,都是把 Key 和 baseURL 收敛到一处,工具侧只负责发请求。
回到 Code Runner 本身,我自己的做法是把scratch目录下的脚本按用途分子目录,每个子目录一个tsconfig.json,executorMap里用$dir自动切换工作目录。这样几十个脚本共用一套环境变量,换模型只改一行model字段,跑完就删,不留垃圾。这套习惯坚持下来,临时验证的效率会比每次新建项目高很多。