章节 01
导读 / 主楼:Seedpod:统一多厂商LLM接入的Go语言客户端库
Seedpod是一个与模型厂商解耦的Go语言LLM客户端,提供统一API接入OpenAI、Anthropic、Gemini、Ollama等多个大模型服务,支持多模态消息、流式输出、推理块保留和费用估算。
正文
Seedpod是一个与模型厂商解耦的Go语言LLM客户端,提供统一API接入OpenAI、Anthropic、Gemini、Ollama等多个大模型服务,支持多模态消息、流式输出、推理块保留和费用估算。
章节 01
Seedpod是一个与模型厂商解耦的Go语言LLM客户端,提供统一API接入OpenAI、Anthropic、Gemini、Ollama等多个大模型服务,支持多模态消息、流式输出、推理块保留和费用估算。
章节 02
seedpod.Client接口,业务代码面向这个接口编写,具体的Provider实现则在运行时通过注册表解析。这种设计遵循了依赖倒置原则,使得上层应用与具体的模型服务解耦。\n\n创建客户端非常简单:\n\ngo\nclient, err := seedpod.New(\"openai\", \"sk-YOUR-KEY\",\n provider.WithModel(\"gpt-4o-mini\"),\n)\n\n\nProvider通过空白导入自动注册,这种设计借鉴了Go标准库中数据库驱动注册的模式:\n\ngo\nimport (\n _ \"github.com/teoclub/seedpod/provider/openai\"\n _ \"github.com/teoclub/seedpod/provider/anthropic\"\n _ \"github.com/teoclub/seedpod/provider/gemini\"\n _ \"github.com/teoclub/seedpod/provider/ollama\"\n)\n\n\n### 消息与内容抽象\n\nSeedpod定义了一套统一的消息模型,位于schema包中。消息类型包括System、User、Assistant和Tool消息,每种消息可以包含多个内容块。\n\n内容块支持多种形式:\n- schema.Text(\"...\"):纯文本内容\n- schema.Image(\"https://...\"):图片URL\n- schema.Image(\"data:image/png;base64,...\"):Base64编码的图片数据\n- schema.Reasoning(\"...\"):推理/思考内容\n\n这种设计使得多模态对话变得直观。例如,向模型询问图片内容:\n\ngo\nprompt := []*schema.Message{\n schema.NewUserMessage(\n schema.Text(\"请描述这张图。\"),\n schema.Image(\"https://example.com/diagram.png\"),\n ),\n}\n\n\n### 流式处理机制\n\n对于需要实时反馈的场景,Seedpod提供了流式API。client.Stream()返回一个channel,应用程序可以逐块消费模型输出:\n\ngo\nstream, err := client.Stream(ctx, prompt)\nfor chunk := range stream {\n if chunk.ReasoningDelta != \"\" {\n log.Printf(\"推理增量: %s\", chunk.ReasoningDelta)\n }\n fmt.Print(chunk.Delta)\n if chunk.Done {\n break\n }\n}\n\n\nStreamChunk结构包含了普通文本增量、推理内容增量、流结束标记和错误信息,让调用方能够完整掌控流式交互过程。\n\n## Provider实现细节\n\n### 内置Provider支持\n\nSeedpod目前内置了四个主流Provider的实现:\n\n| Provider | 默认模型 | Base URL | 特性说明 |\n|---------|---------|---------|---------|\n| OpenAI | gpt-4o-mini | api.openai.com/v1 | Chat Completions,多模态输入,SSE流式 |\n| Anthropic | claude-3-haiku | api.anthropic.com | Messages API,独立system字段,流式输出 |\n| Gemini | gemini-1.5-flash | generativelanguage.googleapis.com | 多模态、Web搜索、图片输出模态 |\n| Ollama | llama3 | localhost:11434 | 本地部署,/api/chat接口,流式支持 |\n\n### 扩展机制\n\n除了内置Provider,Seedpod允许开发者在运行时注册自定义Provider。通过seedpod.RegisterProvider()函数,可以将任何符合provider.Provider接口的实现注册到全局注册表中:\n\ngo\nfunc init() {\n seedpod.MustRegisterProvider(\"my-llm\",\n func(apiKey string, opts ...provider.Option) (provider.Provider, error) {\n return newMyClient(apiKey, opts...)\n },\n )\n}\n\n\n这种设计使得接入私有部署的模型服务或实验性的新API变得非常容易。\n\n## 高级特性\n\n### 费用估算\n\nSeedpod内置了费用计算功能。通过provider.WithCost(inputRate, outputRate)配置每百万token的美元价格,库会自动根据API返回的token使用量计算总成本:\n\ngo\nclient, err := seedpod.New(\"openai\", apiKey,\n provider.WithModel(\"gpt-4o\"),\n provider.WithCost(2.50, 10.00),\n)\n\nresp, err := client.Generate(ctx, prompt)\nfmt.Printf(\"Tokens: %d in, %d out\\n\", resp.Usage.PromptTokens, resp.Usage.CompletionTokens)\nfmt.Printf(\"Cost: $%.6f\\n\", resp.Usage.Cost)\n\n\n计算公式为:Cost = PromptTokens * InputRate / 1,000,000 + CompletionTokens * OutputRate / 1,000,000。未配置价格时,成本显示为0。\n\n### Gemini特有功能\n\n针对Google Gemini模型,Seedpod提供了一些专属选项:\n\n- Web搜索增强:provider.WithWebSearch(true)启用grounding功能,让模型可以访问最新网络信息\n- 图片生成:provider.WithResponseModalities(\"IMAGE\")请求图片输出,适用于gemini-2.5-flash-image等生成模型\n\n### 灵活的配置选项\n\nprovider包提供了一系列函数式选项,用于精细控制请求行为:\n\n- WithBaseURL(url):指向代理、自托管网关或本地服务\n- WithTemperature(value):设置采样温度,默认0.7\n- WithMaxTokens(n):设置输出token上限\n- WithHTTPClient(client):替换HTTP客户端,便于集成自定义中间件\n- WithHeader(k, v):追加自定义请求头\n\n## 命令行工具\n\nSeedpod仓库包含一个CLI工具,方便进行端到端的Provider测试:\n\n\ngo run ./examples/cli [options]\n\n\n常用参数包括:\n- -provider:指定Provider名称\n- -model:选择模型\n- -prompt:直接传入提示词\n- -prompt-file:从文件读取提示词\n- -images:逗号分隔的图片路径或URL\n- -stream:启用流式模式\n- -temperature:采样温度\n- -input-cost / -output-cost:配置价格用于费用估算\n\n这个CLI工具对于快速验证配置、测试不同模型的行为非常有用。\n\n## 实际应用场景\n\nSeedpod适合以下类型的项目:\n\n1. 多模型对比应用:需要同时测试多个厂商模型的输出质量\n2. 模型降级策略:主模型不可用时自动切换到备用Provider\n3. 混合部署架构:云端API与本地Ollama实例协同工作\n4. 成本敏感型应用:根据价格动态选择最经济的模型\n5. 多模态对话系统:需要处理图文混合输入的AI助手\n\n## 总结与展望\n\nSeedpod为Go语言开发者提供了一个简洁而强大的LLM接入方案。它的统一API设计降低了多模型开发的复杂度,同时保留了各厂商的特色功能。运行时Provider注册机制赋予了系统良好的扩展性,费用估算功能则帮助团队更好地控制AI调用成本。\n\n随着大模型生态的持续演进,像Seedpod这样的抽象层将变得越来越重要。它让开发者能够专注于业务逻辑本身,而不必被不同API的细节所困扰。对于正在构建AI应用的Go开发者来说,Seedpod值得一试。章节 03
Seedpod:统一多厂商LLM接入的Go语言客户端库\n\n背景与动机\n\n随着大语言模型生态的快速发展,开发者面临着一个日益突出的问题:不同厂商的API接口各异,从OpenAI的Chat Completions到Anthropic的Messages API,再到Google Gemini的Generative Language API,每个服务都有其独特的调用方式和返回格式。这种碎片化给多模型应用的开发和维护带来了不小的负担。\n\nSeedpod项目正是为解决这一痛点而生。它是一个用Go语言编写的轻量级LLM客户端库,核心理念是"一套API,多个厂商"——通过统一的抽象层,让业务代码能够在不同Provider之间平滑切换,而无需关心底层实现细节。\n\n项目概述\n\nSeedpod的设计目标与llmhub类似,但更加专注于Go生态。它把OpenAI、Anthropic、Gemini、Ollama以及自定义模型服务封装到同一套API后面,提供了以下核心能力:\n\n- 多模态消息支持:一次请求中可以混合文本和图片输入\n- 流式响应处理:通过Go channel消费增量内容,适合实时交互场景\n- 推理内容保留:部分模型会返回reasoning/thinking内容,Seedpod会归一化保存\n- 运行时Provider注册:支持在运行时动态注册第一方或第三方Provider\n- 费用估算功能:根据token使用量和配置的单价自动计算调用成本\n\n核心架构设计\n\n统一客户端接口\n\nSeedpod的核心是seedpod.Client接口,业务代码面向这个接口编写,具体的Provider实现则在运行时通过注册表解析。这种设计遵循了依赖倒置原则,使得上层应用与具体的模型服务解耦。\n\n创建客户端非常简单:\n\ngo\nclient, err := seedpod.New(\"openai\", \"sk-YOUR-KEY\",\n provider.WithModel(\"gpt-4o-mini\"),\n)\n\n\nProvider通过空白导入自动注册,这种设计借鉴了Go标准库中数据库驱动注册的模式:\n\ngo\nimport (\n _ \"github.com/teoclub/seedpod/provider/openai\"\n _ \"github.com/teoclub/seedpod/provider/anthropic\"\n _ \"github.com/teoclub/seedpod/provider/gemini\"\n _ \"github.com/teoclub/seedpod/provider/ollama\"\n)\n\n\n消息与内容抽象\n\nSeedpod定义了一套统一的消息模型,位于schema包中。消息类型包括System、User、Assistant和Tool消息,每种消息可以包含多个内容块。\n\n内容块支持多种形式:\n- schema.Text(\"...\"):纯文本内容\n- schema.Image(\"https://...\"):图片URL\n- schema.Image(\"data:image/png;base64,...\"):Base64编码的图片数据\n- schema.Reasoning(\"...\"):推理/思考内容\n\n这种设计使得多模态对话变得直观。例如,向模型询问图片内容:\n\ngo\nprompt := []*schema.Message{\n schema.NewUserMessage(\n schema.Text(\"请描述这张图。\"),\n schema.Image(\"https://example.com/diagram.png\"),\n ),\n}\n\n\n流式处理机制\n\n对于需要实时反馈的场景,Seedpod提供了流式API。client.Stream()返回一个channel,应用程序可以逐块消费模型输出:\n\ngo\nstream, err := client.Stream(ctx, prompt)\nfor chunk := range stream {\n if chunk.ReasoningDelta != \"\" {\n log.Printf(\"推理增量: %s\", chunk.ReasoningDelta)\n }\n fmt.Print(chunk.Delta)\n if chunk.Done {\n break\n }\n}\n\n\nStreamChunk结构包含了普通文本增量、推理内容增量、流结束标记和错误信息,让调用方能够完整掌控流式交互过程。\n\nProvider实现细节\n\n内置Provider支持\n\nSeedpod目前内置了四个主流Provider的实现:\n\n| Provider | 默认模型 | Base URL | 特性说明 |\n|---------|---------|---------|---------|\n| OpenAI | gpt-4o-mini | api.openai.com/v1 | Chat Completions,多模态输入,SSE流式 |\n| Anthropic | claude-3-haiku | api.anthropic.com | Messages API,独立system字段,流式输出 |\n| Gemini | gemini-1.5-flash | generativelanguage.googleapis.com | 多模态、Web搜索、图片输出模态 |\n| Ollama | llama3 | localhost:11434 | 本地部署,/api/chat接口,流式支持 |\n\n扩展机制\n\n除了内置Provider,Seedpod允许开发者在运行时注册自定义Provider。通过seedpod.RegisterProvider()函数,可以将任何符合provider.Provider接口的实现注册到全局注册表中:\n\ngo\nfunc init() {\n seedpod.MustRegisterProvider(\"my-llm\",\n func(apiKey string, opts ...provider.Option) (provider.Provider, error) {\n return newMyClient(apiKey, opts...)\n },\n )\n}\n\n\n这种设计使得接入私有部署的模型服务或实验性的新API变得非常容易。\n\n高级特性\n\n费用估算\n\nSeedpod内置了费用计算功能。通过provider.WithCost(inputRate, outputRate)配置每百万token的美元价格,库会自动根据API返回的token使用量计算总成本:\n\ngo\nclient, err := seedpod.New(\"openai\", apiKey,\n provider.WithModel(\"gpt-4o\"),\n provider.WithCost(2.50, 10.00),\n)\n\nresp, err := client.Generate(ctx, prompt)\nfmt.Printf(\"Tokens: %d in, %d out\\n\", resp.Usage.PromptTokens, resp.Usage.CompletionTokens)\nfmt.Printf(\"Cost: $%.6f\\n\", resp.Usage.Cost)\n\n\n计算公式为:Cost = PromptTokens * InputRate / 1,000,000 + CompletionTokens * OutputRate / 1,000,000。未配置价格时,成本显示为0。\n\nGemini特有功能\n\n针对Google Gemini模型,Seedpod提供了一些专属选项:\n\n- Web搜索增强:provider.WithWebSearch(true)启用grounding功能,让模型可以访问最新网络信息\n- 图片生成:provider.WithResponseModalities(\"IMAGE\")请求图片输出,适用于gemini-2.5-flash-image等生成模型\n\n灵活的配置选项\n\nprovider包提供了一系列函数式选项,用于精细控制请求行为:\n\n- WithBaseURL(url):指向代理、自托管网关或本地服务\n- WithTemperature(value):设置采样温度,默认0.7\n- WithMaxTokens(n):设置输出token上限\n- WithHTTPClient(client):替换HTTP客户端,便于集成自定义中间件\n- WithHeader(k, v):追加自定义请求头\n\n命令行工具\n\nSeedpod仓库包含一个CLI工具,方便进行端到端的Provider测试:\n\n\ngo run ./examples/cli [options]\n\n\n常用参数包括:\n- -provider:指定Provider名称\n- -model:选择模型\n- -prompt:直接传入提示词\n- -prompt-file:从文件读取提示词\n- -images:逗号分隔的图片路径或URL\n- -stream:启用流式模式\n- -temperature:采样温度\n- -input-cost / -output-cost:配置价格用于费用估算\n\n这个CLI工具对于快速验证配置、测试不同模型的行为非常有用。\n\n实际应用场景\n\nSeedpod适合以下类型的项目:\n\n1. 多模型对比应用:需要同时测试多个厂商模型的输出质量\n2. 模型降级策略:主模型不可用时自动切换到备用Provider\n3. 混合部署架构:云端API与本地Ollama实例协同工作\n4. 成本敏感型应用:根据价格动态选择最经济的模型\n5. 多模态对话系统:需要处理图文混合输入的AI助手\n\n总结与展望\n\nSeedpod为Go语言开发者提供了一个简洁而强大的LLM接入方案。它的统一API设计降低了多模型开发的复杂度,同时保留了各厂商的特色功能。运行时Provider注册机制赋予了系统良好的扩展性,费用估算功能则帮助团队更好地控制AI调用成本。\n\n随着大模型生态的持续演进,像Seedpod这样的抽象层将变得越来越重要。它让开发者能够专注于业务逻辑本身,而不必被不同API的细节所困扰。对于正在构建AI应用的Go开发者来说,Seedpod值得一试。