本文使用的是langchaingo包对deepseek的api进行调用,而不是deepseek官方给的调用方法。
文章偏向于应用实现,步骤细致,尤其适合小白查看。
在开始调用之前,我们需要先简单了解一下langchaingo。
langchaingo是什么
langchaingo 是 go 语言的一个库,属于 LangChain 生态系统的一部分,帮助开发者轻松与大型语言模型(LLM)交互,如 DeepSeek 和 GPT-4。它抽象了与不同 LLM API 的复杂性,使开发者能专注于构建应用。
简单来说,我们需要通过langchaingo来调用deepseek的api接口,通过该接口来实现与AI的互动。
接下了我们直接开始调用。
获取API key
在调用之前,我们需要申请一个API key。
API key(应用程序接口密钥)是一个唯一的字符串标识符,通常由服务提供商(如 DeepSeek、OpenAI 等)生成,用于验证和授权对 API 的访问。
首先在 https://platform.deepseek.com/ 中申请一个自己的 API key
现在我们已经申请到了自己的API key,但现在是无法使用这个key的,因为余额为0,我们需要给账户充值一下,才能用这个key。
充值完成后就可以正常使用了,可以看到每次使用该key调用api都会耗费一些余额。
这里补充一点(小白可以跳过):我们每次与大模型进行交互时,会消耗 token。在这里 token 是模型用来表示自然语言文本的的最小单位,可以是一个词、一个数字或一个标点符号等。deepseek官方是根据模型输入和输出的总 token 数进行计量计费的。
基础调用
打开你的goland,下载下方依赖
go get “github.com/tmc/langchaingo/llms”
go get “github.com/tmc/langchaingo/llms/openai”
第一步:初始化deepseek大模型:
注:通常用llm表示各种大模型,本文后续将直接使用llm来指代deepseek大模型。
package main
import (
"github.com/tmc/langchaingo/llms/openai"
)
func main() {
// 初始化大模型
llm, err := openai.New(
openai.WithModel("deepseek-reasoner"),
openai.WithToken("API key"),
openai.WithBaseURL("https://api.deepseek.com"),
)
}
其中的各个参数解释如下:
openai.WithModel():指定你要调用deepseek中的哪个模型,我们可以填入 ‘deepseek-chat’ (对应DeepSeek-V3)或 deepseek-reasoner(对应DeepSeek-R1)。
openai.WithToken():指定你的API key,我们把刚刚申请到的key填入即可。
openai.WithBaseURL():指定DeepSeek API 服务的基础地址,我们填入"https://api.deepseek.com" 即可。
看到这里可能有的同学要问了:“你调用的不是deepseek嘛,怎么这配的参数全是openAI的??”
这里官方给的答复是:DeepSeek API 使用与 OpenAI 兼容的 API 格式,通过修改配置,您可以使用 OpenAI SDK 来访问 DeepSeek API。
第二步:通过大模型llm调用API来生成答复:
package main
import (
"context"
"fmt"
"log"
"github.com/tmc/langchaingo/llms"
"github.com/tmc/langchaingo/llms/openai"
)
func main() {
// 第一步:初始化大模型llm
llm, err := openai.New(
openai.WithModel("deepseek-reasoner"),
openai.WithToken("API key"),
openai.WithBaseURL("https://api.deepseek.com"),
)
if err != nil {
log.Fatal("初始化失败:", err)
}
// 第二步:通过大模型llm调用API
ctx := context.Background()
prompt := "早上好"
completion, err := llms.GenerateFromSinglePrompt(
ctx,
llm,
prompt,
)
if err != nil {
log.Fatal(err)
}
// 输出大模型生成的答复
fmt.Println(completion)
}
llms.GenerateFromSinglePrompt():该函数调用llm生成答复
prompt:提示词,表示我们向llm提问的问题。
completion:llm生成的答复。
接下来运行测试一下,运行后需要等待几秒钟,让llm生成答复。
至此,我们已经可以完成llm的最基本的调用。
接下了,我们进行一下进阶调用。
进阶调用
可以看到,我们完成了的基础调用,实际上只满足了GenerateFromSinglePrompt函数的前3个参数,至于之后的参数,那肯定就是用来给我们进行进阶调用的
看了一下,总共有这么多进阶调用的方法,我们挑几个重点来讲!
流式响应
当我们在官网向AI提问的时候,AI给我们的答复都是一点一点显示出来的,而不是一次性全部显示出来的。像这样一点一点生成的响应,就是所谓的流式响应!
我们现在为代码添加流式响应,原有代码不变,在 llms.GenerateFromSinglePrompt() 函数中新加一个 llms.WithStreamingFunc() 参数即可。 llm 会循环调用 llms.WithStreamingFunc(),并在每次调用时将分块结果赋值到 chunk,我们只需要打印 chunk 就好。
package main
import (
"context"
"fmt"
"log"
"github.com/tmc/langchaingo/llms"
"github.com/tmc/langchaingo/llms/openai"
)
func main() {
// 第一步:初始化大模型llm
llm, err := openai.New(
openai.WithModel("deepseek-reasoner"),
openai.WithToken("API key"),
openai.WithBaseURL("https://api.deepseek.com"),
)
if err != nil {
log.Fatal("初始化失败:", err)
}
// 第二步:通过大模型llm调用API
ctx := context.Background()
prompt := "早上好"
_, err = llms.GenerateFromSinglePrompt(
ctx,
llm,
prompt,
// 新增流式响应,允许模型以分块(chunk)形式返回结果。
llms.WithStreamingFunc(func(ctx context.Context, chunk []byte) error {
fmt.Print(string(chunk))
return err
}),
)
if err != nil {
log.Fatal(err)
}
// 输出大模型生成的答复
//fmt.Println(completion)
}
控制随机性
在 llms.GenerateFromSinglePrompt() 函数中新加一个llms.WithTemperature() 参数,填入的值temperature用于控制生成文本的随机性,范围通常在 0.0 到 2.0 之间,默认为1。
较低值(如 0.2):生成更确定、更保守的输出。
较高值(如 1.0):生成更随机、更具创造性的输出。
package main
import (
"context"
"fmt"
"log"
"github.com/tmc/langchaingo/llms"
"github.com/tmc/langchaingo/llms/openai"
)
func main() {
// 第一步:初始化大模型llm
llm, err := openai.New(
openai.WithModel("deepseek-reasoner"),
openai.WithToken("API key"),
openai.WithBaseURL("https://api.deepseek.com"),
)
if err != nil {
log.Fatal("初始化失败:", err)
}
// 第二步:通过大模型llm调用API
ctx := context.Background()
prompt := "早上好"
_, err = llms.GenerateFromSinglePrompt(
ctx,
llm,
prompt,
// 新增流式响应,允许模型以分块(chunk)形式返回结果。
llms.WithStreamingFunc(func(ctx context.Context, chunk []byte) error {
fmt.Print(string(chunk))
return err
}),
// 新增控制生成随机性
llms.WithTemperature(0.5),
)
if err != nil {
log.Fatal(err)
}
// 输出大模型生成的答复
//fmt.Println(completion)
}
停止词
在 llms.GenerateFromSinglePrompt() 函数中新加一个llms.WithStopWords() 参数,传入一个[]string表示停止词,当llm生成的答复中遇到这些停止词时会停止生成。
package main
import (
"context"
"fmt"
"log"
"github.com/tmc/langchaingo/llms"
"github.com/tmc/langchaingo/llms/openai"
)
func main() {
// 第一步:初始化大模型llm
llm, err := openai.New(
openai.WithModel("deepseek-reasoner"),
openai.WithToken("API key"),
openai.WithBaseURL("https://api.deepseek.com"),
)
if err != nil {
log.Fatal("初始化失败:", err)
}
// 第二步:通过大模型llm调用API
ctx := context.Background()
prompt := "早上好"
_, err = llms.GenerateFromSinglePrompt(
ctx,
llm,
prompt,
// 新增流式响应,允许模型以分块(chunk)形式返回结果。
llms.WithStreamingFunc(func(ctx context.Context, chunk []byte) error {
fmt.Print(string(chunk))
return err
}),
// 新增生成随机性
llms.WithTemperature(0.5),
// 新增停止词
llms.WithStopWords([]string{"\n", "END"}),
)
if err != nil {
log.Fatal(err)
}
// 输出大模型生成的答复
//fmt.Println(completion)
}
剩余功能
剩余功能很多,就不一一说了,大家看下方概述吧,调用方式和上方是一样的,相信大家已经学会了如何调用!
- Model (string)
作用:指定要使用的 LLM 模型名称。
示例:“deepseek-chat” 或 “gpt-3.5-turbo”。
说明:不同的 LLM 提供商(如 OpenAI、DeepSeek)支持不同的模型。你需要根据提供商的文档选择合适的模型名称。 - CandidateCount (int)
作用:指定生成候选答案的数量。
默认值:通常为 1。
说明:如果设置为大于 1,模型会返回多个可能的答案(例如 3 个候选答案)。这在需要多样化输出的场景中很有用。 - MaxTokens (int)
作用:限制生成文本的最大 token 数量。
示例:MaxTokens: 50 表示最多生成 50 个 token。
说明:token 通常包括单词、标点等。设置此值可以控制输出长度,避免过长的响应。 - Temperature (float64)
作用:控制生成文本的随机性。
范围:通常在 0.0 到 2.0 之间。
说明:
较低值(如 0.2):生成更确定、更保守的输出。
较高值(如 1.0):生成更随机、更具创造性的输出。
默认值:通常为 1.0。 - StopWords ([]string)
作用:指定停止词,模型在遇到这些词时停止生成。
示例:StopWords: []string{“\n”, “END”}。
说明:如果生成文本中出现这些词,模型会提前停止生成,适合需要特定格式输出的场景。 - StreamingFunc (func(ctx context.Context, chunk []byte) error)
作用:启用流式输出,允许模型以分块(chunk)形式返回结果。
说明:
每次生成一个 chunk(字节切片),都会调用此函数。
常用于实时显示生成内容(如聊天应用)。
示例:
Collapse
Wrap
Copy
StreamingFunc: func(ctx context.Context, chunk []byte) error {
fmt.Print(string(chunk))
return nil
}
- TopK (int)
作用:控制 Top-K 采样,限制模型在生成时考虑的词的范围。
说明:
模型只从概率最高的 K 个词中选择下一个词。
较小的 K 值使输出更确定,较大的 K 值增加多样性。 - TopP (float64)
作用:控制 Top-P 采样(也叫核采样),基于累积概率选择词。
范围:0.0 到 1.0。
说明:
模型选择累积概率达到 P 的最小词集合。
较小的 P 值(如 0.1)使输出更集中,较大的 P 值增加多样性。 - Seed (int)
作用:设置随机种子,确保生成结果可重现。
说明:如果设置了种子,相同的输入和参数会生成相同的输出。适合调试或需要一致性的场景。 - MinLength (int)
作用:指定生成文本的最小长度(以 token 计)。
说明:如果生成的 token 数量少于此值,模型会继续生成直到满足要求。 - MaxLength (int)
作用:指定生成文本的最大长度(以 token 计)。
说明:与 MaxTokens 类似,但某些模型可能使用 MaxLength 作为替代参数。 - N (int)
作用:指定生成多少个独立序列(类似 CandidateCount)。
说明:如果设置为 3,模型会生成 3 个不同的响应。 - RepetitionPenalty (float64)
作用:惩罚重复的词,减少生成文本中的重复。
范围:通常大于 1.0。
说明:值越大,模型越倾向于避免重复词语,适合需要多样化输出的场景。 - FrequencyPenalty (float64)
作用:根据词的出现频率施加惩罚,减少高频词的使用。
范围:通常在 0.0 到 1.0 之间。
说明:值越大,高频词的概率越低,适合避免生成过于常见的词。 - PresencePenalty (float64)
作用:对已出现的词施加惩罚,鼓励生成新词。
范围:通常在 0.0 到 1.0 之间。
说明:与 FrequencyPenalty 类似,但只关注词是否出现过,而不考虑频率。 - JSONMode (bool)
作用:强制模型以 JSON 格式输出。
说明:如果启用,模型会尝试生成有效的 JSON 字符串,适合需要结构化数据的场景。 - Tools ([]Tool)
作用:指定模型可以使用的工具(功能调用)。
说明:工具通常是外部函数,模型可以调用它们来执行任务(如搜索、计算)。需要提供商支持此功能。 - ToolChoice (any)
作用:控制模型是否必须使用工具。
说明:可以设置为 “auto”(自动选择)、“none”(不使用工具)或特定工具名称。 - Functions ([]FunctionDefinition)
作用:定义模型可以调用的函数(类似 Tools)。
说明:需要提供函数的定义(如名称、参数),模型会根据提示决定是否调用。 - FunctionCallBehavior (FunctionCallBehavior)
作用:控制模型调用函数的行为。
说明:可以设置为自动调用、强制调用或禁用调用,具体取决于模型支持。 - Metadata (map[string]interface{})
作用:附加元数据,随请求发送给 LLM。
说明:可以用于传递额外信息(如用户 ID、请求 ID),供提供商记录或处理。 - ResponseMIMEType (string)
作用:指定期望的响应 MIME 类型。
说明:例如 “application/json” 或 “text/plain”,某些模型可能支持不同的输出格式。