这边我选择deepseek练手
- 分析上面的图
- 这是一个post请求
- model: 是请求的哪个模型
- message: 就是请求的内容,包含
角色 以及 角色说的话术- system:是一个大的背景介绍(前提),比如 你是一个前端专家
- user:用户
- assistant: 大模型
- 如果需要记住前面的内容,就需要把大模型上次说的也传入message(费token)
- stream: 是否开启流式,非流式就是一次性给你
- 请求的 url
https://api.deepseek.com/chat/completions - 还需要携带2个请求头,
DEEPSEEK_API_KEY就是我们第一张图的apikey
-
注意:
- message中记录的越多(请求体)就越费钱
- 大模型返回的数据越多也越费钱
- 如果不想大模型返回过多,调用模型时候可以控制参数,比如
温度- 温度越低大模型就更加冷静更加聚焦,返回的内容更少也更精准
- 也可以限制
MaxToken,每次返回的token的个数上线
-
例子1如下:
package main
import (
"bytes"
"fmt"
"io"
"log"
"net/http"
"os"
"time"
"agent/config"
"github.com/bytedance/sonic"
)
const DeepseekUrl = "https://api.deepseek.com/chat/completions" // API地址
// 定义message结构体
type Message struct {
Role string `json:"role"` // 角色"system", "user", "assistant"
Content string `json:"content"` // 内容
}
// 定义请求体结构体
type RequestBody struct {
Model string `json:"model"` // 模型名称
Messages []*Message `json:"messages"` // 消息列表
Stream bool `json:"stream"` // 是否流式返回
}
func chatWithDeepseek(rb *RequestBody) {
bs, err := sonic.Marshal(rb) // 转成json
if err != nil {
log.Printf("json序列化失败: %s", err)
return
}
// 发送请求 bytes.NewReader(bs) 是请求体
rq, _ := http.NewRequest(http.MethodPost, DeepseekUrl, bytes.NewReader(bs))
// 添加请求头
rq.Header.Add("Content-Type", "application/json")
// 添加授权(鉴权)
rq.Header.Add("Authorization", fmt.Sprintf("Bearer %s", config.APIKEY)) // 这里的key不做展示了
client := http.Client{
Timeout: 30 * time.Second, // 设置超时时间
} // 创建http客户端
resp, err := client.Do(rq) // 发送请求
if err != nil {
log.Printf("请求失败: %s", err)
return
}
defer resp.Body.Close() // 关闭连接
if resp.StatusCode != http.StatusOK {
// 状态码不为200,则请求失败
_, _ = io.Copy(os.Stdout, resp.Body) // 打印返回内容
return
}
// 请求成功,读取返回内容
bs, _ = io.ReadAll(resp.Body) //读取返回内容
fmt.Println(string(bs))
}
func main() {
rb := &RequestBody{
Model: "deepseek-chat",
Messages: []*Message{
{
Role: "system",
Content: "",
},
{
Role: "user",
Content: "离五一放假还有几天?",
// 再加上后面这段 "今天是2026年3月3号,离五一放假还有几天?"
},
},
Stream: false, // 是否流式返回
}
chatWithDeepseek(rb)
}
-
返回结果如下
-
给出了日期的准了
- 当大模型提示不准的时候,就需要人去给它更多限定条件,使它精准
- prompt工程师(简称ai铲屎官)
-
你会发现这一堆返回有点杂,我们需要去提取我们要的信息
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"log"
"net/http"
"os"
"time"
"agent/config"
"github.com/bytedance/sonic"
)
const DeepseekUrl = "https://api.deepseek.com/chat/completions" // API地址
// 定义message结构体
type Message struct {
Role string `json:"role"` // 角色"system", "user", "assistant"
Content string `json:"content"` // 内容
}
// 定义请求体结构体
type RequestBody struct {
Model string `json:"model"` // 模型名称
Messages []*Message `json:"messages"` // 消息列表
Stream bool `json:"stream"` // 是否流式返回
}
type Choice struct {
Index int `json:"index"`
Message *Message `json:"message"`
}
type ResponseBody struct {
Choices []*Choice `json:"choices"` // 响应结果
}
func chatWithDeepseek(rb *RequestBody) {
bs, err := sonic.Marshal(rb) // 转成json
if err != nil {
log.Printf("json序列化失败: %s", err)
return
}
// 发送请求 bytes.NewReader(bs) 是请求体
rq, _ := http.NewRequest(http.MethodPost, DeepseekUrl, bytes.NewReader(bs))
// 添加请求头
rq.Header.Add("Content-Type", "application/json")
// 添加授权(鉴权)
rq.Header.Add("Authorization", fmt.Sprintf("Bearer %s", config.APIKEY)) // 这里的key不做展示了
client := http.Client{
Timeout: 30 * time.Second, // 设置超时时间
} // 创建http客户端
resp, err := client.Do(rq) // 发送请求
if err != nil {
log.Printf("请求失败: %s", err)
return
}
defer resp.Body.Close() // 关闭连接
if resp.StatusCode != http.StatusOK {
// 状态码不为200,则请求失败
_, _ = io.Copy(os.Stdout, resp.Body) // 打印返回内容
return
}
// 请求成功,读取返回内容
bs, _ = io.ReadAll(resp.Body) //读取返回内容
// fmt.Println(string(bs))
var respBody ResponseBody
err = json.Unmarshal(bs, &respBody)
if err == nil {
for k, v := range respBody.Choices {
fmt.Println(k, v.Message.Content) // 打印内容
}
}else {
fmt.Println(string(bs))
}
}
func main() {
rb := &RequestBody{
Model: "deepseek-chat",
Messages: []*Message{
{
Role: "system",
Content: "",
},
{
Role: "user",
Content: "今天是2026年3月3号,离五一放假还有几天?",
},
},
Stream: false, // 是否流式返回
}
chatWithDeepseek(rb)
}
把请求改为流式
- 流式不处理的就是这样的
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"log"
"net/http"
"os"
"time"
"agent/config"
"github.com/bytedance/sonic"
)
const DeepseekUrl = "https://api.deepseek.com/chat/completions" // API地址
// 定义message结构体
type Message struct {
Role string `json:"role"` // 角色"system", "user", "assistant"
Content string `json:"content"` // 内容
}
// 定义请求体结构体
type RequestBody struct {
Model string `json:"model"` // 模型名称
Messages []*Message `json:"messages"` // 消息列表
Stream bool `json:"stream"` // 是否流式返回
}
type Choice struct {
Index int `json:"index"`
Message *Message `json:"message"`
}
// 流式返回结果结构体
type StreamChoice struct {
Index int `json:"index"`
Message *Message `json:"delta"`
}
type ResponseBody struct {
Choices []*Choice `json:"choices"` // 响应结果
}
type StreamResponseBody struct {
Choices []*StreamChoice `json:"choices"` // 响应结果
}
func chatWithDeepseek(rb *RequestBody) {
bs, err := sonic.Marshal(rb) // 转成json
if err != nil {
log.Printf("json序列化失败: %s", err)
return
}
// 发送请求 bytes.NewReader(bs) 是请求体
rq, _ := http.NewRequest(http.MethodPost, DeepseekUrl, bytes.NewReader(bs))
// 添加请求头
rq.Header.Add("Content-Type", "application/json")
// 添加授权(鉴权)
rq.Header.Add("Authorization", fmt.Sprintf("Bearer %s", config.APIKEY)) // 这里的key不做展示了
client := http.Client{
Timeout: 30 * time.Second, // 设置超时时间
} // 创建http客户端
resp, err := client.Do(rq) // 发送请求
if err != nil {
log.Printf("请求失败: %s", err)
return
}
defer resp.Body.Close() // 关闭连接
if resp.StatusCode != http.StatusOK {
// 状态码不为200,则请求失败
_, _ = io.Copy(os.Stdout, resp.Body) // 打印返回内容
return
}
// 非流式返回
// 请求成功,读取返回内容
// bs, _ = io.ReadAll(resp.Body) //读取返回内容
// fmt.Println(string(bs))
// var respBody ResponseBody
// err = json.Unmarshal(bs, &respBody)
// if err == nil {
// for k, v := range respBody.Choices {
// fmt.Println(k, v.Message.Content) // 打印内容
// }
// }
// 读取流式数据
buffer := make([]byte, 1024*2) // 设置缓冲区大小2k
for {
n, err := resp.Body.Read(buffer)
if err == io.EOF {
break
}
if err != nil {
log.Printf("读取数据失败: %s", err)
return
}
// fmt.Println(string(buffer[:n]))
for _, segment := range bytes.Split(buffer[:n], []byte("data: ")) {
// 去掉空行
segment = bytes.TrimSpace(segment)
if len(segment) == 0 {
continue
}
// [DONE] 说明流式数据结束 一定要处理
if string(segment) == "[DONE]" {
break
}
// 进行json反序列化
var streamResponse StreamResponseBody
err := json.Unmarshal(segment, &streamResponse)
if err == nil {
fmt.Print(streamResponse.Choices[0].Message.Content) // 打印内容
} else {
log.Printf("json反序列化失败: %s", err)
break
}
}
}
}
func main() {
rb := &RequestBody{
Model: "deepseek-chat",
Messages: []*Message{
{
Role: "system",
Content: "",
},
{
Role: "user",
Content: "今天是2026年3月3号,离五一放假还有几天?",
},
},
// Stream: false, // 否流式返回
Stream: true, // 流式返回
}
chatWithDeepseek(rb)
}
- 结果如下