用 Pi 写第一个 Agent

最后更新:2026-10-10

这一节我们从 pi-agent-core 出发,写一个能调用工具的最小 Agent。读完你应该能理解 Pi 的核心循环长什么样、AgentSession 和 Agent 各管什么,以及怎么观察它的一举一动。

建议先扫一眼 总体架构 与 核心概念,会更快上手;工具与包的边界在 核心包 里有详细说明。

核心思路

Pi 的运行时把「不稳定的外部世界」和「稳定的核心循环」分开:

你提供
工具(函数)+ Prompt

把业务能力封装成工具,把目标写进 prompt。

pi-agent-core
Agent → AgentSession → AgentLoop

Agent 持有工具与模型;Session 持有对话上下文;Loop 驱动「请求模型 → 执行工具 → 写回」。

pi-ai
统一 LLM API

屏蔽各家模型差异,AgentLoop 通过它请求模型。

分步实现

  1. 定义工具:用装饰器声明一个可被 Agent 调用的函数,写清名称、用途与参数。下面是一个「读文件」工具的示例。
  2. 构造 Agent:把模型实例与工具列表交给 Agent,得到会调用工具的运行时。
  3. 构造 AgentSession:用 Agent 创建一次会话,写入系统提示与用户消息。
  4. 运行并观察事件:订阅 AgentEvent 流,实时看到模型回复与 toolCall 的调用与返回。
  5. 理解核心循环:循环反复「请求模型 → 执行工具 → 写回结果」,直到模型给出不含工具调用的最终答案。

最小代码示例(TypeScript 风格)

import { Agent, tool, AgentSession } from '@earendil-works/pi-agent-core';
import { createModel } from '@earendil-works/pi-ai';

// 1) 定义一个工具:读取文件内容
const readFile = tool({
  name: 'read_file',
  description: '读取指定路径的文件内容',
  parameters: { path: { type: 'string', description: '文件绝对或相对路径' } },
  async run({ path }) {
    return await fs.readFile(path, 'utf8');
  },
});

// 2) 构造 Agent(选定模型 + 工具列表)
const model = createModel('openai/gpt-4o');
const agent = new Agent({ model, tools: [readFile] });

// 3) 构造一次会话并写入消息
const session = new AgentSession(agent);
session.pushSystem('你是一个谨慎的编码助手,先读文件再回答。');
session.pushUser('读一下 ./package.json 并告诉我用了哪些脚本。');

// 4) 运行并观察事件
for await (const event of session.run()) {
  if (event.type === 'text')        console.log('模型:', event.text);
  if (event.type === 'toolCall')    console.log('调用:', event.name, event.args);
  if (event.type === 'toolResult')  console.log('结果:', event.result);
}

核心循环到底是什么

上面那段 session.run() 内部跑的就是 Pi 的稳定内核:

上下文→ model.complete→ toolCall?→ 执行工具→ 写回结果→ 继续 / 停止
  1. 把系统提示、历史消息和工具定义打包成上下文;
  2. 通过 pi-ai 请求模型;
  3. 如果模型返回 toolCall,就执行对应工具,把结果写回上下文;
  4. 带着新结果再次请求模型,直到模型不再调用工具、给出最终答案。
为什么这样设计:把循环写死、把工具和模型做成可替换的外设,你就能在不碰内核的情况下「自我扩展」——运行时加载新工具、新扩展、新资源即可获得新能力。

试着扩展

实战建议:从最小任务开始

第一次跑真机,不要同时接入多个 Provider、扩展和自动化脚本。按这个顺序来:

  1. 最小任务:让 Agent 解释当前目录结构,确认模型响应和会话状态正常;
  2. 逐步加工具:先启用目录读取,再启用单个文件编辑,一次只加一种能力;
  3. 再谈自动化:等上面都稳了,再接多 Provider 和自动化脚本。

故障速查:

✅ 验收标准:能稳定完成一个小任务,并知道如何查看会话、日志和错误信息,才算完成入门配置。

常见问题(FAQ)

Agent 和 AgentSession 有什么区别?

Agent 是「会调用工具的运行时」本身,定义行为与能力;AgentSession 是一次具体对话的上下文容器,持有消息历史、状态与分支。一个 Agent 可以创建多个 Session。

工具函数需要返回什么?

工具只需是普通异步函数,用装饰器标注名称、描述与参数 schema;返回值会被 Pi 序列化后作为 toolCall 结果回传给模型,进入下一轮循环。

没有真实模型能调试吗?

可以。pi-ai 提供 MockModel,能离线模拟模型回复,让你专注验证工具定义与核心循环逻辑,不消耗真实 token。

AgentEvent 里能看到哪些信息?

典型的 AgentEvent 包含模型流式文本、toolCall 的调用与返回、会话状态变更等。订阅它就能在 UI 或日志里实时呈现代理的思考与动作。

微信群二维码

扫码加入
Pi Agent 微信交流群

💬