Skip to content

第 1 章 · 课程导览与环境准备

本章目标:理解 @earendil-works/pi-agent-core@earendil-works/pi-ai 两个包的分工,搭好 TypeScript 开发环境并跑通第一个程序。

1.1 这门课要做什么

Pi 生态中与你最相关的两个包:

包名职责类比
@earendil-works/pi-ai统一多 Provider 的 LLM API:模型目录、认证、流式、工具调用、token 计费一层「模型适配器」
@earendil-works/pi-agent-core有状态的 Agent 运行时:工具执行循环、事件流、状态管理、steering 队列一层「Agent 引擎」

分层关系非常清晰——pi-agent-core 构建在 pi-ai 之上

text
┌─────────────────────────────────┐
│   你的应用(CLI / Web / 服务)    │
├─────────────────────────────────┤
│   pi-agent-core                 │  ← Agent 状态机 + 工具循环 + 事件
│   (Agent / agentLoop)          │
├─────────────────────────────────┤
│   pi-ai                         │  ← 统一的 LLM 调用层
│   (Models / stream / complete) │
├─────────────────────────────────┤
│   OpenAI / Anthropic / Google…  │  ← 各家真实 API
└─────────────────────────────────┘

为什么不用各家官方 SDK 直接写

因为一旦你想换模型或做跨提供商切换,每家 SDK 的消息格式、工具协议、错误语义都不同。pi-ai 把这些差异抹平成一套统一接口,你的业务代码不需要为「换模型」付任何重构成本。

1.2 初始化 TypeScript 项目

bash
mkdir my-agent && cd my-agent
npm init -y
npm install @earendil-works/pi-agent-core @earendil-works/pi-ai
npm install -D typescript tsx @types/node

创建 tsconfig.json

jsonc
{
  "compilerOptions": {
    // 使用 NodeNext 以获得正确的 ESM 解析行为
    "module": "nodenext",
    "moduleResolution": "nodenext",
    "target": "es2022",
    // 严格模式是必须的:pi 的类型系统依赖严格检查
    "strict": true,
    "skipLibCheck": true,
    "outDir": "dist"
  },
  "include": ["src"]
}

package.json 中加入运行脚本:

jsonc
{
  "scripts": {
    // 用 tsx 直接跑 TypeScript,免去编译步骤
    "start": "tsx src/index.ts"
  }
}

1.3 Hello World:最小可运行的 Agent

创建 src/index.ts

typescript
// 导入 Agent 运行时与统一模型集合
import { Agent } from "@earendil-works/pi-agent-core";
import { createModels } from "@earendil-works/pi-ai";
import { anthropicProvider } from "@earendil-works/pi-ai/providers/anthropic";

// 创建模型集合并注册 Anthropic Provider
const models = createModels();
models.setProvider(anthropicProvider());

// 从目录中查找具体模型(找不到则抛错)
const model = models.getModel("anthropic", "claude-sonnet-4-6");
if (!model) throw new Error("Model not found");

// 实例化 Agent:注入系统提示词、模型和流式函数
const agent = new Agent({
  initialState: {
    systemPrompt: "You are a helpful assistant.",
    model,
  },
  streamFn: models.streamSimple.bind(models),
});

// 订阅事件流:把增量文本实时写到终端
agent.subscribe((event) => {
  if (
    event.type === "message_update" &&
    event.assistantMessageEvent.type === "text_delta"
  ) {
    process.stdout.write(event.assistantMessageEvent.delta);
  }
});

// 发送第一条提示词
await agent.prompt("用一句话介绍你自己");

确保环境变量里有 API Key 再运行:

bash
export ANTHROPIC_API_KEY=sk-ant-...
npm start

1.4 没有付费 Key?先用 Faux Provider

pi-ai 内置了一个用于测试的假 Provider,不花一分钱即可验证整条链路:

typescript
// fauxProvider 会按脚本返回预设的响应
import { createModels, fauxProvider } from "@earendil-works/pi-ai";
import { builtinModels } from "@earendil-works/pi-ai/providers/all";

// 方式一:只注册 faux(最轻量)
const models = createModels();
const faux = fauxProvider();
models.setProvider(faux.provider);

// 方式二:注册所有内置 Provider(包含 faux 之外的全部真实厂商)
const all = builtinModels();

console.log(faux.getModel()); // 返回第一个 faux 模型

后续章节的单元测试都会用到它——先让逻辑跑通,再接真实模型

1.5 学习路线图

章节主题
02–03pi-ai 基础:统一 API、Provider 与模型目录
04–05Agent 入门:实例化、prompt、事件流
06–09核心:工具调用、消息转换、上下文变换
10–15进阶:认证、思考推理、图像、错误处理、自定义 Provider、测试
16–20生产:Handoffs、持久化、浏览器、综合实战

1.6 本章小结

  • pi-ai 是统一的 LLM 调用层,pi-agent-core 是构建其上的有状态 Agent 运行时;
  • 项目需要 strict: true 的 TypeScript 配置,推荐用 tsx 直接运行;
  • 一个最小 Agent = Agent 实例 + initialState + streamFn
  • 没有 Key 时可用 fauxProvider() 先打通全链路。

🧪 随堂测验

点击你认为正确的选项。答错时会展示正确答案与原因解析。

1. pi-agent-core 和 pi-ai 的关系是什么?

2. 创建一个最小的 Agent 实例,以下哪组配置是必需的?

3. 没有 API Key 时想先验证代码逻辑,应该使用什么?

4. tsconfig 中为什么建议开启 strict: true?

🛠️ 动手实践

  1. 完成本章环境搭建,分别用 ANTHROPIC_API_KEY(或任意已有 Key)与 fauxProvider() 跑通 Hello World,对比输出差异。
  2. 把系统提示词改成「你是 pirate 风格的助手」,观察回复风格变化。
  3. 阅读 node_modules/@earendil-works/pi-ai/package.jsonexports 字段,列出你能找到的所有子路径入口。

环境就绪后进入第 2 章,深入 pi-ai 的统一 API。