一、为什么是 Bun?
2025 年,Anthropic 收购了 Bun。你没看错,就是那个做出 Claude 的 Anthropic。
Bun 现在是 Claude Code 的底层运行时。这意味着什么?你写的每一行 Bun 代码,和当今最强的 AI 编程工具跑在同一个引擎上。
那 Bun 到底是什么?

Bun 是一个比 Node.js 更快、开箱即用、零配置的 JavaScript / TypeScript 运行时 + 包管理器。
三个关键词:
- 更快:基于 Zig 语言构建,启动速度、包安装速度数倍于 Node
- 开箱即用:原生支持 TypeScript,不需要装 ts-node、不需要配 webpack
- 零配置 :一个
bun run index.ts直接跑 TypeScript,不需要任何配置文件
安装一行搞定:
bash
powershell -c "irm bun.sh/install/windows | iex"
装完就能用,没有 node_modules 地狱,没有 tsconfig 焦虑。
配置不成功就去下bun-windows-x64.zip的安装包,问豆包等llm 去教你
二、TypeScript:给 JavaScript 装上刹车

2.1 JS 弱类型的痛
JavaScript 有一个经典问题------你以为它是数字,它其实是字符串。
打开一个 HTML 页面,写一个 input:
bash
<input type="text" id="input">
<script>
const input = document.getElementById('input')
input.addEventListener("change", function(event) {
console.log(event.target.value, typeof event.target.value);
// 你输入 123,控制台打印:123 string
// 永远是 string,永远是 string,永远是 string
})
</script>
浏览器的 input.value 返回的永远是字符串。这不是 bug,这是设计。但问题来了:
bash
let a = 1;
let b = "2";
console.log(a + b); // "12" ------ 字符串拼接!
+ 运算符一头是数字、一头是字符串,JS 不会报错,它会悄悄地把数字转成字符串然后拼起来。你期待结果是 3,实际得到 "12"。
不报错 + 结果错误 = 线上 Bug 炸弹。这种 bug 可能藏在系统里几个月才爆。
2.2 TypeScript 登场
TypeScript 来自微软,是 JavaScript 的超集 ------所有合法的 JS 代码都是合法的 TS 代码,但 TS 多了类型约束。
bash
const nickname: string = "9527";
const age: number = 18;
console.log(`我是${nickname},我今年${age}岁`);
当你给变量加了类型,编辑器立刻就能检查出类型错误------不用等到运行时。
2.3 函数类型与类型转换
bash
function add(a: number, b: number): number {
return a + b;
}
let a = 1;
let b = "2";
// add(a, b); // ❌ 编译报错:类型"string"的参数不能赋给类型"number"的参数
// 方式一:显式转换
let c: number = add(a, Number(b));
// 方式二:隐式转换(+号前置)
console.log(add(a, +b)); // 3 ✅
TS 在编译阶段就把 bug 拦下来了。你不用等用户反馈 "这个计算好像不对",IDE 里直接标红。
这也是为什么 TypeScript 已经成为 AI Agent 的标配------AI 写的代码也需要类型约束来保证质量。
三、异步编程:Promise 和 async/await
调用 AI 接口是网络请求,网络请求是异步的。JS 的异步演进路线是:callback → Promise → async/await。今天你只需要掌握最后一站。
封装一个 sleep 函数:
bash
function sleep(t) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve();
}, t);
});
}
async function main() {
console.log('--start--');
await sleep(1000); // 等待 1 秒
console.log('--end--');
}
main();
核心就两句话:
Promise是一个 "许下诺言" 的对象------它代表一个未来才会完成的操作await后面跟 Promise,代码会暂停在这里,等 Promise 完成后继续
理解了这个模式,你就能理解所有 AI 接口调用的底层逻辑------它们都是异步的。
四、实战:用 axios 调用 DeepSeek 大模型
4.1 项目搭建
bash
bun init axios-demo
cd axios-demo
bun add axios dotenv
Bun 的项目配置极简,package.json 长这样:
bash
{
"name": "axios-demo",
"module": "index.ts",
"type": "module",
"dependencies": {
"axios": "^1.17.0",
"dotenv": "^17.4.2"
},
"devDependencies": {
"@types/bun": "latest"
},
"peerDependencies": {
"typescript": "^5"
}
}
注意 "module": "index.ts"------Bun 原生就跑 .ts 文件,不需要编译。
4.2 理解 HTTP 请求结构
调用 AI API 本质上就是发一个 HTTP POST 请求。一个 HTTP 请求包含三个核心部分:
| 部分 | 作用 | 示例 |
|---|---|---|
| 请求行 | URL + Method + HTTP Version | POST https://api.deepseek.com/v1/chat/completions |
| 请求头 | 元信息(认证、格式) | Authorization: Bearer sk-xxx、Content-Type: application/json |
| 请求体 | 实际数据 | { model: "deepseek-v4-flash", messages: [...] } |
4.3 为什么用 POST 而不是 GET?
- GET 请求有长度限制,URL 最长约 2048 字符
- API Key 放在 GET 的 URL 参数里?不安全------URL 会被日志、代理、浏览器历史记录
- AI 对话可能包含图片上传,需要请求体传二进制数据
所以调用 AI 接口,一律用 POST,API Key 放请求头,对话内容放请求体。
4.4 核心代码
bash
import axios from "axios";
import dotenv from "dotenv";
dotenv.config();
async function chat() {
try {
const res = await axios.post(
`${process.env.DEEPSEEK_API_URL}`,
{
model: "deepseek-v4-flash",
messages: [
{
role: "user",
content: "你好"
}
]
},
{
headers: {
'Content-Type': "application/json",
'Authorization': `Bearer ${process.env.DEEPSEEK_API_KEY}`
}
}
);
// axios 默认将响应数据包装在 data 属性中
console.log(res.data.choices[0].message.content);
} catch (err: any) {
console.log(err.message);
}
}
chat();
.env 文件:
bash
DEEPSEEK_API_URL=https://api.deepseek.com/v1/chat/completions
DEEPSEEK_API_KEY=sk-你的密钥
4.5 这段代码讲了什么
- axios 是对
fetch的封装,省去了手动处理 JSON、处理超时、处理错误的大量样板代码 - dotenv 把 API Key 从代码中分离出来------密钥永远不要硬编码
- try/catch 包裹整个请求------LLM 可能超时、可能限流、可能 Key 过期,必须有异常处理
- async/await 让异步代码看起来像同步代码,可读性大幅提升
一行 bun run index.ts,你就完成了一次 AI 对话。


