阿里通义大模型与 LangChainGo 集成案例
概述
本案例将展示如何将阿里通义大模型(如通义千问)与 LangChainGo 框架集成,实现文本生成、对话交互等功能。通义大模型是阿里巴巴达摩院开发的大语言模型,具有强大的中文理解和生成能力,结合 LangChainGo 可以快速构建复杂的 AI 应用。
环境准备
前提条件
- Go 1.21+ 开发环境
- 阿里通义大模型 API 访问密钥(API Key 和 Secret Key)
- 已安装
langchaingo库
获取API key https://bailian.console.aliyun.com/?tab=model#/api-key
安装依赖
go get github.com/tmc/langchaingo
go get github.com/aliyun/alibaba-cloud-sdk-go/services/dashscope
实现代码
1. 通义大模型客户端实现
首先,我们需要实现一个 LangChainGo 兼容的通义大模型客户端:
package main
import (
"context"
"encoding/json"
"fmt"
"strings"
"github.com/aliyun/alibaba-cloud-sdk-go/services/dashscope"
"github.com/tmc/langchaingo/llms"
)
// TongyiLLM 通义大模型客户端
type TongyiLLM struct {
apiKey string
modelName string
client *dashscope.Client
}
// NewTongyi 创建新的通义大模型实例
func NewTongyi(apiKey string, modelName string) (*TongyiLLM, error) {
client, err := dashscope.NewClientWithAccessKey("cn-beijing", apiKey)
if err != nil {
return nil, err
}
return &TongyiLLM{
apiKey: apiKey,
modelName: modelName,
client: client,
}, nil
}
// GenerateContent 实现 llms.Model 接口
func (t *TongyiLLM) GenerateContent(ctx context.Context, messages []llms.MessageContent, options ...llms.CallOption) (*llms.ContentResponse, error) {
// 解析调用选项
opts := llms.CallOptions{}
for _, opt := range options {
opt(&opts)
}
// 转换消息格式
var chatMessages []dashscope.ChatMessage
for _, msg := range messages {
role := convertRole(msg.Role)
content := strings.Join(msg.Parts, "\n")
chatMessages = append(chatMessages, dashscope.ChatMessage{
Role: role,
Content: content,
})
}
// 构建请求
req := dashscope.NewChatCompletionRequest()
req.Model = t.modelName
req.Messages = &chatMessages
if opts.Temperature > 0 {
req.Parameters = map[string]interface{}{
"temperature": opts.Temperature,
}
}
// 发送请求
resp, err := t.client.ChatCompletion(req)
if err != nil {
return nil, err
}
// 处理响应
if resp.Body.Code != "200" {
return nil, fmt.Errorf("通义大模型调用失败: %s, %s", resp.Body.Code, resp.Body.Message)
}
// 解析结果
var result map[string]interface{}
if err := json.Unmarshal([]byte(resp.Body.Result), &result); err != nil {
return nil, err
}
choices := result["choices"].([]interface{})
firstChoice := choices[0].(map[string]interface{})
message := firstChoice["message"].(map[string]interface{})
content := message["content"].(string)
return &llms.ContentResponse{
Choices: []llms.ContentChoice{
{
Content: llms.MessageContent{
Role: llms.ChatMessageTypeAI,
Parts: []string{content},
},
},
},
}, nil
}
// 转换角色名称
func convertRole(role llms.ChatMessageType) string {
switch role {
case llms.ChatMessageTypeSystem:
return "system"
case llms.ChatMessageTypeHuman:
return "user"
case llms.ChatMessageTypeAI:
return "assistant"
default:
return "user"
}
}
// 实现其他必要接口
func (t *TongyiLLM) GetNumTokens(text string) int {
// 简单的令牌计数实现,实际应用中可能需要更精确的计算
return len(strings.Fields(text))
}
2. 文本生成示例
使用通义大模型进行文本生成:
package main
import (
"context"
"fmt"
"log"
"os"
"github.com/tmc/langchaingo/llms"
)
func main() {
// 从环境变量获取 API Key
apiKey := os.Getenv("DASHSCOPE_API_KEY")
if apiKey == "" {
log.Fatal("请设置 DASHSCOPE_API_KEY 环境变量")
}
// 创建通义大模型实例,使用通义千问模型
llm, err := NewTongyi(apiKey, "qwen-plus")
if err != nil {
log.Fatal(err)
}
// 简单文本生成
ctx := context.Background()
prompt := "请介绍一下Go语言的主要特点"
// 调用大模型生成内容
result, err := llms.GenerateFromSinglePrompt(ctx, llm, prompt,
llms.WithTemperature(0.7),
)
if err != nil {
log.Fatal(err)
}
fmt.Println("生成结果:")
fmt.Println(result)
}
3. 带记忆的对话示例
结合 LangChainGo 的记忆功能实现多轮对话:
package main
import (
"context"
"fmt"
"log"
"os"
"github.com/tmc/langchaingo/chains"
"github.com/tmc/langchaingo/memory"
"github.com/tmc/langchaingo/prompts"
)
func main() {
// 初始化通义大模型
apiKey := os.Getenv("DASHSCOPE_API_KEY")
if apiKey == "" {
log.Fatal("请设置 DASHSCOPE_API_KEY 环境变量")
}
llm, err := NewTongyi(apiKey, "qwen-plus")
if err != nil {
log.Fatal(err)
}
// 创建对话记忆
chatMemory := memory.NewConversationBufferMemory()
// 创建提示模板
prompt := prompts.NewChatPromptTemplate(
[]prompts.MessageFormatter{
prompts.NewSystemMessagePromptTemplate(
"你是一个友好的助手,帮助用户解答问题。请用中文回答。",
nil,
),
prompts.NewHumanMessagePromptTemplate(
"{{.input}}",
[]string{"input"},
),
},
)
// 创建对话链
chain := chains.NewLLMChain(llm, prompt, chains.WithMemory(chatMemory))
// 对话循环
for {
var input string
fmt.Print("你: ")
fmt.Scanln(&input)
if input == "exit" {
break
}
result, err := chains.Call(context.Background(), chain, map[string]any{"input": input})
if err != nil {
log.Fatal(err)
}
fmt.Println("AI:", result["text"])
}
}
4. 文档摘要示例
使用通义大模型实现文档摘要功能:
package main
import (
"context"
"fmt"
"log"
"os"
"strings"
"github.com/tmc/langchaingo/chains"
"github.com/tmc/langchaingo/documentloaders"
"github.com/tmc/langchaingo/textsplitter"
)
func main() {
// 初始化通义大模型
apiKey := os.Getenv("DASHSCOPE_API_KEY")
if apiKey == "" {
log.Fatal("请设置 DASHSCOPE_API_KEY 环境变量")
}
llm, err := NewTongyi(apiKey, "qwen-plus")
if err != nil {
log.Fatal(err)
}
// 创建摘要链
summaryChain := chains.LoadRefineSummarization(llm)
// 示例文档内容
docContent := `Go语言是一种由Google开发的开源编程语言,于2009年11月正式发布。
它的设计目标是简单、高效、并发支持良好,以及易于学习和使用。
Go语言具有以下主要特点:
1. 简洁的语法:Go语言的语法简洁明了,减少了不必要的语法元素,使代码更易于阅读和编写。
2. 内置并发支持:Go语言通过goroutine和channel提供了简洁而强大的并发编程模型。
3. 静态类型:Go语言是静态类型的,这有助于在编译时捕获错误,提高代码的可靠性。
4. 垃圾回收:Go语言具有自动垃圾回收机制,减轻了开发者的内存管理负担。
5. 跨平台编译:Go语言支持跨平台编译,可以轻松生成不同操作系统的可执行文件。
由于这些特点,Go语言在云原生、微服务、分布式系统等领域得到了广泛应用。`
// 加载并分割文档
docs, err := documentloaders.NewText(strings.NewReader(docContent)).LoadAndSplit(
context.Background(),
textsplitter.NewRecursiveCharacter(),
)
if err != nil {
log.Fatal(err)
}
// 执行摘要
output, err := chains.Call(context.Background(), summaryChain, map[string]any{
"input_documents": docs,
})
if err != nil {
log.Fatal(err)
}
// 输出结果
fmt.Println("文档摘要:")
fmt.Println(output["text"])
}
运行方法
- 首先设置环境变量:
export DASHSCOPE_API_KEY="你的阿里通义API密钥"
- 运行相应的示例代码:
go run tongyi_example.go
关键技术点解析
-
模型适配:实现了 LangChainGo 的
llms.Model接口,使通义大模型能够无缝集成到 LangChainGo 生态中 -
消息转换:处理了通义大模型与 LangChainGo 之间的消息格式差异,包括角色映射和内容转换
-
参数配置:支持温度等生成参数的配置,控制输出的随机性
-
功能集成:展示了如何将通义大模型与 LangChainGo 的链(Chains)、记忆(Memory)等组件结合使用
扩展方向
-
添加流式输出支持:实现
GenerateContentStream方法,支持实时输出 -
完善令牌计数:实现更精确的中文字符令牌计数
-
支持更多模型:扩展支持通义大模型家族的其他模型,如 qwen-vl 多模态模型
-
工具调用:集成工具调用能力,使通义大模型能够使用外部工具
通过以上案例,我们展示了如何将阿里通义大模型与 LangChainGo 框架集成,利用 LangChainGo 的丰富组件快速构建强大的 AI 应用。