目录
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