Genkit 中间件(10分钟阅读)

TLDR AI 工具

摘要

Google 宣布 Genkit 中间件,这是一种可组合的钩子,可拦截 AI 生成调用,实现重试、回退、工具审批和技能,用于构建可靠的智能代理应用。

Genkit 是一个构建全栈、AI 驱动和自主代理应用的框架,适用于任何平台。它支持 TypeScript、Go、Dart 和 Python。Genkit 使用可组合的钩子来拦截生成调用,以实现重试和回退,从而获得最高可靠性,在执行破坏性工具调用前获得人工批准,并在每一层提供可观测性。其中间件系统运行一个工具循环,直至模型完成。Genkit 开发者工具可用于检查、测试和调试应用及中间件执行。
查看原文
查看缓存全文

缓存时间: 2026/05/16 00:14

# 宣布 Genkit 中间件:拦截、扩展并加固您的智能体应用 来源:https://developers.googleblog.com/announcing-genkit-middleware-intercept-extend-and-harden-your-agentic-apps/ Genkit(https://genkit.dev/)是一个开源框架,用于**构建支持任何平台的全栈、AI 驱动与智能体应用**,支持 TypeScript、Go、Dart 和 Python。构建一个可用于生产的智能体应用和 AI 特性,需要的不仅仅是强大的模型和精心的提示词设计。您可能还需要重试与回退机制以实现最大可靠性、在破坏性工具调用前加入人工审核,以及每一层的可观测性。 Genkit 通过**中间件**解决了这一问题:一种可组合的钩子,用于拦截生成调用(包括工具执行循环)并注入自定义行为。中间件系统现已支持 TypeScript、Go 和 Dart,Python 支持即将推出。 ## **Genkit 中间件的工作原理** Genkit 中的每次 `generate()` 调用都会运行一个**工具循环**:模型生成输出,执行所有请求的工具,将结果反馈给新的模型调用,如此循环直到模型完成。中间件钩子附着在该循环的三个层次上: | 钩子 | 运行时机 | 典型用途 | |------|----------|----------| | Generate | 每次工具循环迭代 | 上下文注入、消息重写、对话级逻辑 | | Model | 每次模型 API 调用 | 重试、回退、缓存、延迟日志 | | Tool | 每次工具执行 | 人工介入、沙箱隔离、按工具日志 | ## **预构建中间件** Genkit 提供了几种针对常见用例的预构建中间件解决方案。以下是目前已可用的内容: ### **1. 重试** 在由于临时错误(`RESOURCE_EXHAUSTED`、`UNAVAILABLE` 等)导致模型 API 调用失败时,自动使用带抖动的指数退避进行重试。仅重试模型调用,不重播外围的工具循环。 ``` resp, err := genkit.Generate(ctx, g, ai.WithModelName("googleai/gemini-flash-latest"), ai.WithPrompt("Summarize the quarterly earnings report."), ai.WithUse(&middleware.Retry{ MaxRetries: 3, InitialDelayMs: 1000, BackoffFactor: 2, }), ) ``` Go Copied ### **2. 回退** 当主模型在指定的一组错误代码上失败时,切换到备用模型。当主模型配额用尽时,回退到完全不同的提供商非常有用。 ``` resp, err := genkit.Generate(ctx, g, ai.WithModelName("googleai/gemini-flash-latest"), ai.WithPrompt("Analyze this complex document..."), ai.WithUse(&middleware.Fallback{ Models: []ai.ModelRef{ anthropic.ModelRef("claude-sonnet-4-6", nil), // 回退到 Claude }, Statuses: []core.StatusName{core.RESOURCE_EXHAUSTED}, }), ) ``` Go Copied ### **3. 工具审批** 将工具执行限制在一个允许列表中。任何不在列表中的工具都会触发一个中断,以便在操作继续前进行人工确认。 ``` resp, _ := genkit.Generate(ctx, g, ai.WithPrompt("Delete the temp files"), ai.WithTools(deleteFilesTool), ai.WithUse(&middleware.ToolApproval{ AllowedTools: []string{}, // 空列表 = 每次工具调用都中断 }), ) if len(resp.Interrupts()) > 0 { interrupt := resp.Interrupts()[0] // 提示用户审批,然后使用审批标记恢复。 approved, _ := deleteFilesTool.RestartWith(interrupt, ai.WithResumedMetadata[DeleteInput](map[string]any{"toolApproved": true}), ) resp, err := genkit.Generate(ctx, g, ai.WithMessages(resp.History()...), ai.WithTools(deleteFilesTool), ai.WithToolRestarts(approved), ai.WithUse(&middleware.ToolApproval{}), ) fmt.Println(resp.Text()) } ``` Go Copied ### **4. 技能** 扫描目录中的 `SKILL.md` 文件,并将其内容注入系统提示词。同时还暴露一个 `use_skill` 工具,使模型能够按需加载特定技能。 ``` resp, err := genkit.Generate(ctx, g, ai.WithPrompt("How do I deploy this service?"), ai.WithUse(&middleware.Skills{SkillPaths: []string{"./skills"}}), ) ``` Go Copied ### **5. 文件系统** 通过注入的工具(`list_files`、`read_file`,以及启用写权限时的 `write_file` 和 `edit_file`)赋予模型对本地文件系统的受控访问。路径安全性得到强制执行,因此模型永远无法逃逸根目录。 ``` resp, err := genkit.Generate(ctx, g, ai.WithPrompt("Create a hello world program in the workspace"), ai.WithUse(&middleware.Filesystem{ RootDir: "./workspace", AllowWriteAccess: true, }), ) ``` Go Copied ## **构建自定义中间件** 预构建的中间件覆盖了常见场景,但该系统的真正威力在于编写自己的中间件。假设您正在构建一个智能体客服应用,需要确保模型从不提及竞品产品或内部定价数据。与其在每个提示词中编码这些规则,不如通过中间件来确定性地强制执行它们。 自定义中间件在所有语言中遵循一个简单的契约:提供一个名称和一个返回所需钩子的工厂函数。工厂函数在每次 `generate()` 调用时被调用一次,您只需实现所需的钩子。 以下是一个完整的、约 20 行代码的自定义内容过滤器: ``` // ContentFilter rejects model responses containing any forbidden term. type ContentFilter struct { ForbiddenTerms []string `json:"forbiddenTerms"` } func (ContentFilter) Name() string { return "app/contentFilter" } func (f ContentFilter) New(ctx context.Context) (*ai.Hooks, error) { return &ai.Hooks{ WrapModel: func(ctx context.Context, p *ai.ModelParams, next ai.ModelNext) (*ai.ModelResponse, error) { resp, err := next(ctx, p) if err != nil { return nil, err } text := strings.ToLower(resp.Text()) for _, term := range f.ForbiddenTerms { if strings.Contains(text, strings.ToLower(term)) { return nil, fmt.Errorf("content filter: response contains %q", term) } } return resp, nil }, }, nil } ``` Go Copied 您甚至可以组合并堆叠不同的中间件解决方案。中间件从左到右堆叠,第一个列出的是最外层包装,依此类推: ``` resp, err := genkit.Generate(ctx, g, ai.WithModelName("googleai/gemini-flash-latest"), ai.WithPrompt("What CRM should our customer use?"), ai.WithUse( &middleware.Retry{MaxRetries: 3}, // 外层:重试整个内层堆叠 &ContentFilter{ // 内层:验证模型输出 ForbiddenTerms: []string{"CompetitorCRM", "RivalCo", "internal price"}, }, ), ) ``` Go Copied 这里,`Retry` 包装 `ContentFilter`,而 `ContentFilter` 又包装模型调用。顺序很重要,Genkit 使其明确可见。 如果您认为自己构建了一个对其他开发者有价值的中间件,您可以将其作为一个包发布,让其他人从中受益! ## **开发者 UI 体验** 您可以使用 Genkit 开发者 UI(https://genkit.dev/docs/go/devtools/)来检查、测试和调试您的应用,包括中间件的执行。当您注册中间件时,它会变得在 Dev UI 中可见:您可以检查其配置、追踪通过每个钩子层的执行情况,并测试不同的组合。 抱歉,您的浏览器不支持播放此视频 ## **开始使用** 我们很高兴 Genkit 中间件为您的应用解锁的能力,并期待看到您为解决自己的用例而构建的自定义中间件。查阅中间件文档(https://genkit.dev/docs/go/middleware/)以深入了解,或者如果您是框架新手,可以开始使用 Genkit(https://genkit.dev/docs/go/get-started/)。 有构建新预构建中间件的想法?请提交 issue(https://github.com/genkit-ai/genkit/issues)。我们很乐意听取哪些改进能提升您的开发体验! Happy coding! 🚀

相似文章

CopilotKit/CopilotKit

GitHub Trending (daily)

CopilotKit 是一款一流的 SDK,用于构建具有生成式 UI、共享状态和人机协同工作流的全栈代理应用,已被 Google、LangChain 和 AWS 等主要公司采用。

Google I/O, Gemini Spark, Antigravity

Simon Willison's Blog

Google I/O 推出了 Gemini Spark,一款由 Gemini 3.5 Flash 和 Antigravity 驱动的个人 AI 智能体,同时宣布 Gemini CLI 将转变为闭源的 Antigravity CLI。文章重点突出了智能体产品在提示注入和数据安全处理方面的担忧。