golangAPI调用deepseek

1.deepseek官方API调用文档

1.访问格式

在这里插入图片描述
现在我们来解析这个curl

2.curl组装

// 这是请求头要加的参数
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <DeepSeek API Key>" \

// 这是请求体要加的参数
-d '{
        "model": "deepseek-chat",
        "messages": [
          {"role": "system", "content": "You are a helpful assistant."},
          {"role": "user", "content": "Hello!"}
        ],
        "stream": false
      }'

这个里面可以看出,user角色使我们要输入的问题,stream选择是否为流式响应

2.go代码

1. config 配置

type Config struct {
	BaseURL    string
	APIKey     string
	HTTPClient *http.Client
}

2.模型相关

type Model interface {
	Chat(ctx context.Context, req Request) (*Response, error)
	Stream(ctx context.Context, req Request) (<-chan Response, error)
}

type Request struct {
	Model    string    `json:"model"`
	Messages []Message `json:"messages"`
	Stream   bool      `json:"stream"`
}

type Message struct {
	Role    string `json:"role"`
	Content string `json:"content"`
}

type Response struct {
	Content string `json:"content"`
}

3.错误处理

// Error 标准错误类型
type Error struct {
	Code    int
	Message string
	Model   string
}

func (e *Error) Error() string {
	return fmt.Sprintf("[%s] %d: %s", e.Model, e.Code, e.Message)
}

4.deepseekAPI接口实现

type DeepSeek struct {
	Cfg ai.Config
}

func NewDeepSeek(cfg ai.Config) *DeepSeek {
	return &DeepSeek{Cfg: cfg}
}

func (d *DeepSeek) Stream(ctx context.Context, request ai.Request) (<-chan ai.Response, error) {
	return d.handleStreaming(ctx, request)
}

func (d *DeepSeek) Chat(ctx context.Context, request ai.Request) (*ai.Response, error) {
	doRequest, err := d.doRequest(ctx, request, false)
	if err != nil {
		return nil, err
	}
	return d.parseResponse(doRequest)
}

func (d *DeepSeek) parseResponse(resp *http.Response) (*ai.Response, error) {
	all, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, fmt.Errorf("io.ReadAll failed, err: %v\n", err)
	}
	defer resp.Body.Close()
	return &ai.Response{Content: string(all)}, nil
}

// 私有方法
func (d *DeepSeek) doRequest(ctx context.Context, req ai.Request, stream bool) (*http.Response, error) {
	req.Stream = stream
	body, _ := json.Marshal(req)

	httpReq, err := http.NewRequestWithContext(
		ctx,
		"POST",
		d.Cfg.BaseURL+"/chat/completions",
		bytes.NewReader(body),
	)
	// 设置请求头
	httpReq.Header.Set("Content-Type", "application/json")
	httpReq.Header.Set("Authorization", "Bearer "+apiKey)
	resp, err := d.Cfg.HTTPClient.Do(httpReq)
	if err != nil {
		return nil, &ai.Error{
			Model:   "deepseek",
			Code:    http.StatusInternalServerError,
			Message: fmt.Sprintf("HTTP error: %v", err),
		}
	}

	if resp.StatusCode != http.StatusOK {
		return nil, &ai.Error{
			Model:   "deepseek",
			Code:    http.StatusInternalServerError,
			Message: fmt.Sprintf("failed to request: %v", err),
		}
	}
	return resp, nil
}

func (d *DeepSeek) handleStreaming(ctx context.Context, req ai.Request) (<-chan ai.Response, error) {
	ch := make(chan ai.Response)
	go func() {
		defer close(ch)
		// 发起流式请求
		resp, err := d.doRequest(ctx, req, true)
		if err != nil {
			ch <- ai.Response{Content: "request error!"}
			return
		}
		defer resp.Body.Close()

		scanner := bufio.NewScanner(resp.Body)
		for scanner.Scan() {
			select {
			case <-ctx.Done():
				ch <- ai.Response{Content: "ctx done!"}
				return
			default:
				// 解析事件流
				event := parseEvent(scanner.Bytes())
				if event != nil {
					ch <- *event
				}
			}
		}
	}()

	return ch, nil
}

