Google Developers Blog

Announcing Genkit Middleware: Intercept, extend, and harden your agentic apps

8.5内容质量
Announcing Genkit Middleware: Intercept, extend, and harden your agentic apps

TL;DR · AI 摘要

Genkit middleware provides composable hooks to intercept, extend, and harden agentic applications with pre-built solutions for retries, fallbacks, tool approval, skills, and filesystem access.

核心要点

  • 支持重试、回退、工具审批等预置中间件
  • 提供文件系统访问和技能注入功能
  • 可自定义中间件扩展应用能力

结构提纲

按章节快速跳转。

  1. 介绍Genkit框架及其核心功能

  2. 描述生成调用的工具循环和三个中间件层

  3. 用于上下文注入和对话逻辑

  4. 处理重试、缓存和延迟日志

  5. 实现人机交互和工具日志

  6. 列出可用的预置中间件解决方案

  7. 自动重试临时错误并使用指数退避

  8. 在主模型失败时切换到备用模型

思维导图

用一张图看清主题之间的关系。

查看大纲文本(无障碍 / 无 JS 友好)
  • Genkit Middleware
    • 核心功能
      • 拦截生成调用

金句 / Highlights

值得收藏与分享的关键句。

  • Genkit middleware provides composable hooks that intercept generation calls, including the tool execution loop, and inject custom behaviors.

    第1段

    ⬇︎ 下载 PNG𝕏 分享到 X
  • Pre-built middleware includes retry, fallback, tool approval, skills, and filesystem access features.

    第4段

    ⬇︎ 下载 PNG𝕏 分享到 X
  • Custom middleware can be created to extend application capabilities for specific use cases.

    最后段

    ⬇︎ 下载 PNG𝕏 分享到 X
#AI#中间件#Genkit
打开原文

宣布推出 Genkit 中间件:拦截、扩展和强化你的代理型应用

URL 来源: https://developers.googleblog.com/announcing-genkit-middleware-intercept-extend-and-harden-your-agentic-apps/

发布日期: 2026-05-14

Genkit 是一个开源框架,用于构建全栈、AI 驱动且代理型的应用程序,支持任何平台,并兼容 TypeScript、Go、Dart 和 Python。构建生产就绪的代理型应用程序和 AI 功能需要的不仅仅是强大的模型和精心设计的提示词。你可能还需要重试和回退机制以确保最大可靠性,在破坏性工具调用前进行人工审批,以及在每一层实现可观测性。

Genkit 通过 中间件 解决了这些问题:可组合的钩子可以拦截生成调用(包括工具执行循环),并注入自定义行为。目前,中间件系统已在 TypeScript、Go 和 Dart 中可用,Python 支持即将推出。

**Genkit 中间件的工作原理**

Genkit 中的每个 generate() 调用都会运行一个 工具循环:模型生成输出,请求的工具执行,结果反馈到新的模型调用中,直到模型完成为止,循环重复。中间件钩子附加在该循环的三个层级上:

| 钩子 | 运行时间 | 典型用途 | | --- | --- | --- | | Generate | 每次工具循环迭代运行一次 | 上下文注入、消息重写、对话级逻辑 | | Model | 每次模型 API 调用运行一次 | 重试、回退、缓存、延迟记录 | | Tool | 每次工具执行运行一次 | 人工介入、沙盒化、工具级日志 |

**预建中间件**

Genkit 提供了几种针对常见用例的预建中间件解决方案。以下是当前可用的内容:

**1. 重试**

当模型 API 调用因临时错误(如 RESOURCE_EXHAUSTED, UNAVAILABLE 等)失败时,使用带有抖动的指数退避自动重试。仅重试模型调用,周围的工具循环不会重新播放。

code
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

已复制

**2. 回退**

当主模型在指定的一组错误代码上失败时切换到备用模型。当主模型超出配额时,这非常有用,可以回退到完全不同的提供商。

code
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

已复制

**3. 工具审批**

将工具执行限制为允许列表。不在列表中的任何工具都会触发中断,从而在操作继续之前启用人工确认。

code
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

已复制

**4. 技能**

扫描目录中的 SKILL.md 文件,并将其内容注入系统提示中。还暴露了一个 use_skill 工具,以便模型按需加载特定技能。

code
resp, err := genkit.Generate(ctx, g,
    ai.WithPrompt("How do I deploy this service?"),
    ai.WithUse(&middleware.Skills{SkillPaths: []string{"./skills"}}),
)

Go

已复制

**5. 文件系统**

通过注入工具(如 list_files, read_file, 启用写入时的 write_fileedit_file),为模型提供对本地文件系统的范围访问权限。路径安全性得到强制执行,因此模型永远无法逃离根目录。

code
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

已复制

**构建自定义中间件**

预建中间件涵盖了常见的场景,但该系统的真正强大之处在于编写你自己的中间件。想象一下,你在构建一个代理型客户服务应用,并需要确保模型从不提及竞争对手的产品或内部定价数据。与其在每个提示中编码这些规则,你可以通过中间件确定性地强制执行它们。

所有语言中的自定义中间件都遵循一个简单的契约:提供一个名称和一个返回所需钩子的工厂函数。每次调用 generate() 时都会调用该工厂函数,而你只需实现所需的钩子即可。

以下是一个完整的自定义内容过滤器,代码量约为 20 行:

code
// ContentFilter 拒绝包含任何禁止术语的模型响应。
type ContentFilter struct {
    ForbiddenTerms []string `json:"forbiddenTerms"`
}

func (ContentFilter) Name() string { return "app/contentFilter" }
go
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

你甚至可以组合和堆叠不同的中间件解决方案。中间件堆栈从左到右执行,第一个列出的中间件是外层包装器,依此类推:

code
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 来检查、测试和调试你的应用程序,包括中间件的执行。当你注册中间件时,它会在开发人员 UI 中可见:你可以检查其配置,跟踪每个钩子层的执行,并测试不同的组合。

Video 3
Video 3

**开始使用**

我们对 Genkit 中间件为你的应用解锁的能力感到兴奋,并期待看到你为解决具体用例而构建的自定义中间件。查看 中间件文档 以深入了解,或者如果你是框架新手,可以开始使用 Genkit

有新的预构建中间件的想法吗?提交问题。我们很乐意了解什么可以改善你的开发体验!

快乐编码! 🚀

[](https://developers.googleblog.com/announcing-genkit-middleware-intercept-extend-and-harden-your-agentic-apps/) Previous

Next

[](https://developers.googleblog.com/build-long-running-ai-agents-that-pause-resume-and-never-lose-context-with-adk/)