Genkit Go 1.0 实战:Google 官方 AI 框架

4 阅读3分钟

Genkit Go 1.0 实战:Google 官方 AI 框架

Google 出了个 Go 版本的 Genkit。

之前 JavaScript/TypeScript 的 Genkit 我用过,挺顺手。现在 Go 1.0 出来了,第一时间体验了一下。

今天分享我的使用感受。

Genkit 是什么

简单说,Genkit 是 Google 出的 AI 应用开发框架:

  • 模型无关:支持 OpenAI、Claude、Gemini 等
  • 工具调用:让 AI 调用你的函数
  • 流式输出:边生成边展示
  • 可观测性:内置 tracing 和监控

坦白讲,Google 出品的工具品质还是有保证的。

为什么选 Genkit

框架优点缺点
LangChain生态成熟太重,Go 支持差
llama.cpp本地部署不适合生产
GenkitGoogle 背书,Go 原生刚出 1.0,文档少

快速上手

安装

go get github.com/google/genkit/go

基础用法

package main

import (
    "context"
    "fmt"
    "log"

    "github.com/google/genkit/go/ai"
    "github.com/google/genkit/go/genkit"
)

func main() {
    // 初始化 Genkit
    g, err := genkit.New(genkit.Config{})
    if err != nil {
        log.Fatal(err)
    }

    // 定义一个 prompt
    prompt := ai.Prompt{
        Text: "用一句话解释什么是 Go 语言",
    }

    // 调用模型
    response, err := g.Generate(context.Background(), prompt)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println(response.Text)
}

工具调用

这是 Genkit 的核心功能。

定义工具

import "github.com/google/genkit/go/tools"

func main() {
    // 定义一个天气查询工具
    weatherTool := tools.DefineTool(
        "getWeather",
        "获取指定城市的天气",
        map[string]interface{}{
            "type": "object",
            "properties": map[string]interface{}{
                "city": map[string]interface{}{
                    "type":        "string",
                    "description": "城市名称",
                },
            },
            "required": []string{"city"},
        },
        func(ctx context.Context, input map[string]interface{}) (string, error) {
            city := input["city"].(string)
            // 调用天气 API
            weather, err := fetchWeather(city)
            if err != nil {
                return "", err
            }
            return fmt.Sprintf("%s 的天气是:%s", city, weather), nil
        },
    )

    // 注册工具
    g.RegisterTools(weatherTool)
}

在 prompt 里调用

// 让 AI 决定什么时候调用工具
prompt := ai.Prompt{
    Text: "北京今天天气怎么样?",
}

// AI 会自动识别需要调用 getWeather
response, _ := g.Generate(context.Background(), prompt)
fmt.Println(response.Text)
// 输出:北京的天气是:晴,温度 25°C

流式输出

// 边生成边展示
stream, err := g.GenerateStream(context.Background(), ai.Prompt{
    Text: "写一篇关于 Go 语言的文章",
})
if err != nil {
    log.Fatal(err)
}

for chunk := range stream {
    fmt.Print(chunk.Text)  // 实时打印
}

多模型支持

// 配置多个模型
g, _ := genkit.New(genkit.Config{
    Models: map[string]genkit.Model{
        "claude": ai.Claude(model="claude-3-5-sonnet"),
        "gemini": ai.Gemini(model="gemini-1.5-pro"),
        "gpt":    ai.OpenAI(model="gpt-4"),
    },
})

// 按需切换
response1, _ := g.Generate(context.Background(), prompt,
    genkit.WithModel("claude"))

response2, _ := g.Generate(context.Background(), prompt,
    genkit.WithModel("gemini"))

实际项目结构

package main

import (
    "github.com/google/genkit/go/ai"
    "github.com/google/genkit/go/genkit"
    "github.com/google/genkit/go/tools"
)

// 定义工具
var searchTool = tools.DefineTool(...)
var calculatorTool = tools.DefineTool(...)

// 定义 Agent
func createAgent(g *genkit.Genkit) *ai.Agent {
    return ai.DefineAgent(
        g,
        "data-analyst",
        "数据分析 Agent",
        []ai.Tool{searchTool, calculatorTool},
        ai.AgentPrompt{
            Text: `你是一个专业的数据分析师。
用户会给你数据问题,你会:
1. 先理解问题
2. 决定是否需要搜索信息
3. 进行必要计算
4. 给出分析结果`,
        },
    )
}

func main() {
    g, _ := genkit.New(genkit.Config{})
    
    // 注册工具
    g.RegisterTools(searchTool, calculatorTool)
    
    // 创建 Agent
    agent := createAgent(g)
    
    // 运行
    result, _ := agent.Run(context.Background(), "分析这周的销售额趋势")
    fmt.Println(result)
}

可观测性

Genkit 内置了 tracing:

g, _ := genkit.New(genkit.Config{
    Telemetry: genkit.TelemetryConfig{
        Trace: true,
        Metrics: true,
    },
})

// 所有调用都会自动 tracing
response, _ := g.Generate(ctx, prompt)
// 可以到 http://localhost:4000 查看 trace

踩坑记录

坑 1:工具定义要规范

// ❌ 错误定义
tool := tools.DefineTool("getData", "获取数据", nil, handler)

// ✅ 正确格式
tool := tools.DefineTool(
    "getData",
    "获取指定日期范围的数据",
    map[string]interface{}{
        "type": "object",
        "properties": map[string]interface{}{
            "start": map[string]interface{}{"type": "string"},
            "end":   map[string]interface{}{"type": "string"},
        },
    },
    handler,
)

坑 2:Handler 返回类型

// ❌ 返回 map
func handler(ctx context.Context, input map[string]interface{}) (map[string]interface{}, error) {
    return map[string]interface{}{"result": "ok"}, nil
}

// ✅ 返回 string
func handler(ctx context.Context, input map[string]interface{}) (string, error) {
    return `{"result": "ok"}`, nil
}

适用场景

适合用 Genkit

  • 需要 AI 调用外部工具的应用
  • 多模型切换的场景
  • 需要可观测性的生产项目

不适合

  • 简单的单次调用(直接调 API 更省事)
  • 需要精细控制的项目(Genkit 抽象太多)
  • 资源极度敏感的场景(有一定开销)

总结

Genkit Go 1.0 是个有潜力的框架。

优点

  • Google 背书,品质有保证
  • Go 原生,用着顺手
  • 工具调用设计合理
  • 内置 tracing

缺点

  • 刚出 1.0,文档少
  • 社区生态还在建设中
  • 有些场景下有点重

我的判断:值得跟进,但生产使用前建议先跑通 demo。