教程中心进阶
进阶

用 Google Genkit Agents API 搭全栈 AI Agent(状态持久化 + 产物 + 流式)

2026.07.24· 7 个步骤 · 22 分钟阅读· 🔧 Google Genkit

你已经会用一堆智能体框架了,但每次产品从「能聊两句」升级到「多轮协作 + 长任务 + 前端实时更新」时,是不是都得把框架内部拆了重接?2026 年 7 月谷歌 Genkit(构建全栈 AI 应用的开源框架)发布预览版 Agents API,核心思路很聪明:把消息历史、工具执行循环、流式传输、状态持久化、前端协议全部塞进一个 chat() 接口背后。无论智能体跑在进程内还是挂在 HTTP 端点后,用法完全一致。本教程用 TypeScript 带你从零跑通一个「记状态、能产出文件、可流式对话」的全栈 Agent。

🔧 本教程适合:会一点 TypeScript/Node、想少写胶水代码、希望同一个 Agent 既能在本地命令行跑、也能原样部署成线上服务的中高级开发者。预览版现支持 TypeScript 与 Go,Python/Dart 在路上。

先搞懂:Genkit Agents API 解决什么痛点?

大多数框架把两类数据混在一起,结果一升级就崩。Genkit 明确区分了它们:

概念通俗解释例子
自定义状态(State)驱动「下一轮对话」的强类型应用数据工作流进度、任务清单、已选实体
产物(Artifact)用户可单独查看 / 下载 / 版本管理的生成物报告、代码补丁、旅行行程
chat() 接口一个抽象,统一上面所有能力一次性应答、流式多轮、暂停等待人工确认

一个 Agent 对象贯穿三种形态:一次性回答、流式多轮对话、等待人工确认的暂停工具调用、独立运行的长耗时任务——全靠同一个对象,产品从聊天机器人迭代到多智能体工作流时不用换框架内部组件。

Step 1:准备环境并初始化 Genkit 项目

1 装 Node,拉起一个 Genkit 工程

Genkit 是 Node 优先的框架,先确认你有 Node 20+,然后新建项目并装包:

# 新建目录并初始化
mkdir my-genkit-agent && cd my-genkit-agent
npm init -y

# 安装 Genkit 核心 + Google AI 插件(用 Gemini 当大脑)
npm install genkit @genkit-ai/ai @genkit-ai/googleai

# 可选:装 CLI 方便本地调试
npm install -D genkit-cli
💡 你需要一个 Google AI / Vertex AI 的 API Key(Gemini)。本地调试时通过环境变量 GEMINI_API_KEY 注入即可,别写死在代码里。

Step 2:定义你的第一个 Agent(chat 接口)

2 用一个 chat() 串起历史、工具与流式

下面是一个最小可跑的 Agent:它维护一段对话历史,能多轮回答。关键就是 agent.chat() 返回的会话对象可以一直复用。

import { genkit } from 'genkit';
import { googleAI } from '@genkit-ai/googleai';

const ai = genkit({ plugins: [googleAI()] });

// 定义一个最简单的 Agent
const agent = ai.defineAgent(
  { name: 'helper', model: googleAI.model('gemini-2.5-flash') },
  async (input) => {
    return `收到:${input.prompt}`;
  }
);

// 发起一轮对话
const session = agent.chat();
const r1 = await session.send('帮我规划一次三天两晚的上海出差');
console.log(r1.text);
🚀 到这里你已经有一个能多轮对话的会话了。session.send() 自动把历史带进去,不用自己拼 messages 数组。

Step 3:给 Agent 加工具,让它真正「干活」

3 注册一个工具,Agent 自己决定什么时候调

光能聊没用,得让它能查实时数据。我们加一个「查天气」工具:

const getWeather = ai.defineTool(
  { name: 'getWeather', description: '查询某城市天气',
    inputSchema: z.object({ city: z.string() }) },
  async ({ city }) => {
    // 这里换成你真实的天气 API
    return { city, tempC: 28, condition: '晴' };
  }
);

