使用 Genkit Go 接入 Ollama:本地模型推理、工具调用与向量嵌入完整指南
使用 Genkit Go 接入 Ollama本地模型推理、工具调用与向量嵌入完整指南【免费下载链接】genkitOpen-source framework for building agentic apps in JavaScript, Go, Dart, and Python, built and used in production by Google项目地址: https://gitcode.com/GitHub_Trending/ge/genkit本篇技术指南围绕 Genkit Go 的 Ollama 插件展开介绍如何通过统一接口接入本地或远程的 Ollama 模型服务覆盖语言模型聊天/文本生成、工具调用、思考推理、多模态视觉、文本嵌入模型的安装、配置、定义与调用并深入源码分析其模型能力探测、请求端点和思考标签解析等底层实现。读完本文你将能够在 Go 应用中完整落地本地大模型 工具 RAG 向量检索的端到端方案。插件能力概览Ollama 插件为 Genkit Go 应用提供了与 Ollama API 通信的统一接口。插件本身不绑定任何默认模型其能力完全取决于你通过ollama pull model拉取的模型支持两类能力语言模型聊天与文本生成模型支持工具调用Tools、视觉/多模态Vision以及思考/推理Thinking嵌入模型文本向量嵌入Embedding。插件底层通过三个 Ollama HTTP 端点工作聊天模型走POST /api/chat纯文本补全模型走POST /api/generate嵌入请求走POST /api/embed这一点在 ollama.go 与 embed.go 的请求构建代码中可以明确看到。安装与初始化配置安装在 Go 模块中执行go get github.com/firebase/genkit/go/plugins/ollama初始化插件插件通过genkit.WithPlugins注册到 Genkit 实例中。默认 Ollama 服务地址为http://localhost:11434import ( context github.com/firebase/genkit/go/genkit github.com/firebase/genkit/go/plugins/ollama ) func main() { ctx : context.Background() // 初始化 Ollama 插件 o : ollama.Ollama{ ServerAddress: http://localhost:11434, // RequiredOllama 服务地址 Timeout: 60, // Optional响应超时秒默认 30 } g : genkit.Init(ctx, genkit.WithPlugins(o)) }配置字段说明Ollama结构体见 ollama.go仅有两个公开配置字段字段必填默认值说明ServerAddress是无Ollama 服务地址留空会在Init时 panicTimeout否30秒模型响应的 HTTP 超时时间值为 0 时在Init中被重置为 30从源码看Init除了校验ServerAddress非空、兜底Timeout默认值外还会创建共享的 HTTP client 和能力缓存表ollama.go。插件实现genkit.Plugin接口Name()返回ollama并通过api.DynamicPlugin接口支持本地模型的动态发现详见下文底层机制。语言模型为什么需要显式定义模型因为 Ollama 模型是本地托管的且可用模型取决于用户已拉取的内容插件不会预初始化任何默认模型必须在使用前显式调用DefineModel注册。// 定义一个聊天模型例如 tinyllama o.DefineModel(g, ollama.ModelDefinition{ Name: tinyllama, Type: chat, // 交互式模型用 chat纯文本补全用 }, nil) // 之后即可按名称取用 m : ollama.Model(g, tinyllama)ModelDefinition结构体ollama.go只有Name和Type两个字段。其中Type决定走哪个 API 端点chat走/api/chat支持工具、多模态、思考走/api/generate纯文本补全。ollama.Model(g, name)本质是genkit.LookupModel未定义时返回nilollama.go。注册到 Genkit 后模型的完整 action 名为ollama/model-name。基本使用import ( context fmt log github.com/firebase/genkit/go/ai github.com/firebase/genkit/go/genkit github.com/firebase/genkit/go/plugins/ollama ) func main() { // ... 初始化 Genkit、注册 ollama 插件并定义 tinyllama ... m : ollama.Model(g, tinyllama) resp, err : genkit.Generate(ctx, g, ai.WithModel(m), ai.WithPrompt(Explain how neural networks learn in simple terms.), ) if err ! nil { log.Fatal(err) } fmt.Println(resp.Text()) }高级生成配置参数通过ollama.GenerateContentConfig可以透传 Ollama 的高级采样参数。该结构体定义在 ollama.go其中除KeepAlive外均为指针字段因此插件提供了ollama.Ptr泛型辅助函数ollama.go来便捷地初始化可选数值字段。import github.com/firebase/genkit/go/plugins/ollama resp, err : genkit.Generate(ctx, g, ai.WithModel(m), ai.WithPrompt(Write a poem about the sea.), ai.WithConfig(ollama.GenerateContentConfig{ Temperature: ollama.Ptr(0.8), // 采样温度 TopK: ollama.Ptr(40), // Top-K 采样 TopP: ollama.Ptr(0.9), // Top-P 采样核采样 NumPredict: ollama.Ptr(100), // 最大输出 token 数 KeepAlive: 5m, // 模型在内存中驻留 5 分钟 Seed: ollama.Ptr(42), // 随机种子固定复现结果 }), )各字段含义与序列化行为见 model.go 的applyGenerateContentConfig字段类型映射到 Ollama 请求说明Think*ThinkOption顶层think思考/推理模式开关见下文思考与推理Seed*intoptions.seed随机种子Temperature*float64options.temperature采样温度TopK*intoptions.top_kTop-K 采样TopP*float64options.top_pTop-P 核采样MinP*float64options.min_p最小概率过滤Stop[]stringoptions.stop停止序列NumCtx*intoptions.num_ctx上下文窗口大小NumPredict*intoptions.num_predict最大输出 token 数KeepAlivestring顶层keep_alive模型内存驻留时间GenerateContentConfig之外的配置类型也受支持见 model.go 的ApplyOptions既可以是map[string]any其中think、keep_alive被识别为顶层字段其余键进入options也可以是*ai.GenerationCommonConfig其MaxOutputTokens、StopSequences、Temperature、TopK、TopP会被自动映射见 model.go。这些行为均有 model_test.go 中的表驱动测试覆盖。工具调用Tool CallingOllama 对特定模型支持原生工具调用如llama3.1、mistral等。定义模型时Type必须为chat源码在 ollama.go 中规定仅 chat 模型才启用工具能力。// 定义一个支持工具的模型 o.DefineModel(g, ollama.ModelDefinition{ Name: llama3.1, Type: chat, }, nil) m : ollama.Model(g, llama3.1) // 定义一个工具 weatherTool : genkit.DefineTool(g, getWeather, gets the weather, func(ctx *ai.ToolContext, input *WeatherInput) (*WeatherOutput, error) { return WeatherOutput{Temp: 72}, nil }, ) resp, err : genkit.Generate(ctx, g, ai.WithModel(m), ai.WithPrompt(What is the weather in New York?), ai.WithTools(weatherTool), )完整的可运行示例见 go/samples/ollama-tools/main.go它演示了带系统消息、ai.WithToolChoice(ai.ToolChoiceAuto)自动工具选择与Temperature配置的天气查询场景。文本与工具调用并存插件支持在消息内容中同时接收文本和工具调用。当模型既返回文本又发起工具请求时两者都会被保留在消息内容中对应 ollama.go 中translateChatResponse同时追加ToolRequestPart与TextPart的逻辑。工具定义会被转换为 Ollama 的 function 格式convertToolsollama.go工具参数 schema 直接透传自 Genkit 的ToolDefinition.InputSchema。思考与推理Thinking and Reasoning插件支持具备推理能力的模型如deepseek-r1。通过Think配置开启思考模式resp, err : genkit.Generate(ctx, g, ai.WithModel(m), ai.WithPrompt(What is heavier, one kilo of steel or one kilo of feathers?), ai.WithConfig(ollama.GenerateContentConfig{ Think: ollama.ThinkEnabled(true), // 为支持的模型启用思考模式 }), ) // 模型的推理过程作为独立 part 返回 fmt.Println(Reasoning:, resp.Reasoning()) fmt.Println(Final Answer:, resp.Text())ThinkOption提供两种构造方式ollama.goollama.ThinkEnabled(bool)布尔开关用于deepseek-r1这类 Ollama 原生思考模型ollama.ThinkEffort(low|medium|high)思考强度等级用于 GPT-OSS 系列模型。ThinkOption序列化时输出为布尔值或字符串见其MarshalJSON并声明了布尔或字符串的 JSON Schemaollama.go。流式模式下的思考输出差异这是使用中容易踩坑的点非流式模式对于以think标签形式在普通文本中输出推理内容的模型而非使用 Ollama 原生的thinkingAPI 字段插件会自动解析这些标签并映射为 Genkit 的ReasoningPart。解析逻辑基于正则(?si)(think|thinking)(.*?)/(?:think|thinking)ollama.go支持大小写不敏感、跨行与多个连续的思考块对应测试见 ollama_test.go。流式模式由于 token 逐块到达的特性think标签会作为普通TextPart内容流式输出不会被解析为推理 part。对于原生支持 Ollamathinking字段的模型两种模式下都会正确流式输出ReasoningPart。另外需要注意一个防御性细节仅当显式开启Think时插件才会解析正文中的think标签避免模型在普通文本中合法输出该标签时被误判为推理内容ollama.go。多模态输入图像分析插件支持多模态模型如llava进行图像分析。图像以 data URIbase64形式传入// 定义一个多模态模型 o.DefineModel(g, ollama.ModelDefinition{ Name: llava, Type: chat, }, nil) m : ollama.Model(g, llava) // 使用内联数据base64 imagePart : ai.NewMediaPart(image/jpeg, data:image/jpeg;base64,...) resp, err : genkit.Generate(ctx, g, ai.WithModel(m), ai.WithMessages( ai.NewUserMessage( ai.NewTextPart(Describe this image), imagePart, ), ), )底层实现中concatImagesollama.go只收集 MIME 类型以image/开头的媒体 part音频输入不支持通过uri.Data提取二进制数据后 base64 编码写入 Ollama 请求的images字段convertPartsollama.go则负责把用户与模型消息中的媒体内容统一转成该格式。完整的本地图片文件读取 base64 编码 llava分析的示例见 go/samples/ollama-vision/main.go。嵌入模型Embedding Models插件支持 Ollama 上托管的文本嵌入模型如nomic-embed-text。dimensions为必填参数必须与模型的嵌入维度一致nomic-embed-text为 768。注意从源码测试embed_test.go可以确认嵌入器按模型名注册与查找而不是按服务器地址——旧代码中按 server-address 查找的用法已不适用。定义嵌入器// 定义一个嵌入模型 o.DefineEmbedder(g, nomic-embed-text, 768, nil) embedder : ollama.Embedder(g, nomic-embed-text)DefineEmbedder签名embed.go为DefineEmbedder(g, model string, dimensions int, embedOpts *ai.EmbedderOptions)。从源码可以确认的约束dimensions 0会直接 panicollama.DefineEmbedder: dimensions must be greater than 0同一模型重复注册会 panic重复注册测试见 embed_test.go元数据默认值标签为Ollama Embedding - modelSupports.Input默认[text]Dimensions为传入的维度embed_test.go 验证了默认元数据请求时EmbedOptions若未指定模型会绑定到定义时的模型名若指定了不同的模型名则报错拒绝见TestDefineEmbedderRequestOptionsHandling。使用嵌入res, err : genkit.Embed(ctx, g, ai.WithEmbedder(embedder), ai.WithTextDocs(Machine learning models process data to make predictions.), ) if err ! nil { log.Fatal(err) } fmt.Printf(Embedding length: %d\n, len(res.Embeddings[0].Embedding))底层实现embed.go会把单个文档以字符串形式、多个文档以字符串数组形式填入POST /api/embed请求的input字段并解析响应的embeddings数组返回。结合 Genkit 的检索器/向量库插件如仓库内的 localvec 与 pgvector 示例即可搭建本地 RAG 检索链路。底层机制模型能力探测与动态发现深入 ollama.go可以看到插件在能力探测方面做了一套相当完整的机制这对理解为什么某些模型自动支持工具/视觉很有帮助本地模型列表ListActions调用GET /api/tags列出本机已拉取的模型并过滤掉名称含embed的嵌入模型ollama.go。能力探测对每个模型并发调用POST /api/show并发上限maxConcurrentCapabilityQueries 4见 ollama.go从返回的capabilities推导ModelSupports包含tools则启用工具包含vision则启用媒体输入modelSupportsFromCapabilitiesollama.go。能力缓存按模型 digest 缓存探测结果——成功结果进程内长期有效失败结果仅缓存 30 秒以便重试capabilityFailureCacheLifetimenormalizeModelName会把:latest后缀归一化到同一缓存键ollama.go。相关测试如TestDynamicPlugin覆盖了缓存命中、失败重试、并发限流等场景ollama_test.go。静态兜底列表当/api/show探测不可用时插件回退到内置的toolSupportedModels含llama3.1、mistral、qwen2.5等与mediaSupportedModels含llava、bakllava、gemma3等静态列表判断能力ollama.go动态发现的模型则回退到defaultOllamaSupports工具与媒体均启用。动态插件接口ListActionsResolveAction实现了api.DynamicPlugin使得未经DefineModel注册的本地模型也可以被 Genkit 的 action 发现机制按需解析并使用——ollama.Model(g, name)在查找失败时会触发ResolveAction动态创建模型 actionollama.go。相关验证见 ollama_live_test.go 中的TestLiveDynamicDiscovery需真实 Ollama 服务通过-test-live标志开启。小结与进一步探索Genkit Go 的 Ollama 插件让本地模型的接入变得高度统一一个插件实例 一次DefineModel/DefineEmbedder注册即可获得与 Genkit 生态完全一致的生成、工具、推理、多模态与嵌入体验同时保留了按模型能力自动探测的灵活性。建议下一步阅读插件源码ollama.go、model.go、embed.go单元测试ollama_test.go、model_test.go、embed_test.go可运行示例ollama-tools、ollama-vision真实服务联调测试ollama_live_test.go。实际运行时请先确保本地已启动 Ollama 服务默认localhost:11434并完成ollama pull model否则模型定义虽能成功但生成请求会因服务不可达而报错。【免费下载链接】genkitOpen-source framework for building agentic apps in JavaScript, Go, Dart, and Python, built and used in production by Google项目地址: https://gitcode.com/GitHub_Trending/ge/genkit创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考