使用 Genkit JS 开发 AI 应用:Flow、Agent、Dotprompt 与 CLI 调试实战指南
【免费下载链接】skillsAgent Skills for Google products and technologies项目地址: https://gitcode.com/GitHub_Trending/skills29/skills
导读
本文以开源仓库 skills29/skills 中的 Genkit JS Skill 为核心,系统讲解如何在 Node.js/TypeScript 中使用 Google 官方 AI 编排框架Genkit开发 AI 应用:从genkit实例初始化、defineFlow定义首个生成式流程,到 Dotprompt 提示词工程、Beta 版 Agent 多轮对话、中间件(Middleware)横切能力,再到genkit start/flow:run/trace系列 CLI 的调试与验证工作流。读完本文,你将掌握一套可复制、可验证的 Genkit 开发闭环:编写代码 → CLI 捕获 Trace → 依据 Trace 定位错误 → 依据官方文档修复,并清楚区分 v1.x 与 pre-1.0 的破坏性 API 差异,避免踩坑。
注意:本文所有能力均以仓库文档与源码为事实依据。Genkit 正处于快速演进期,Agent API 为 Beta 预览状态,相关导入路径、函数签名与版本号以文中标注的版本要求为准。
环境前置:genkit CLI 版本要求
开发 Genkit JS 应用的第一步是确保命令行工具genkit可用,且版本满足要求。
- 运行
genkit --version验证版本,最低要求为 1.29.0; - 若命令不存在,或版本为 1.x 且低于 1.29.0,请升级:
npm install -g genkit-cli@^1.29.0新项目接入:如果是在全新代码库中初始化 Genkit,不要跳过配置步骤,建议直接阅读仓库中的 Setup 指南——它给出了完整的项目脚手架流程(创建ai/genkit.ts、ai/flows、ai/tools目录结构、将genkit-cli加入 devDependencies 并添加genkit:dev脚本等)。
CLI 版本说明同样记录在 Docs & CLI Reference 中;若不想全局安装,也可以用npx -y genkit-cli@^1.29.0前缀临时指定版本运行。
Hello World:用defineFlow定义第一个生成流程
Genkit v1.x 的入口是genkit()工厂函数。它接收插件列表,返回一个ai实例,所有能力(生成、流程、提示词、工具、Agent)都挂在该实例上。以下是最小可运行示例:
import { z, genkit } from 'genkit'; import { googleAI } from '@genkit-ai/google-genai'; // 初始化 Genkit,挂载 Google AI 插件 const ai = genkit({ plugins: [googleAI()], }); export const myFlow = ai.defineFlow({ name: 'myFlow', inputSchema: z.string().default('AI'), outputSchema: z.string(), }, async (subject) => { const response = await ai.generate({ model: googleAI.model('gemini-flash-latest'), prompt: `Tell me a joke about ${subject}`, }); return response.text; });几个值得注意的 v1.x 要点:
z必须从genkit包导入(而不是直接引zod),inputSchema/outputSchema用 Zod 描述输入输出,flow:run时会对入参做校验;- 模型引用使用插件工厂
googleAI.model('gemini-flash-latest'),优先使用*-latest别名而非带版本号的旧模型(详见后文"迁移"一节); - 响应对象属性是直接访问:
response.text(不是response.text())。
更多可复现的最小示例(基础文本生成、结构化输出、流式生成、思考模式、Google Search Grounding、图像生成/编辑、TTS 语音生成)可在 Examples 中找到,例如结构化输出用output: { schema: JokeSchema }让response.output获得强类型。
Dotprompt:把提示词搬进.prompt文件
把提示词内联在 TypeScript 里不利于迭代与变体管理。Genkit 的Dotprompt用.prompt文件承载提示词:YAML frontmatter 描述模型、输入输出 schema、工具与中间件,正文用 Handlebars 模板渲染。
加载位置与promptDir
默认从./prompts目录自动加载.prompt文件,可通过promptDir选项配置(设为null可关闭自动加载):
import { genkit } from 'genkit'; import { googleAI } from '@genkit-ai/google-genai'; const ai = genkit({ plugins: [googleAI()], promptDir: './prompts', // default });文件格式示例
prompts/recipe.prompt:
--- model: googleai/gemini-pro-latest input: schema: food: string ingredients?(array): string # ? = optional output: schema: Recipe # 引用通过 ai.defineSchema 注册的命名 schema --- You are a chef famous for creative recipes. Generate a recipe for {{food}}. {{#if ingredients}} Make sure to include the following ingredients: {{list ingredients}} {{/if}}Schema 字段既可使用紧凑的 Picoschema 语法(如上),也可通过ai.defineSchema注册命名 schema 后在 frontmatter 中按名引用。详细说明见 Dotprompt 参考。
加载与调用:ai.prompt()
ai.prompt(name, { variant? })返回可调用的ExecutablePrompt,同时提供.stream()、.render()、.asTool():
// 非流式:直接以输入对象调用 const recipePrompt = ai.prompt('recipe'); const { output } = await recipePrompt({ food: 'banana bread' }); // 流式 const storyPrompt = ai.prompt('story'); const { response, stream } = storyPrompt.stream({ subject: 'a robot' }); for await (const chunk of stream) { console.log(chunk.text); } const final = await response; // 只渲染不生成(适合拼 ai.generate 或 LLM-judge 评测) const rendered = await ai.prompt('recipe').render({ food: 'banana bread' }); // rendered 是一个 GenerateOptions 对象(messages、model、config、...)变体、Partials 与 Helper
- 变体(Variants):命名文件为
<name>.<variant>.prompt(如recipe.robot.prompt),调用时传{ variant: 'robot' }; - Partials:以
_<name>.prompt命名可复用片段,模板中用{{>name param=value}}引入; - Helper:用
ai.defineHelper('list', fn)注册模板内可调用的函数(如{{list ingredients}})。
frontmatter 中的工具与控制字段
.prompt的 frontmatter 可直接声明工具调用与中间件,让"Agent 风格"的提示词在文件内自洽描述:
--- model: googleai/gemini-flash-latest input: schema: tone: string tools: - getAttractions - getFlightInfo toolChoice: auto # auto | required | none maxTurns: 20 # 最大工具调用循环轮数 returnToolRequests: false # true 时返回工具请求而不实际执行 use: - name: retry # 也支持裸字符串:`- retry` config: maxRetries: 4 --- {{role "system"}} You are a friendly trip planning assistant. Help users plan trips by suggesting attractions and looking up flight information. Keep your tone {{tone}}. {{history}}use中的中间件名会解析到注册在 Genkit 实例上的中间件,因此需要把中间件以插件形式注册:
import { retry } from '@genkit-ai/middleware'; const ai = genkit({ plugins: [googleAI(), retry.plugin()], promptDir: './prompts', });注意:Agent(defineAgent)与.prompt共享同一套 frontmatter 字段(system/prompt、tools、maxTurns、returnToolRequests、use),一个带{{history}}和工具声明的.prompt文件可以直接支撑一个 Agent。
Agents(Beta):持久化多轮对话
Genkit 提供了预览版AgentAPI,用于持久化、多轮对话场景(会话、快照、中断、分支、后台执行)。
⚠️Beta 说明:Agent API 尚未稳定。服务端 API 从
genkit/beta导入,浏览器客户端从genkit/beta/client导入——不是稳定的genkit入口。要求genkit>= 1.39.0。导入路径与函数签名可能变动,始终使用genkit/beta前缀。
与裸ai.generate+ 工具循环相比,Agent 额外提供:
- Sessions:以不可变**快照(snapshot)**形式记录多轮历史;
- State:类型化会话状态(消息 + 自定义数据 + artifacts);
- Interrupts:人机协同的暂停/恢复;
- Branching:从任意快照分叉对话;
- Detaching:后台运行一轮并轮询结果。
定义与使用 Agent
// genkit.ts —— 注意 agents 需要从 'genkit/beta' 导入 import { genkit } from 'genkit/beta'; import { googleAI } from '@genkit-ai/google-genai'; export const ai = genkit({ plugins: [googleAI()], model: googleAI.model('gemini-flash-latest'), });import { z } from 'genkit'; import { ai } from './genkit.js'; const getWeather = ai.defineTool( { name: 'getWeather', description: 'Look up the current weather for a city.', inputSchema: z.object({ city: z.string() }), outputSchema: z.object({ tempC: z.number(), summary: z.string() }), }, async ({ city }) => ({ tempC: 21, summary: 'Sunny' }) ); export const weatherAgent = ai.defineAgent({ name: 'weatherAgent', system: 'You are a helpful weather assistant. Use the getWeather tool. Be concise.', tools: [getWeather], // `store` 可选。省略即采用客户端托管状态(见下文)。 });常用defineAgent选项:
name(必填):action 名称;system/prompt/ dotprompt 字段:与definePrompt相同;tools:Agent 可用的工具与中断;model:覆盖默认模型;store:服务端持久化的SessionStore;stateSchema:z.ZodType<State>,描述自定义会话状态,设置后State在加载时被推断并校验;input/inputSchema:提示词模板的输入变量。
const chat = weatherAgent.chat(); // 非流式一轮:历史自动延续 const res = await chat.send('Weather in Tokyo?'); console.log(res.text); console.log(res.snapshotId); // 本轮不可变检查点 id const res2 = await chat.send('What about Paris?'); // 流式一轮 const turn = chat.sendStream('And London?'); for await (const chunk of turn.stream) { process.stdout.write(chunk.text ?? ''); } const final = await turn.response;会话持久化:Session Store
当 Agent 配置了store时,服务端持有会话历史;每轮产生不可变快照,快照链承载对话状态,同时支持分支与后台执行。内置三种存储:
import { InMemorySessionStore, FileSessionStore } from 'genkit/beta'; // 内存:适合测试/开发,重启即丢失 const memStore = new InMemorySessionStore(); // 文件:快照持久化到 <dir>/global/<snapshotId>.json const fileStore = new FileSessionStore('./.snapshots'); // 文件 + 链裁剪:每条链只保留最近 N 个快照 const pruning = new FileSessionStore('./.snapshots', { maxPersistedChainLength: 3, });挂载到 Agent 后,可用chat({ snapshotId })从某快照恢复会话;stateSchema可为会话附加类型化自定义状态(存于SessionState的.custom字段):
const profileAgent = ai.defineAgent({ name: 'profileAgent', system: 'Greet the user by name and tailor answers to their tier.', store: new InMemorySessionStore<z.infer<typeof Profile>>(), stateSchema: Profile, }); const chat = profileAgent.chat({ state: { custom: { name: 'Ada', tier: 'pro' } }, });生产级方案:FirestoreSessionStore(来自@genkit-ai/google-cloud/beta)将每轮持久化为增量 JSON Patch diff,锚定在周期性分片检查点上,避免单个文档触及 Firestore 1 MiB 上限;每轮读写量由checkpointInterval(默认 25 轮全量检查点)约束,适合长会话的聊天/编码 Agent。也支持实现自定义SessionStore接口(getSnapshot/saveSnapshot/onSnapshotStateChange)。详见 Sessions & persistence。
客户端托管状态(无 store)
如果 Agent不配store,服务端完全无状态,会话状态 blob(消息 + 自定义数据 + artifacts)归调用方所有。remoteAgent客户端(来自genkit/beta/client)会自动在每轮请求间往返携带状态,无需管理快照 id:
// 服务端:无 store → 无状态,客户端持有状态 blob export const weatherAgentStateless = ai.defineAgent({ name: 'weatherAgentStateless', system: 'You are a helpful weather assistant. Use getWeather. Be concise.', tools: [getWeather], });// 客户端:复用同一个 chat,状态自动串接 import { remoteAgent, type AgentChat } from 'genkit/beta/client'; const agent = remoteAgent({ url: '/api/weatherAgentStateless' }); const chat: AgentChat = agent.chat(); await chat.send('Weather in London?'); await chat.send('Is it sunny in Tokyo?'); // 记得之前的轮次 const res = await chat.send('And Paris?'); console.log(JSON.stringify(res.raw.state, null, 2));选择建议:不想在服务端运行存储(客户端自行持久化历史)时用客户端托管状态;希望服务端持有历史,或需要分支/后台执行时用 Session Store(中断两种方式都支持)。
通过 HTTP 提供 Agent
用@genkit-ai/express的expressHandler暴露 Agent,可选挂载配套的getSnapshotDataAction(快照查找/恢复)与abortAgentAction(后台中断):
import { expressHandler } from '@genkit-ai/express'; import express from 'express'; import { weatherAgent } from './weather-agent.js'; const app = express(); app.use(express.json()); app.post('/api/weatherAgent', expressHandler(weatherAgent)); app.post( '/api/weatherAgent/getSnapshot', expressHandler(weatherAgent.getSnapshotDataAction) ); app.post( '/api/weatherAgent/abort', expressHandler(weatherAgent.abortAgentAction) ); app.listen(8080);浏览器端通过remoteAgent拿到类型化 HTTP 客户端;getSnapshotUrl/abortUrl默认指向${url}/getSnapshot与${url}/abort。多 Agent 服务、CORS/流式响应头、静态 Web UI 及 Next.js/Firebase 等宿主框架的细节见 Deploying agents。Agent 生态的其余主题——人机协同中断(agents-human-in-the-loop.md)、分支(agents-branching.md)、后台执行(agents-background.md)、类型化状态(agents-state.md)、Artifacts(agents-artifacts.md)、多 Agent 编排(agents-multi-agent.md)、defineCustomAgent全控制(agents-custom.md)——均在 Agents 参考 中有渐进式指引。
Middleware:给生成过程叠加横切能力
中间件包装生成过程以增加横切行为——重试、回退、附加工具、请求/响应变换等。通过use: [...]数组挂载,该数组在ai.generate/ai.generateStream、可执行提示词(definePrompt)和 Agent(defineAgent)上都可用:
import { retry } from '@genkit-ai/middleware'; const res = await ai.generate({ model: googleAI.model('gemini-flash-latest'), prompt: 'Say hello', use: [retry({ maxRetries: 2 })], });务必通过.plugin()注册中间件——不注册时在use: [...]中也能工作,但不会出现在 Genkit Dev UI 中:
import { genkit } from 'genkit'; import { googleAI } from '@genkit-ai/google-genai'; import { retry, artifacts } from '@genkit-ai/middleware'; export const ai = genkit({ plugins: [googleAI(), retry.plugin(), artifacts.plugin()], });@genkit-ai/middleware内置工厂
npm i @genkit-ai/middleware| 中间件 | 作用 | 关键选项 |
|---|---|---|
retry(options?) | 瞬时错误指数退避重试 | maxRetries: 3、initialDelayMs: 1000、maxDelayMs: 60000、backoffFactor: 2、noJitter: false;默认状态码UNAVAILABLE, DEADLINE_EXCEEDED, RESOURCE_EXHAUSTED, ABORTED, INTERNAL |
fallback(options) | 主模型失败时回退到其他模型 | models: [...](按序尝试)、isolateConfig: false;默认状态码额外含NOT_FOUND, UNIMPLEMENTED |
artifacts(options?) | 注入write_artifact/read_artifact工具 | readonly: false(true 时仅read_artifact) |
agents(options) | 子 Agent 委派,每个子 Agent 注入一个delegate_to_<name>工具 | agents: ['researcher', 'coder']、maxDelegations: 5 |
filesystem(options) | 授予模型list_files/read_file/write_file/search_and_replace工具,沙箱限定根目录 | rootDirectory(必填)、allowWriteAccess: false、toolNamePrefix: '' |
skills(options?) | 扫描目录中的 skill 文件(frontmattername/description),向系统提示词注入清单并提供use_skill工具 | skillPaths: ['skills'] |
toolApproval(options) | 工具执行白名单,白名单外抛ToolInterruptError(可经中断恢复) | approved: ['getWeather', 'search'] |
核心内置模型中间件
部分中间件随genkit核心提供(无需额外包),从genkit/model/middleware导入:
downloadRequestMedia({ maxBytes? })——抓取 URL 媒体并内联;validateSupport({ name, ... })——断言模型支持所请求的特性;simulateSystemPrompt({ preface? })——为不支持 system prompt 的模型模拟;augmentWithContext(options?)——注入检索到的上下文文档;simulateConstrainedGeneration(options?)——模拟受约束/JSON 输出。
import { simulateConstrainedGeneration } from 'genkit/model/middleware'; await ai.generate({ model: someModel, prompt: '...', use: [simulateConstrainedGeneration()], });Agent 与中间件的组合
Agent 与中间件是天然搭配:use: [...]数组是叠加复杂行为的入口。一个完整的编码助手 Agent 几乎全是配置:
import { filesystem, retry, skills, toolApproval } from '@genkit-ai/middleware'; import { FileSessionStore } from 'genkit/beta'; import { ai } from './genkit.js'; export const codingAgent = ai.defineAgent({ name: 'codingAgent', system: 'You are an expert AI coding assistant working in a sandboxed workspace.', tools: [runShell, askUser], // 你自己的工具/中断 use: [ // 风险工具执行前要求用户批准(中断);读取类自动放行。 // 顺序很重要:toolApproval 需放在 filesystem 之前。 toolApproval({ approved: ['list_files', 'read_file', 'use_skill', 'run_shell', 'ask_user'], }), // list_files / read_file / write_file / search_and_replace,沙箱限定。 filesystem({ rootDirectory: WORKSPACE_DIR, allowWriteAccess: true }), // 通过 use_skill 工具按需加载编码规范。 skills({ skillPaths: [SKILLS_DIR] }), // 模型瞬时错误自动重试。 retry(), ], store: new FileSessionStore('./.snapshots-coding'), // toolApproval 需要 maxTurns: 30, });编写自定义中间件
用generateMiddleware编写可复用、具名的中间件。它返回一个在use: [...]中调用的工厂(与@genkit-ai/middleware包内中间件的构建方式一致),工厂可接收可选的 Zod 校验配置,并拿到ai实例:
// timing.ts import { generateMiddleware, z } from 'genkit'; const OptionsSchema = z.object({ label: z.string().optional() }); export const timing = generateMiddleware( { name: 'timing', description: 'Logs how long the model call takes.', configSchema: OptionsSchema, }, ({ config, ai }) => { // 每次 generate() 调用执行一次。返回下述任一 hook。 return { model: async (req, ctx, next) => { const start = Date.now(); const res = await next(req, ctx); console.log(`[${config?.label ?? 'timing'}] ${Date.now() - start}ms`); return res; }, }; } );可用 hook 共四类:generate(envelope, ctx, next)包装整个 generate action(envelope 携带{ request, currentTurn, messageIndex },适合注入请求参数、后处理响应或捕获工具循环错误);model(req, ctx, next)包装底层模型调用(缓存、重试、请求/响应改写);tool(req, ctx, next)包装单个工具调用(校验输入、缓存或覆盖工具输出);tools: ToolAction[]静态注入工具(artifacts()/filesystem()即通过此方式加工具)。钩子选择建议与完整签名见 Building custom middleware。
关键警告:不要依赖内部知识,务必查文档
Genkit 近期经历了一次重大破坏性 API 变更(v1.x)。训练知识很可能已过时,必须查阅文档再动手:
genkit docs:read js/get-started.md genkit docs:read js/flows.md详见 Common Errors 中列出的已废弃 API 及其 v1.x 替代写法。始终通过 Genkit CLI 或仓库内参考文档核实信息。
v1.x 与 pre-1.0 迁移对照速查
| 项目 | 正确(v1.x) | 错误(pre-1.0) |
|---|---|---|
| 包导入 | import { z, genkit } from 'genkit';+ 插件各自导入 | import { genkit } from '@genkit-ai/core';import { defineFlow } from '@genkit-ai/flow' |
| 模型引用 | googleAI.model('gemini-flash-latest')或带插件前缀字符串'googleai/gemini-flash-latest' | 直接使用导入的模型对象,或不带插件前缀的裸字符串'gemini-flash-latest' |
| Gemini 模型选择 | 使用gemini-flash-latest/gemini-pro-latest别名 | 版本化旧模型(gemini-1.5-flash、gemini-2.5-flash)已废弃 |
| 响应访问 | 直接属性response.text、response.output | 方法调用response.text()、response.output() |
| 流式生成 | 不 awaitgenerateStream;直接迭代stream;await response取最终结果 | for await (const chunk of stream());await response() |
| 初始化 | const ai = genkit({ plugins: [...] }) | 全局配置configureGenkit(...) |
| Flow 定义 | ai.defineFlow({...}, fn)(挂在实例上) | 从@genkit-ai/flow全局导入defineFlow |
永远不要直接导入@genkit-ai/flow、@genkit-ai/ai或@genkit-ai/core包。
Zod 与 Schema 常见错误
- 导入来源:始终
import { z } from "genkit",直接引zod包可能导致实例不匹配或兼容性问题; - 支持类型:坚持标量(
string/number/boolean)、object、array等基础类型,避免除非必要且已验证的复杂 Zod 特性; - 描述字段:输出 schema 的字段务必使用
.describe('...')引导 LLM 正确填充。
多模态与音频注意事项
- 使用图像生成模型(如
gemini-2.5-flash-image)时必须在 config 中指定responseModalities: ["TEXT", "IMAGE"],否则会报错或输出格式不正确; - 语音生成的返回内容可能是裸 PCM 数据(如 Google GenAI)而非 MP3/WAV(OpenAI 返回 MP3)。不要假设是 MP3,不要直接把裸 PCM 塞进 HTML audio 标签,先运行
genkit docs:search "speech audio"查找提供商特定的转换步骤(如 PCM 转 WAV)。参考 Examples 中的 TTS 完整示例。
错误排查协议(不可协商)
遇到任何与 Genkit 相关的错误(ValidationError、API 错误、类型错误、404 等)时:
- 强制第一步:阅读 Common Errors;
- 判断错误是否匹配已知模式;
- 应用文档中记录的解决方案;
- 仅当在 common-errors.md 中找不到时,再查阅其他来源(如
genkit docs:search)。
禁止:基于假设或内部知识尝试修复;"因为你觉得你知道答案"而跳过阅读 common-errors.md;依赖 pre-1.0 Genkit 的模式。
此协议对错误处理不可协商。
开发工作流(Agent 场景推荐流程)
- 判断 Agent 还是 Flow:任务是对话式、多轮的,或被称为"agent / assistant / chatbot"时,用
ai.defineAgent(见 Agents)构建,而不是在 flow 内手搓generate+ 工具循环;只有单次、无状态的生成才用普通 flow。 - 选择 Provider:Genkit 是 provider 无关的(Google AI、OpenAI、Anthropic、Ollama 等)。用户未指定时默认 Google AI;询问其他 provider 时用
genkit docs:search "plugins"查文档。 - 识别框架:检查
package.json确定运行时(Next.js、Firebase、Express)。查找@genkit-ai/next、@genkit-ai/firebase或@genkit-ai/google-cloud,并按对应框架模式适配实现。 - 遵循最佳实践:
- 项目结构上,把 flows 和 tools 分目录存放(如
src/flows、src/tools),用index.ts统一导出; - Google AI 场景始终使用最新别名(
gemini-flash-latest通用、gemini-pro-latest复杂任务); - 敏感 key(如
GEMINI_API_KEY)存入环境变量或.env,绝不硬编码; - 保持最小化:只指定与默认值不同的选项;不确定时查文档/源码。详见 Best Practices。
- 项目结构上,把 flows 和 tools 分目录存放(如
- 确保正确性:
- 修改后运行类型检查(如
npx tsc --noEmit); - 类型检查失败时先查 Common Errors 再搜源码;
- 用 Trace 验证,而不是盲跑。直接运行应用(
node/tsx/npm start)不会捕获开发 Trace,必须用genkit start启动(见下节)。
- 修改后运行类型检查(如
- 处理错误:任何错误的第一步都是阅读 Common Errors,匹配文档模式,先应用文档修复再尝试其他方案。
CLI 使用指南:用 Trace 证明工具真的被调用
查找文档的命令
genkit docs:search <query> # 例:genkit docs:search "streaming" genkit docs:list # 列出全部文档 genkit docs:read <path> # 例:genkit docs:read js/flows.mdgenkit start:无侵入式包装,捕获一切 Trace
genkit start无侵入地包装任何使用 Genkit 库的 Node.js 程序:程序原样运行,同时捕获每个 Genkit action 的 Trace,让你在终端里证明工具确实被调用、检查模型输入输出,即使是无头检查也可以。它会转发 stdio,因此依赖 stdin/stdout 的交互式 CLI 工具也能正常工作。直接运行应用(node/tsx/npm start)会跳过 Trace 捕获,等于盲调。
主要模式(默认):在正常运行命令前加genkit start --前缀:
genkit start -- npx tsx --watch src/index.ts genkit start --noui -- npx tsx src/index.ts # 不带 Dev UI(仍是常驻服务)genkit start会一直运行直到按 Ctrl+C。这对常见场景(Web/移动应用调用的服务端、你自行退出的交互式 CLI)是预期且正确的。--noui只去掉 Dev UI,不是一次性命令,不会自行退出。不要把genkit start当作自动化/非交互环境中的阻塞步骤。
非交互使用(Agent/CI):在--前加全局--non-interactive标志,让 CLI 使用默认值、绝不阻塞等待提示(如首次运行的 analytics 通知):
genkit start --non-interactive -- npx tsx src/index.ts其他框架示例:Next.js 用genkit start -- npx next dev。开发期推荐加 watcher 自动重载(tsx --watch/node --watch)。
flow:run:运行单个 Flow(自动退出)
按名称从 CLI 调用指定 flow。在--后追加运行命令来为本次运行拉起运行时:
genkit flow:run myFlow '{"data": "input"}' -- npx tsx src/index.ts这是自终止的:运行一次 flow,打印Trace ID后退出(用genkit trace:get <id>检查)。因此它是"必须自行退出的快速非交互检查"的正确选择,不会像genkit start那样阻塞。
始终显式传输入 JSON:省略时flow:run会发送undefined,不会回退到 schema 的.default(),带默认值输入参数的 flow 会因此校验失败。注意:flow:run运行的是flow(ai.defineFlow),不能直接flow:run一个 agent(ai.defineAgent)。要从 CLI 验证 Agent,把一轮对话包进一个一次性 flow 再运行:
import { z } from 'genkit'; import { weatherAgent } from './weather-agent.js'; import { ai } from './genkit.js'; export const tryWeatherAgent = ai.defineFlow( { name: 'tryWeatherAgent', inputSchema: z.string(), outputSchema: z.string() }, async (message) => (await weatherAgent.chat().send(message)).text ); // genkit flow:run tryWeatherAgent '"Weather in Tokyo?"' -- npx tsx src/index.tsTrace 调试:最快看到提示词与模型 I/O 的方式
在genkit start下运行任意程序后,从终端检查 Trace:
genkit trace:list # 查找最近的 Trace ID genkit trace:get <traceId> # 完整 Trace 详情(输入、输出、工具调用、错误) genkit trace:get <traceId> --format json # 机器可读 JSON,可直接管道给 jq 等解析器机器可读输出请加--format json:默认输出面向人类(横幅/日志行、大 Trace 可能截断),不要直接管道;用--format json、grep 或 Dev UI 的 Trace 查看器。genkit trace:get对调试失败的模型调用、检查工具执行、分析 flow 中某一步的确切输入输出尤其有用。更多命令见 CLI Reference,完整命令列表用genkit --help。
评测:eval:flow与eval:run
genkit eval:flow <flowName> [data] -- <run cmd>:运行 flow 并针对已配置的 evaluator 评估输出。单输入示例:genkit eval:flow answerQuestion '[{"testCaseId": "1", "input": {"question": "What is Genkit?"}}]' -- npx tsx src/index.ts;批量输入用--input inputs.json;genkit eval:run <dataset>:对数据集运行已配置的 evaluator,示例:genkit eval:run dataset.json --output results.json。
新项目落地:从 Setup 到开发闭环
仓库中的 Setup 指南 给出了完整的初始化步骤,摘要如下:
- 检查代码库中是否已安装 provider 插件(如
@genkit-ai/google-genai、@genkit-ai/oai-compat、genkitx-*);无偏好时默认@genkit-ai/google-genai,Next.js 项目还需装@genkit-ai/next; - 在源码目录创建
ai/genkit.ts(只挂模型 provider 插件,不要加 next 插件):
import { genkit, z } from 'genkit'; // 在此导入所选 provider 插件。示例: import { googleAI } from '@genkit-ai/google-genai'; export const ai = genkit({ plugins: [ googleAI(), // 在此添加 provider 插件 ], model: googleAI.model('gemini-flash-latest'), // 在此设置模型 }); export { z };- 创建
ai/tools、ai/flows目录(暂空),以及ai/index.ts(import 各 flow/tool 供 Dev UI 使用); - 将
genkit-cli加入 devDependencies(如npm install -D genkit-cli)锁定版本并在 CI 中可用,然后在package.json添加genkit:dev脚本:genkit start -- npx tsx --watch {sourceDir}/ai/index.ts; - 开发期运行
npm run genkit:dev(常驻、Dev UI 在 http://localhost:4000),并设置环境变量(Google provider 需GEMINI_API_KEY)。
总结:Genkit JS 开发闭环
围绕 Genkit JS 的核心心智模型可以浓缩为四点:
- 一切挂在
ai实例上:genkit()工厂返回的实例提供generate、defineFlow、definePrompt、defineTool、defineAgent、defineSchema、defineHelper等全部能力; - 提示词与 Agent 配置即代码:
.prompt文件用 frontmatter 承载模型、schema、工具与中间件,Agent 的复杂行为(文件系统、技能、审批、重试)通过use中间件数组以声明式方式叠加; - 先查文档再动手:v1.x 经历了破坏性 API 变更,任何错误的第一步都是查阅 Common Errors,日常开发用
genkit docs:search/docs:read获取权威信息; - 用 Trace 证明一切:
genkit start捕获每次模型 I/O 与工具调用,flow:run提供可自动退出的非交互验证,trace:get --format json让调试结果可管道、可机器解析。
按此闭环开发,你可以在保持代码最小化的同时获得完整的可观测性,让每次模型调用、每个工具执行都有据可查。更深入的参考资料(Agent 生态、中间件目录、CLI 全量命令、最小可复现示例、错误速查)均可在本仓库 genkit-js 目录 下继续探索。
【免费下载链接】skillsAgent Skills for Google products and technologies项目地址: https://gitcode.com/GitHub_Trending/skills29/skills
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考