@googledevs:构建智能体应用很简单,但让它们达到生产就绪状态却很难。推出 Genkit Middleware:一种可组合的方式……
摘要
Google 发布 Genkit Middleware,这是一个用于 Genkit 开源框架的可组合中间件系统,可为智能体应用添加重试、回退、人工审核和全链路可观测性。现已支持 TypeScript、Go 和 Dart,Python 支持即将推出。
查看缓存全文
缓存时间: 2026/05/15 07:00
构建智能体应用很容易。但让它们达到生产就绪状态却很难。🛠️
现正式推出 Genkit 中间件:一种可组合的方式,用于拦截、扩展和加固你的智能体应用。
✅ 重试与回退 ✅ 人工审批 ✅ 全栈可观测性
现已支持 TypeScript、Go,
正式推出 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 通过中间件解决了这些问题:可组合的钩子(hook)拦截生成调用(包括工具执行循环),并注入自定义行为。中间件系统现已支持 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/) 来检查、测试和调试你的应用,包括中间件执行。注册中间件后,它会在开发者 UI 中可见:你可以检查其配置、追踪每个钩子层的执行过程,并测试不同的组合。
抱歉,您的浏览器不支持此视频的播放。
开始使用
我们对 Genkit 中间件为您应用解锁的能力感到兴奋,并期待看到您为解决自身用例而构建的自定义中间件。查阅中间件文档 (https://genkit.dev/docs/go/middleware/) 以深入了解,或者如果您是新手,可以开始使用 Genkit (https://genkit.dev/docs/go/get-started/)。
对新的预构建中间件有想法?请提交 issue (https://github.com/genkit-ai/genkit/issues)。我们很想听听哪些能改善您的开发体验!
快乐编码!🚀
相似文章
Genkit 中间件(10分钟阅读)
Google 宣布 Genkit 中间件,这是一种可组合的钩子,可拦截 AI 生成调用,实现重试、回退、工具审批和技能,用于构建可靠的智能代理应用。
@googledevs: 构建自主的、全栈 AI 应用从未如此简单!宣布 Genkit Agents API(TS 和 Go 预览版)。Sa…
Google 宣布了适用于 TypeScript 和 Go 的 Genkit Agents API(预览版),这是一个开源框架,通过处理消息历史、流式传输、工具循环和持久化,简化了构建全栈对话式 AI 应用的过程。
@googledevs:使用 @golang 构建生产级的多代理应用 Go 2.0 的 Agent Development Kit 运行单个代理…
Google 宣布推出 Go 2.0 的代理开发套件(ADK),引入了基于图的工作流引擎、人在回路(human-in-the-loop)原语以及动态编排,用于构建生产级的多代理应用程序。
@googledevs:让代理的上下文保持精简,同时不牺牲专业知识。了解 Genkit Go 中的 Agent Skills 如何将专业化知识打包为…
Google 的博客文章介绍了 Genkit for Go 中对 Agent Skills 的支持,展示了渐进式披露如何让代理按需加载专业知识,从而减少 token 使用量并提高可靠性。
@akshay_pachaar: Karpathy的Agentic Engineering终于有了合适的工具!(由谷歌打造)Karpathy将Agentic Engineering定义为……
谷歌推出了Agents CLI,这是一个统一的命令行工具,集成了在Google Cloud上对代理进行搭建、评估和部署的功能,使编码助手能够在不切换上下文的情况下实践Agentic Engineering。