func parseEvent(line []byte) *ai.Response {
	// 处理事件流格式
	if !bytes.HasPrefix(line, []byte("data: ")) {
		return nil
	}

	payload := bytes.TrimPrefix(line, []byte("data: "))
	if string(payload) == "[DONE]" {
		return nil
	}

	// 解析响应结构
	var chunk struct {
		Choices []struct {
			Delta struct {
				Content string `json:"content"`
			}
			FinishReason string `json:"finish_reason"`
		}
	}

	if err := json.Unmarshal(payload, &chunk); err != nil {
		return nil
	}

	if len(chunk.Choices) > 0 {
		content := chunk.Choices[0].Delta.Content
		finishReason := chunk.Choices[0].FinishReason

		if content != "" {
			return &ai.Response{Content: content}
		}

		if finishReason == "stop" {
			return nil
		}
	}
	return nil
}

5. 调用使用

func main() {
	cfg := ai.Config{
		BaseURL:    "https://api.deepseek.com/",
		APIKey:     "key",
		HTTPClient: &http.Client{},
	}

	// 初始化deepseek
	d := deepseek.NewDeepSeek(cfg)

	// 封装请求体
	body := ai.Request{
		Model:    "deepseek-chat",
		Messages: []ai.Message{{Role: "system", Content: "You are a helpful assistant."}, {Role: "user", Content: "你是谁"}},
	}

	// 同步调用
	chat, err := d.Chat(context.Background(), body)
	if err != nil {
		panic(err)
	}
	fmt.Println(chat.Content)

	// 流式调用
	stream, _ := d.Stream(context.Background(), body)
	for chunk := range stream {
		fmt.Printf(chunk.Content)
	}
}

3.响应实例

// 同步
{"id":"","object":"chat.completion","created":,"model":"deepseek-chat","choices":[{"index":0,"message":{"role":"assistant","content":"您好!我是由中国的深度求索(DeepSeek)公司开发的何任何问题,我会尽我所能为您提供帮助。"},"logprobs":null,"finish_reason":"stop"}],"usage":{"prompt_tokens":10,"completion_tokens":37,"total_tokens":47,"prompt_tokens_details":{"cached_tokens":0},"prompt_cache_hit_tokens":0,"proms":10},"system_fingerprint":"fp_3a5770e1b4"}


// 流式
您好!我是由中国的深度求索(DeepSeek)公司开发的智能助手DeepSeek-V3。如您有任何任何问题,我会尽我所能为您提供帮助。

代码地址:https://gitee.com/li-zhuoxuan/go_ai

### 如何调用 DeepSeek API #### 准备工作 为了成功调用 DeepSeek API,需完成一系列准备步骤。这包括获取API密钥以及安装必要的库和工具。确保已注册并登录到DeepSeek平台以获得访问权限和API密钥[^1]。 #### HTTP 方法的选择 当通过编程方式请求数据时,选择合适的HTTP动词非常重要。对于某些操作可能需要发送带有主体内容的数据包,在这种情况下应该采用`POST`或`PUT`方法;而简单的查询通常可以使用`GET`来实现。具体取决于所使用的特定端点的要求[^2]。 #### Python 示例代码 下面是一个利用Python脚本发起对DeepSeek API GET请求的例子: ```python import requests url = 'https://api.deepseek.com/v1/endpoint' # 替换成实际的API URL headers = { 'Authorization': 'Bearer YOUR_API_KEY', # 将YOUR_API_KEY替换为真实的令牌字符串 } params = {'param1': 'value1'} # 如果有参数则在此处定义 response = requests.get(url, headers=headers, params=params) if response.status_code == 200: data = response.json() print(data) else: print(f"Error {response.status_code}: {response.text}") ``` 此段程序展示了如何构建一个基本的HTTP GET请求,并处理返回的结果。需要注意的是URL路径、头部信息中的授权字段以及任何附加的查询参数都应根据实际情况调整。 #### 完整指南与更多资源 除了上述基础介绍外,官方还提供了详细的文档和技术支持渠道供开发者深入了解各个特性和服务接口的具体应用方式。建议查阅最新的官方手册以便掌握最全面的信息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值