const agent = ai.defineAgent(
  { name: 'tripPlanner', model: googleAI.model('gemini-2.5-flash'),
    tools: [getWeather] },
  async (input) => input.prompt
);

工具循环由框架接管:你不用写「if 用户问天气就调工具」的判断,Genkit 会在 chat() 内部自动跑「思考→调工具→再思考」循环,直到给出最终答案。

Step 4:区分「状态」与「产物」,让 Agent 会攒东西

4 工具既能更新状态,也能产出文件

这是 Genkit 最实用的设计:工具可以在当前会话里更新「状态」或「产物」,客户端实时收到变更。

const saveItinerary = ai.defineTool(
  { name: 'saveItinerary',
    description: '把行程存成可下载的产物',
    inputSchema: z.object({ markdown: z.string() }) },
  async ({ markdown }, ctx) => {
    // 产物:用户能单独下载/版本管理
    ctx.artifacts.set('itinerary', { content: markdown });
    return { ok: true };
  }
);

// 同时在多轮中维护「已选城市」状态
// ctx.state.set('selectedCity', '上海')
🔑 经验法则:会随对话滚动、影响下一轮决策的,放 State;需要交付给用户、能独立查看的,放 Artifact。前端可以订阅这两类变化做实时渲染。

Step 5:状态持久化(服务端 vs 客户端管理)

5 选一种会话存储,断线也能续上

Genkit 提供两种持久化方案,二选一:

// 方案 A:服务端管理(推荐生产多实例)
// 内置 Firestore(生产)/ 内存(开发)/ 文件(本地测试)
const ai = genkit({
  plugins: [googleAI()],
  sessionStore: { kind: 'file', path: './sessions' }
});
// 客户端用 sessionId 重新连接,自动还原历史+状态+产物

// 方案 B:客户端管理(适合有数据驻留要求的场景)
// 不配存储,服务端每次返回完整状态,客户端回传
// 代价:会话变长后网络负载会增加

合规敏感场景选方案 B:服务端不持久化任何用户数据,满足严格的数据驻留约束。但代价是会话增长后每次请求都要带着完整状态往返。

Step 6:开启流式传输,前端实时显示

6 把 Agent 的「思考过程」流到界面上

sendStream 替代 send,前端就能像打字机一样收到增量内容,连状态/产物变更也实时推送:

const { stream, response } = session.sendStream('把行程细化成每天安排');

// 前端:边收边渲染
for await (const chunk of stream) {
  render(chunk.text);   // 增量文本
}
const final = await response;  // 最终完整结果
💡 流式不只是文字——工具调用、状态更新、产物生成都会实时推到客户端。做「AI 正在查资料」的 loading 动画就靠订阅这些事件。

Step 7:部署成 HTTP 端点,同一个 Agent 复用

7 一行启动,原样变成线上服务

Genkit 的精髓:本地和线上是同一个 Agent 对象,不用为部署重写逻辑。

# 本地用开发者 UI 调试(带可视化 trace)
npx genkit start

# 部署到 Cloud Run / 任意 Node 服务
# 用 genkit/express 暴露 HTTP 端点
import { expressHandler } from 'genkit/express';
app.post('/agent/chat', expressHandler(agent));
🎉 恭喜!你跑通了「定义 Agent → 加工具 → 管状态/产物 → 持久化 → 流式 → 部署」的全链路。这套 chat() 抽象让你在「简易聊天」和「多智能体工作流」之间平滑升级,不用换框架。

常见问题速查

现象大概率原因 & 解决
session.send 报模型未配置没装 googleAI 插件或 GEMINI_API_KEY 未注入
工具没被调用工具 description 太模糊,模型判断不需要
刷新页面后历史丢了没配 sessionStore,或客户端没回传 sessionId
流式卡住不动用了 send 而非 sendStream,或前端没 await stream