使用 gone.WrapFunctionProvider 快速接入第三方服务(下)—— LLM接入支持 openAI 和 deepseek

文字例子源代码:

1.goner/deepseek

2.goner/openai

  • [使用 gone.WrapFunctionProvider 快速接入第三方服务------ LLM接入支持 openAI 和 deepseek](#使用 gone.WrapFunctionProvider 快速接入第三方服务—— LLM接入支持 openAI 和 deepseek "#%E4%BD%BF%E7%94%A8-gonewrapfunctionprovider-%E5%BF%AB%E9%80%9F%E6%8E%A5%E5%85%A5%E7%AC%AC%E4%B8%89%E6%96%B9%E6%9C%8D%E5%8A%A1-llm%E6%8E%A5%E5%85%A5%E6%94%AF%E6%8C%81-openai-%E5%92%8C-deepseek")
    • [1. gone.WrapFunctionProvider 简介](#1. gone.WrapFunctionProvider 简介 "#1-gonewrapfunctionprovider-%E7%AE%80%E4%BB%8B")
    • [2. 配置注入实现](#2. 配置注入实现 "#2-%E9%85%8D%E7%BD%AE%E6%B3%A8%E5%85%A5%E5%AE%9E%E7%8E%B0")
    • [3. 实战示例:OpenAI 和 Deepseek 集成](#3. 实战示例:OpenAI 和 Deepseek 集成 "#3-%E5%AE%9E%E6%88%98%E7%A4%BA%E4%BE%8Bopenai-%E5%92%8C-deepseek-%E9%9B%86%E6%88%90")
      • [3.1 Deepseek 集成](#3.1 Deepseek 集成 "#31-deepseek-%E9%9B%86%E6%88%90")
      • [3.2 OpenAI 集成](#3.2 OpenAI 集成 "#32-openai-%E9%9B%86%E6%88%90")
    • [4. 配置示例](#4. 配置示例 "#4-%E9%85%8D%E7%BD%AE%E7%A4%BA%E4%BE%8B")
      • [4.1 Deepseek 配置](#4.1 Deepseek 配置 "#41-deepseek-%E9%85%8D%E7%BD%AE")
      • [4.2 OpenAI 配置](#4.2 OpenAI 配置 "#42-openai-%E9%85%8D%E7%BD%AE")
      • [4.3 多客户端配置](#4.3 多客户端配置 "#43-%E5%A4%9A%E5%AE%A2%E6%88%B7%E7%AB%AF%E9%85%8D%E7%BD%AE")
    • [5. 使用方式](#5. 使用方式 "#5-%E4%BD%BF%E7%94%A8%E6%96%B9%E5%BC%8F")
      • [5.1 基本使用](#5.1 基本使用 "#51-%E5%9F%BA%E6%9C%AC%E4%BD%BF%E7%94%A8")
      • [5.2 多客户端使用](#5.2 多客户端使用 "#52-%E5%A4%9A%E5%AE%A2%E6%88%B7%E7%AB%AF%E4%BD%BF%E7%94%A8")
    • [6. 最佳实践](#6. 最佳实践 "#6-%E6%9C%80%E4%BD%B3%E5%AE%9E%E8%B7%B5")
      • [6.1 配置分离](#6.1 配置分离 "#61-%E9%85%8D%E7%BD%AE%E5%88%86%E7%A6%BB")
      • [6.2 单例管理](#6.2 单例管理 "#62-%E5%8D%95%E4%BE%8B%E7%AE%A1%E7%90%86")
      • [6.3 错误处理](#6.3 错误处理 "#63-%E9%94%99%E8%AF%AF%E5%A4%84%E7%90%86")
      • [6.4 代理配置](#6.4 代理配置 "#64-%E4%BB%A3%E7%90%86%E9%85%8D%E7%BD%AE")
    • [7. 总结](#7. 总结 "#7-%E6%80%BB%E7%BB%93")

本文将介绍如何使用 gone.WrapFunctionProvider 和配置注入来快速接入大型语言模型(LLM)服务,包括 OpenAI 和 Deepseek。我们将详细说明这种方式的实现原理和最佳实践。

1. gone.WrapFunctionProvider 简介

Gone 框架提供了 gone.WrapFunctionProvider 这个强大的工具函数,它可以将一个普通的函数包装成 Provider。这种方式特别适合于:

  • 需要注入配置的场景
  • 需要创建单例的场景
  • 需要延迟初始化的场景
  • 需要错误处理的场景

对于 LLM 服务集成,这些特性尤其重要,因为我们通常需要管理 API 密钥、自定义基础 URL、设置超时和代理等配置。

2. 配置注入实现

在 Gone 框架中,配置注入是通过结构体标签(struct tag)实现的。以 Deepseek 为例:

go 复制代码
param struct {
    config deepseek.Config `gone:"config,deepseek"`
}

这里的 gone:"config,deepseek" 标签表示:

  • config 表示这是一个配置项
  • deepseek 是配置的命名空间

3. 实战示例:OpenAI 和 Deepseek 集成

3.1 Deepseek 集成

让我们看一个完整的示例,展示如何使用 gone.WrapFunctionProvider 来集成 Deepseek:

go 复制代码
func Load(loader gone.Loader) error {
    var load = gone.OnceLoad(func(loader gone.Loader) error {
        var single *deepseek.Client

        getSingleDeepseek := func(
            tagConf string,
            param struct {
                config Config `gone:"config,deepseek"`
                doer   g.HTTPDoer `gone:"*,optional"`
            },
        ) (*deepseek.Client, error) {
            var err error
            if single == nil {
                options := param.config.ToDeepseekOptions(param.doer)
                single, err = deepseek.NewClientWithOptions(param.config.AuthToken, options...)
                if err != nil {
                    return nil, gone.ToError(err)
                }
            }
            return single, nil
        }
        provider := gone.WrapFunctionProvider(getSingleDeepseek)
        return loader.Load(provider)
    })
    return load(loader)
}

3.2 OpenAI 集成

类似地,OpenAI 的集成也可以使用相同的模式:

go 复制代码
func Load(loader gone.Loader) error {
    var load = gone.OnceLoad(func(loader gone.Loader) error {
        var single *openai.Client

        getSingleOpenAI := func(
            tagConf string,
            param struct {
                config Config `gone:"config,openai"`
                doer   g.HTTPDoer `gone:"*,optional"`
            },
        ) (*openai.Client, error) {
            var err error
            if single == nil {
                options := param.config.ToOpenAIOptions(param.doer)
                single, err = openai.NewClientWithOptions(param.config.AuthToken, options...)
                if err != nil {
                    return nil, gone.ToError(err)
                }
            }
            return single, nil
        }
        provider := gone.WrapFunctionProvider(getSingleOpenAI)
        return loader.Load(provider)
    })
    return load(loader)
}

这些代码实现了以下功能:

  1. 单例模式 :通过闭包变量 single 确保只创建一个客户端实例
  2. 配置注入:通过结构体标签自动注入 LLM 服务配置
  3. 错误处理 :使用 gone.ToError 统一错误处理
  4. HTTP 客户端注入:支持可选的 HTTP 客户端注入,便于自定义网络行为

4. 配置示例

4.1 Deepseek 配置

在项目的配置目录中创建 default.yaml 文件,添加以下 Deepseek 配置:

yaml 复制代码
deepseek:
  authToken: "your-api-key"      # 你的 Deepseek API 密钥
  baseURL: ""                    # 可选:自定义 API 基础 URL
  timeout: 0                     # 可选:请求超时时间(秒)
  path: ""                       # 可选:API 路径(默认为 "chat/completions")
  proxyUrl: ""                   # 可选:HTTP 代理 URL

4.2 OpenAI 配置

类似地,OpenAI 的配置可以如下:

yaml 复制代码
openai:
  authToken: "your-api-key"      # 你的 OpenAI API 密钥
  baseURL: ""                    # 可选:自定义 API 基础 URL
  timeout: 0                     # 可选:请求超时时间(秒)
  proxyUrl: ""                   # 可选:HTTP 代理 URL

4.3 多客户端配置

对于需要连接多个不同服务提供商的场景,可以使用不同的命名空间:

yaml 复制代码
deepseek:
  authToken: "default-deepseek-key"

openai:
  authToken: "default-openai-key"

baidu:
  authToken: "baidu-api-key"
  baseURL: "https://custom.baidu.api.com"

aliyun:
  authToken: "aliyun-api-key"
  baseURL: "https://custom.aliyun.api.com"

5. 使用方式

5.1 基本使用

在应用中使用这些 Provider 非常简单:

go 复制代码
type llmUser struct {
    gone.Flag
    deepseekClient *deepseek.Client `gone:"*"`
    openaiClient   *openai.Client   `gone:"*"`
}

func (s *llmUser) Use() {
    // 使用 Deepseek 客户端
    deepseekResp, err := s.deepseekClient.CreateChatCompletion(
        context.Background(),
        deepseek.ChatCompletionRequest{
            Model: "deepseek-chat",
            Messages: []deepseek.ChatCompletionMessage{
                {
                    Role:    "user",
                    Content: "你好!",
                },
            },
        },
    )
    
    // 使用 OpenAI 客户端
    openaiResp, err := s.openaiClient.CreateChatCompletion(
        context.Background(),
        openai.ChatCompletionRequest{
            Model: "gpt-3.5-turbo",
            Messages: []openai.ChatCompletionMessage{
                {
                    Role:    "user",
                    Content: "Hello!",
                },
            },
        },
    )
    // ...
}

5.2 多客户端使用

对于需要使用多个不同配置的客户端的场景:

go 复制代码
type multiLLMUser struct {
    gone.Flag
    // Deepseek 客户端
    defaultDeepseek *deepseek.Client `gone:"*"`           
    baiduDeepseek   *deepseek.Client `gone:"*,baidu"`    
    
    // OpenAI 客户端
    defaultOpenAI   *openai.Client   `gone:"*"`           
    aliyunOpenAI    *openai.Client   `gone:"*,aliyun"`   
}

func main() {
    gone.NewApp(
        goneDeepseek.Load,
        goneOpenAi.Load,
    ).Run(func(u *multiLLMUser) {
        // 使用不同的客户端...
    })
}

6. 最佳实践

6.1 配置分离

  • 将配置放在独立的配置文件中
  • 使用命名空间避免配置冲突
  • 敏感信息如 API 密钥应通过环境变量注入

6.2 单例管理

  • 对于 LLM 客户端,始终使用单例模式以避免资源浪费
  • 使用 gone.OnceLoad 确保安全的单例初始化

6.3 错误处理

  • 使用 gone.ToError 包装错误
  • 在初始化时进行充分的错误检查
  • 对 API 调用进行适当的重试和超时处理

6.4 代理配置

对于网络受限环境,合理配置代理是必要的:

yaml 复制代码
deepseek:
  authToken: "your-api-key"
  proxyUrl: "http://username:[email protected]:8080"

7. 总结

使用 gone.WrapFunctionProvider 和配置注入是一种优雅且高效的 LLM 服务接入方式。它具有以下优势:

  • 代码简洁,易于维护
  • 配置灵活,支持动态注入
  • 资源管理合理,支持单例模式
  • 错误处理统一,便于排查问题
  • 支持多种 LLM 服务提供商

通过这种方式,我们可以快速且规范地集成 OpenAI、Deepseek 等各种 LLM 服务,提高开发效率,同时保持代码的可维护性和可扩展性。无论是构建聊天机器人、内容生成工具还是其他 AI 驱动的应用,这种集成方式都能提供稳定可靠的基础设施支持。

相关推荐
天天扭码15 分钟前
不需要编写代码——借助Cursor零基础爬取微博热榜(含Cursor伪免费使用教程)
前端·openai·cursor
江湖十年39 分钟前
go-multierror: 更方便的处理你的错误列表
后端·面试·go
kuaile09067 小时前
DeepSeek 与开源:肥沃土壤孕育 AI 硕果
人工智能·ai·gitee·开源·deepseek
—Qeyser8 小时前
用 Deepseek 写的uniapp血型遗传查询工具
前端·javascript·ai·chatgpt·uni-app·deepseek
Pandaconda16 小时前
【新人系列】Golang 入门(十三):结构体 - 下
后端·golang·go·方法·结构体·后端开发·值传递
win4r16 小时前
🚀多维度测评OpenAI最新GPT-4.1模型!百万token上下文窗口!编程能力和指令遵循能力大幅提升!Cline+GPT-4.1十分钟零代码开发macOS
chatgpt·openai·ai编程
that's boy16 小时前
字节跳动开源 LangManus:不止是 Manus 平替,更是下一代 AI 自动化引擎
运维·人工智能·gpt·自动化·midjourney·gpt-4o·deepseek
仙人掌_lz16 小时前
详解如何复现DeepSeek R1:从零开始利用Python构建
开发语言·python·ai·llm·deepseek
mzak17 小时前
鲲鹏+昇腾部署集群管理软件GPUStack,两台服务器搭建双节点集群【实战详细踩坑篇】
qwen·鲲鹏·昇腾·deepseek·gpustack
新智元18 小时前
永别了,GPT-4!
人工智能·openai