五、升华一下:我的AI 全栈学习路线与心得
上面这些代码跑通后,你可能会问:"然后呢?我学会了调用 API,但我能做什么?我怎么成为一个 AI 全栈工程师?"
5.1 AI 全栈 ≠ 调 API
很多人把 AI 全栈理解成"前端 + 后端 + 调 AI API",这是不完整的。
真正的 AI 全栈应该是:
bash
┌─────────────────┐
│ 用户界面层 │ ← React / Vue / 小程序
└────────┬────────┘
│
┌────────▼────────┐
│ API 网关层 │ ← Bun / Node / Go
└────────┬────────┘
│
┌─────────────┼─────────────┐
│ │ │
┌─────▼─────┐ ┌─────▼─────┐ ┌─────▼─────┐
│ 业务逻辑 │ │ LLM 调用 │ │ 数据层 │
│ (传统后端)│ │ (Prompt │ │ (向量库) │
└───────────┘ │ Engineering│ └───────────┘
│ + RAG) │
└───────────┘
需要掌握的不只是 axios.post,还包括:
| 层级 | 核心能力 | 关键工具 |
|---|---|---|
| Prompt Engineering | 写出高质量的系统提示词、管理对话上下文 | Claude / DeepSeek / GPT |
| RAG(检索增强生成) | 把私有知识喂给大模型 | 向量数据库(Pinecone / ChromaDB) |
| Function Calling / Tool Use | 让 AI 调用你的 API、操作数据库 | Claude Tool Use / OpenAI Function Calling |
| Agent 编排 | 多个 AI 协作完成复杂任务 | LangChain / Claude Agent SDK |
| 流式输出 | SSE / WebSocket 实时返回 AI 回复 | Server-Sent Events |
| 安全与合规 | API Key 管理、内容审核、速率限制 | 网关 + 审核中间件 |
5.2 三条核心心得
心得一:先跑通,再理解
不要先啃完所有理论再动手。第一个 AI 接口调用应该在第一周就完成------就像上面那个 axios 例子。跑通之后会兴奋,兴奋是最好的学习动力。
心得二:TypeScript 是 AI 时代的标配
AI Agent 写代码非常快,但它同样会犯 JS 弱类型的错误。TypeScript 的类型系统是我和 AI 之间的契约------'我'定义好类型,AI 填实现,编译器检查结果。这个协作模式效率极高。
这也是为什么 Claude Code 底层选择了 Bun + TypeScript,而不是纯 JavaScript。
心得三:AI 全栈的核心不是模型,是工程能力
模型层是别人的,工程层是你我们。DeepSeek、Claude、GPT 这些模型你换着用,但如何把它们串进业务系统、如何保证稳定性和用户体验、如何处理边界情况------这些才是我们的护城河。
代码里的 try/catch、dotenv 密钥管理、axios 的请求封装......这些看起来 "不 AI" 的工程细节,恰恰是 AI 全栈工程师和 "调包侠" 的分界线。
