
Genkit Python Ollama 插件实战本地 LLM 聊天、流式生成、工具调用与向量嵌入接入指南【免费下载链接】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 官方 Python 生态中的genkit-ollama插件展开讲解如何把本地运行的 Ollama 服务接入 Genkit 应用实现聊天补全chat、流式输出streaming、工具调用tool calling、多模态视觉输入vision与文本向量嵌入embeddings等能力。读完本文你将掌握插件的安装与模型准备、Ollama()插件配置参数、OllamaConfig采样器控制、远端服务器/鉴权头/超时设置以及常见连接故障的排查方法并了解插件在源码层面的实现细节与测试验证从而能独立搭建一个完全运行在本机硬件上的 Genkit AI 应用。genkit-ollama是 Genkit 项目面向 JavaScript、Go、Dart、Python 的开源 Agent 应用框架的官方 Python 插件之一位于仓库的 py/packages/genkit-ollama 目录。它将 Ollama 的本地推理能力封装为 Genkit 标准的模型 Action 与嵌入器 Action让你可以用与云端模型完全一致的ai.generate、ai.embed等 API 来调用本地模型。一、环境准备安装插件与启动本地 Ollama 服务1.1 安装依赖在 Python 项目中使用uv添加 Genkit 核心包与 Ollama 插件uv add genkit genkit-ollama从插件元数据py/packages/genkit-ollama/pyproject.toml可以看到其依赖约束与运行前提genkitGenkit Python 核心框架ollama0.5.3,1.0Ollama 官方 Python 异步客户端SDK插件底层通过它发起 HTTP 请求structlog25.2.0结构化日志requires-python 3.10支持 Python 3.10 至 3.14插件当前版本为0.11.0License 为 Apache-2.0。1.2 安装并启动 Ollama从 ollama.com/download 安装 Ollama 后启动本地服务进程ollama serve默认情况下Ollama 监听http://127.0.0.1:11434。这个默认地址在插件源码中定义为常量DEFAULT_OLLAMA_SERVER_URL见 py/packages/genkit-ollama/src/genkit_ollama/constants.py。1.3 拉取应用所需的模型在运行 Genkit 应用之前先用ollama pull拉取要使用的模型。例如聊天模型llama3.2与嵌入模型nomic-embed-textollama pull llama3.2 ollama pull nomic-embed-text如果你计划使用视觉模型如llava或推理模型如deepseek-r1同样需要先ollama pull对应镜像。二、插件基本用法注册模型与嵌入器2.1 最小示例在 Genkit 应用中通过plugins参数注册Ollama插件并声明要使用的模型与嵌入器from genkit import Genkit from genkit_ollama import EmbeddingDefinition, ModelDefinition, Ollama ai Genkit( plugins[ Ollama( models[ModelDefinition(namellama3.2)], embedders[EmbeddingDefinition(namenomic-embed-text)], ) ], modelollama/llama3.2, ) response await ai.generate(promptWrite a haiku about local models.) print(response.text) embeddings await ai.embed(embedderollama/nomic-embed-text, contentlocal inference) print(len(embeddings[0].embedding))要点说明模型在 Genkit 中的引用名为ollama/模型名即插件名前缀ollama/加上 Ollama 模型名。源码中的ollama_name()函数负责拼接该命名空间py/packages/genkit-ollama/src/genkit_ollama/plugin_api.pyModelDefinition除name外还支持api_typechat或generate与supports工具/媒体能力声明EmbeddingDefinition支持可选的dimensions字段上述代码片段假设运行在异步上下文async def函数内中直接粘贴在模块顶层会触发SyntaxError: await outside function。2.2 完整可运行入口仓库提供了完整的可运行示例 py/samples/ollama-sample/src/main.py展示了async def main()ai.run_main(...)的标准入口写法并通过OLLAMA_CHAT_MODEL、OLLAMA_EMBEDDER_MODEL环境变量覆盖默认模型名默认为llama3.2与nomic-embed-textai Genkit( plugins[ Ollama( models[ModelDefinition(namechat_model)], embedders[EmbeddingDefinition(nameembedder_model)], server_addressos.getenv(OLLAMA_HOST), ) ], modelfollama/{chat_model}, ) async def main() - None: response await ai.generate(prompt...) print(response.text) ... if __name__ __main__: ai.run_main(main())2.3 不预配置模型按需动态发现Ollama插件也支持完全不传models/embedders模型在请求时按名称动态解析resolve。此时插件通过list_actions()调用 Ollama 的模型列表接口client.list()把本地已拉取的模型自动注册为ollama/name形式的 Action名字中包含embed的模型会被识别为嵌入器py/packages/genkit-ollama/src/genkit_ollama/plugin_api.py。需要留意的是动态发现的模型无法做能力探测因此插件为其声明完整通用能力集工具与媒体均开启源码中的_DYNAMIC_MODEL_SUPPORTS常量即为此设计并与 JS 插件的GENERIC_MODEL_INFO、Go 插件的defaultOllamaSupports保持对齐。三、流式生成Streamingai.generate_stream返回一个流式响应对象逐块读取stream中的增量文本最后通过await stream_response.response取得完整响应stream_response ai.generate_stream(promptStream a haiku about Ollama.) async for chunk in stream_response.stream: print(chunk.text, end, flushTrue) final await stream_response.response底层实现上插件根据请求上下文是否处于流式模式ctx.is_streaming决定以streamTrue调用 Ollama SDK 的client.chat/client.generate并逐个 chunk 通过ctx.send_chunk(...)转发ModelResponseChunkpy/packages/genkit-ollama/src/genkit_ollama/models.py。一个值得注意的实现细节Ollama 流式响应中 delta 的 role 常为空字符串插件在_from_ollama_role中会将其映射为Role.MODEL并对未知角色给出告警兜底py/packages/genkit-ollama/src/genkit_ollama/models.py。此外Ollama 流式模式下最终一条消息内容可能为空示例代码因此采用“拼接所有 chunk 的文本”而不是直接读取response.text。四、工具调用Tool Calling在 Genkit 中用ai.tool()定义工具然后在generate时通过tools[current_weather]传入工具名from pydantic import BaseModel, Field class WeatherInput(BaseModel): city: str Field(descriptionCity to look up) ai.tool() async def current_weather(input: WeatherInput) - str: return f{input.city} is 18°C and partly cloudy. response await ai.generate( promptWhat is the weather in London?, tools[current_weather], ) print(response.text)两个与 Ollama 强相关的行为需要特别说明这也是 README 与源码共同强调的点工具入参必须是 object schemaOllama 只支持对象类型的工具输入因此原始类型如str、int必须用 Pydantic 模型包装。源码_convert_parameters会校验 schema 的type非object类型直接抛出ValueErrorpy/packages/genkit-ollama/src/genkit_ollama/models.py。properties存在但省略type时自动推断为 object当工具 schema 声明了properties却没有显式type时插件会推断为objectschema 而不是丢弃该工具避免工具被静默忽略。工具调用结果message.tool_calls会被转换为 Genkit 的ToolRequestPart对话中的工具响应ToolResponsePart在构造 chat 消息时以字符串形式回填到消息内容中。Ollama 返回的tool角色也会被正确映射到Role.TOOL。五、JSON 结构化输出Schema 约束通过output_schema传入 Pydantic 模型即可让模型输出符合 schema 的 JSONfrom pydantic import BaseModel class Haiku(BaseModel): line_one: str line_two: str line_three: str response await ai.generate( promptWrite a haiku about local models., output_schemaHaiku, ) print(response.output)底层原理_chat_with_ollama在检测到request.output_schema或request.output_format时会把对应的 JSON Schema 原样传给 Ollama SDK 的format参数——Ollama 的 chat/generate 接口要么接受字面量json要么接受完整的 JSON Schemapy/packages/genkit-ollama/src/genkit_ollama/models.py。插件在 Dev UI 元数据中声明的输出能力为output: [text, json]、constrained: ALL。六、Ollama 专属配置OllamaConfigOllamaConfig继承自 Genkit 公共的ModelConfig并在此基础上增加了 Ollama 专属参数py/packages/genkit-ollama/src/genkit_ollama/models.py字段类型说明thinkbool \| low \| medium \| high \| None控制推理模型的思维链chain-of-thought可关闭或指定推理强度keep_alivefloat \| str \| None模型在内存中的驻留时间如1h数值单位秒减少冷启动num_ctxint \| None上下文窗口大小token 数如32_000min_pfloat \| None最小概率阈值采样参数seedint \| None随机种子用于可复现输出num_predictint \| None最多生成 token 数示例为推理模型开启思考、设定 32k 上下文窗口并让模型驻留内存一小时from genkit_ollama import OllamaConfig # Reasoning model with a 32k context window kept warm for an hour response await ai.generate( modelollama/deepseek-r1, promptPlan a small REST API., configOllamaConfig( thinkTrue, num_ctx32_000, keep_alive1h, temperature0.2, ), )源码层面有几点值得展开的实现细节extraallow透传未知采样参数OllamaConfig使用 Pydantic 的ConfigDict(alias_generatorto_camel, extraallow, populate_by_nameTrue)因此未知键如repeatPenalty等更新的采样旋钮会被原样转发到 Ollama 服务器的options无需升级 SDK 即可使用新参数。think与keep_alive是顶层请求参数它们不是采样器options的一部分build_request_options会将其从 options 中剥离而build_request_kwargs会单独把它们作为client.chat/client.generate的顶层 kwargs 传递py/packages/genkit-ollama/src/genkit_ollama/models.py。参数名归一化Genkit 的max_output_tokens映射为 Ollama 的num_predict两者同时存在时显式num_predict优先stop_sequences映射为stopversion/api_key等 Genkit 簿记字段被丢弃。所有键统一转 snake_case确保topP之类的 camelCase 旋钮不会因大小写不一致而被静默丢弃。类型强转已知旋钮先经过ollama_api.Options做类型强制转换Genkit 把max_output_tokens/top_k类型化为 float而 Ollama 要求整数再以纯 dict 返回并把Options模型暂未收录的字段如min_p合并回去确保新采样参数仍能到达服务器。思考内容解析对于把think…/think内联在正文中的模型插件通过_THINKING_RE正则与 Go 插件的thinkingRegex一致提取推理文本为独立的ReasoningPart便于 Dev UI 将思维链与最终答案分开渲染think显式开启且模型未返回专用thinking字段时该回退逻辑才会生效普通文本里的这类标签不会被误伤。七、远端服务器、鉴权头与超时7.1 指定远端服务器Ollama插件默认连接http://127.0.0.1:11434可通过server_address指向任意可达的 Ollama 实例Ollama(server_addresshttp://ollama.example.com:11434)7.2 静态请求头以字典形式传入的请求头只应用一次写入缓存的客户端Ollama(request_headers{Authorization: Bearer token})7.3 可调用请求头每次请求动态解析request_headers也可以是一个同步或异步可调用对象接收RequestHeaderParams上下文包含server_address、model/embed_request及对应的模型/嵌入请求对象返回要合并的请求头字典。它会在每一个请求上重新求值适合为短生命周期 token 自动续期from genkit_ollama import RequestHeaderParams async def auth_headers(params: RequestHeaderParams) - dict[str, str]: return {Authorization: fBearer {await mint_token(params.server_address)}} Ollama(request_headersauth_headers, timeout60.0)7.4 实现机制与注意事项从源码看py/packages/genkit-ollama/src/genkit_ollama/plugin_api.py静态头 → 事件循环级缓存的共享客户端静态或无请求头被烘焙进loop_local_client管理的每事件循环缓存客户端中跨请求复用且保持打开可调用头 → 每次请求新建客户端因为 Ollama SDK 在构造AsyncClient时就把 headers 固化没有按请求设置头的钩子所以插件为每个请求构建全新客户端并在上下文退出时关闭其内部 httpx 连接池aclose幂等若未来 SDK 移除_client内部属性插件会记录告警而不会静默泄漏连接池timeout以秒为单位的请求超时转发给底层 httpx 客户端未设置时不会传timeout参数保持 SDK 默认值。插件单元测试 py/packages/genkit-ollama/tests/plugin_api_test.py 对上述行为做了完整验证静态头复用同一客户端实例且不关闭同步/异步可调用头在每次_client_for_request时分别解析出不同 token并且每个新建客户端的连接池都被关闭头回调能正确收到 server/model/request 上下文。八、视觉模型Vision / 多模态Ollama 的视觉模型如llava需要在ModelDefinition中显式声明媒体能力媒体支持是**按模型选择加入opt-in**的以避免向 Genkit 广告模型实际上不具备的能力from genkit_ollama import ModelDefinition, Ollama, OllamaSupports Ollama(models[ModelDefinition(namellava, supportsOllamaSupports(mediaTrue))])OllamaSupports默认toolsTrue、mediaFalsepy/packages/genkit-ollama/src/genkit_ollama/models.py。模型能力元数据会按照 API 类型做门控chat端点是多轮、可使用工具与媒体generate端点是单轮纯文本multiturn/tools/media能力均为关闭见 py/packages/genkit-ollama/src/genkit_ollama/plugin_api.py 与对应测试test_create_model_action_generate_gates_capabilities。多模态输入在底层还有一个必须知道的实现细节py/packages/genkit-ollama/src/genkit_ollama/models.pyOllama Python 客户端的Image类型只接受 base64 字符串、原始字节或本地文件路径不接受 HTTP URL 或完整 data URI。因此_resolve_image需要预先处理三种情况Data URIdata:image/jpeg;base64,...剥离data:...;base64,前缀返回纯 base64HTTP/HTTPS URL用共享的缓存 httpx 客户端下载为原始字节并携带标准User-Agent头部分服务器如 Wikipedia/Wikimedia 会拒绝无 UA 的请求返回 403本地文件路径或原始 base64原样透传给Image类型处理。这是 Python 插件与 JS 插件唯一的行为差异JS 版绕过 SDK 直接构造/api/chat原始请求把图片作为images[]数组中的字符串交给 Ollama 服务端自行拉取而 Python SDK 的 Pydantic 校验更严格会直接拒绝 URL因此必须客户端先行下载。九、连接故障排查插件无法连接 Ollama 服务时抛出OllamaConnectionError异常信息中会带上它尝试连接的 URLpy/packages/genkit-ollama/src/genkit_ollama/_errors.pyCannot reach the Ollama server at http://127.0.0.1:11434. Start it with ollama serve (or set server_address to a reachable host).排查步骤确认守护进程已启动ollama serve若服务在其他主机/端口设置server_address指向可达地址确认所需模型已拉取ollama pull llama3.2等。异常包装的边界设计值得注意wrap_connection_errors只把两类“服务不可达”失败翻译为OllamaConnectionError——Ollama SDK 拦截httpx.ConnectError后抛出的内置ConnectionError以及 SDK 未拦截的超时类httpx.TransportErrorReadTimeout/PoolTimeout。而真正的服务器响应SDK 会转成ollama.ResponseError与 HTTP 状态错误不会被误标为连接错误多模态请求中图片 URL 拉取的失败也在wrap_connection_errors作用域之外不会被误报为 Ollama 服务宕机对应测试test_model_action_does_not_wrap_media_fetch_error验证了这一点。在示例程序 py/samples/ollama-sample/src/main.py 中还演示了通过GenkitError.cause检查底层是否OllamaConnectionError从而区分“Ollama 没启动”与真正的代码缺陷except GenkitError as error: if not isinstance(error.cause, OllamaConnectionError): raise print(Start Ollama and pull the sample models first: ...) raise SystemExit(1) from error十、API 类型chat与generate的选择ModelDefinition.api_type决定走 Ollama 的哪个端点py/packages/genkit-ollama/src/genkit_ollama/constants.pyOllamaAPITypes.CHAT默认走/api/chat支持多轮对话、工具调用、多模态输入适合对话与 Agent 场景OllamaAPITypes.GENERATE走/api/generate单轮、纯文本进出适合简单的补全场景。插件据此决定能力声明与底层调用路径_generate_classified按api_type分派到_chat_with_ollama或_generate_ollama_response。聊天路径会构建结构化messages含工具消息、图片而 generate 路径通过build_prompt把各轮文本简单拼接为单一 promptpy/packages/genkit-ollama/src/genkit_ollama/models.py。十一、使用 Token 用量统计插件从 Ollama 响应中提取 token 统计并回填到 Genkit 的ModelUsagepy/packages/genkit-ollama/src/genkit_ollama/models.pyprompt_eval_count作为输入 token、eval_count作为输出 tokentotal_tokens为两者之和。这为后续的成本核算、限流或 Dev UI 用量展示提供了数据基础。十二、测试覆盖与参考实现插件附带两套测试可作为理解行为的依据单元测试 py/packages/genkit-ollama/tests/plugin_api_test.py覆盖插件初始化参数传播、Action 注册与按名解析、不同api_type/supports下的能力门控、动态模型的通用能力声明、静态/可调用请求头的解析与连接池关闭、各类连接错误的包装与透传集成测试 py/packages/genkit-ollama/tests/integration_test.py验证 chat/generate 模型与 Genkit 框架的 Action 注册以及 mock 客户端下的完整生成流程。核心源码文件速览插件主入口与 Action 装配Ollama插件类、RequestHeaderParams、RequestHeaders、模型/嵌入器 Action 创建与动态发现模型实现OllamaConfig、OllamaSupports、ModelDefinition、OllamaModelchat/generate、流式、工具、媒体、思考解析嵌入器实现EmbeddingDefinition、OllamaEmbedder常量与错误类型、[py/packages/genkit-ollama/src/genkit_ollama/_errors.py)。十三、许可与数据隐私说明Ollama 本身是 MIT 许可的开源软件通过 Ollama 拉取的各个模型遵循各自的许可证生产环境使用前请查阅对应模型卡model card。默认情况下模型完全运行在你的本机硬件上数据不会离开机器——除非你把server_address指向远程 Ollama 服务。该插件源码以 Apache-2.0 许可发布见 py/packages/genkit-ollama/LICENSE版本变更记录见 py/packages/genkit-ollama/CHANGELOG.md。从隐私与成本角度看这正是本地推理插件的核心价值零云端 API 费用、无数据外泄配合 Genkit 统一的生成/嵌入 API你可以在不改变上层应用代码的前提下在本地模型与云端模型之间自由切换。【免费下载链接】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),仅供参考