大模型应用:LangChain-Golang核心模块使用

1.简介
LangChain是一个开源的框架,它提供了构建基于大模型的AI应用所需的模块和工具。它可以帮助开发者轻松地与大型语言模型(LLM)集成,实现文本生成、问答、翻译、对话等任务。LangChain的出现大大降低了AI应用开发的门槛,使得任何人都可以基于LLM构建自己的创意应用。本文将介绍基于Golang使用LangChain相关模块。
项目地址:https://github.com/tmc/langchaingo
2.核心模块
llm调用
func demo(ctx context.Context) {llm, err := openai.New(openai.WithModel("gpt-3.5-turbo"),openai.WithBaseURL("https://api.openai-proxy.com/v1"),openai.WithToken(conf.LLMHubConfig.Openai.Key),)if err != nil {log.Fatal(err)}completion, err := llms.GenerateFromSinglePrompt(ctx,llm,"hello world!",llms.WithTemperature(0),)if err != nil {log.Fatal(err)}fmt.Println(completion)
}
prompt模板
- 简单使用
func promptTemplate(ctx context.Context) {llm, err := openai.New(openai.WithModel("gpt-3.5-turbo"),openai.WithBaseURL(conf.LLMHubConfig.Openai.Host),openai.WithToken(conf.LLMHubConfig.Openai.Key),)if err != nil {log.Fatal(err)}prompt := prompts.PromptTemplate{Template: "你是一个文本翻译员,请将```括起来的原始文本转化为{{.lang}}。原始文本```{{.text}}```",InputVariables: []string{"text"},PartialVariables: map[string]any{"lang": "英语",},TemplateFormat: prompts.TemplateFormatGoTemplate,}result, err := prompt.Format(map[string]any{"text": "我是中国人",})if err != nil {log.Fatal(err)}fmt.Println(result)result, err = llm.Call(ctx, result)if err != nil {log.Fatal(err)}fmt.Println(result)
}
- 带输出格式化
func promptWithRoleJSON(ctx context.Context) {llm, err := openai.New(openai.WithModel("gpt-4o"),openai.WithBaseURL(conf.LLMHubConfig.Openai.Host),openai.WithToken(conf.LLMHubConfig.Openai.Key),)if err != nil {log.Fatal(err)}messages := []llms.MessageContent{llms.TextParts(llms.ChatMessageTypeSystem, "你是一个英文翻译员,需要将<>括起来的英文翻译为中文,用JSON格式输出:原始文本、翻译文本"),llms.TextParts(llms.ChatMessageTypeHuman, "<hello world>"),}content, err := llm.GenerateContent(ctx, messages, llms.WithJSONMode())if err != nil {log.Fatal(err)}fmt.Println(content.Choices[0].Content)
}
上下文记忆
func conversationMemory(ctx context.Context) {llm, err := openai.New(openai.WithModel("gpt-4o"),openai.WithBaseURL(conf.LLMHubConfig.Openai.Host),openai.WithToken(conf.LLMHubConfig.Openai.Key),)if err != nil {log.Fatal(err)}//memoryBuffer := memory.NewConversationBuffer()memoryBuffer := memory.NewConversationWindowBuffer(10)//memoryBuffer := memory.NewConversationTokenBuffer(llm, 1024)chatChain := chains.NewConversation(llm, memoryBuffer)messages := []string{"你好,我叫PBR","你知道我叫什么吗?","你可以解决什么问题?",}for _, message := range messages {completion, err := chains.Run(ctx, chatChain, message)for {if err == nil {break}time.Sleep(30 * time.Second)completion, err = chains.Run(ctx, chatChain, message)}chatMessages, _ := memoryBuffer.ChatHistory.Messages(ctx)fmt.Printf("上下文对话历史:%v\n", json.SafeDump(chatMessages))fmt.Printf("输入:%v\n输出:%v\n", message, completion)}
}
模型链
func llmChains(ctx context.Context) {llm, err := openai.New(openai.WithModel("gpt-4o"),openai.WithBaseURL(conf.LLMHubConfig.Openai.Host),openai.WithToken(conf.LLMHubConfig.Openai.Key),)if err != nil {log.Fatal(err)}// 单个输入prompt := prompts.NewPromptTemplate(`将"""括起来中文翻译为英文输出输入中文:"""{{.text}}"""输出结果中只需要有英文翻译,不要有其他字符`,[]string{"text"})llmChain := chains.NewLLMChain(llm, prompt)out, err := chains.Run(ctx, llmChain, "langchain是一款不错的llm脚手架")if err != nil {log.Fatal(err)}fmt.Println(out)// 多个输入translatePrompt := prompts.NewPromptTemplate("Translate the following text from {{.inputLanguage}} to {{.outputLanguage}}. {{.text}}",[]string{"inputLanguage", "outputLanguage", "text"},)llmChain = chains.NewLLMChain(llm, translatePrompt)// Otherwise the call function must be used.outputValues, err := chains.Call(ctx, llmChain, map[string]any{"inputLanguage": "English","outputLanguage": "Chinese","text": "I love programming.",})if err != nil {log.Fatal(err)}out, ok := outputValues[llmChain.OutputKey].(string)if !ok {log.Fatal(err)}fmt.Println(out)
}
顺序链
unc sequenceChains(ctx context.Context) {llm, err := openai.New(openai.WithModel("gpt-4o"),openai.WithBaseURL(conf.LLMHubConfig.Openai.Host),openai.WithToken(conf.LLMHubConfig.Openai.Key),)if err != nil {log.Fatal(err)}// 将输入翻译为特定语言chain1 := chains.NewLLMChain(llm,prompts.NewPromptTemplate("请将输入的原始文本:{{.originText}}翻译为{{.language}},直接输出翻译文本",[]string{"originText", "language"}))chain1.OutputKey = "transText"// 总结翻译后的文本概要chain2 := chains.NewLLMChain(llm, prompts.NewPromptTemplate("请将输入的原始文本:<{{.transText}}>总结50字以内概要文本。严格使用JSON序列化输出结果,不要带有```json序列化标识。其中originText为原始文本,summaryText为概要文本",[]string{"transText"}))chain2.OutputKey = "summary_json"chain, err := chains.NewSequentialChain([]chains.Chain{chain1, chain2}, []string{"originText", "language"}, []string{"summary_json"})if err != nil {log.Fatal(err)}resp, err := chain.Call(ctx, map[string]any{"originText": "langchain is a good llm frameworks","language": "中文",})if err != nil {log.Fatal(err)}for key, value := range resp {fmt.Printf("key = %v | value = %v\n", key, value)}
}
向量生成
func embeddingCreate(ctx context.Context) {// embedding生成测试llm, err := openai.New(openai.WithEmbeddingModel("text-embedding-ada-002"),openai.WithBaseURL(conf.LLMHubConfig.Openai.Host),openai.WithToken(conf.LLMHubConfig.Openai.Key),)if err != nil {log.Fatal(err)}vectors, err := llm.CreateEmbedding(ctx, []string{"chatgpt-3.5"})if err != nil {log.Fatal(err)}fmt.Println(vectors)
}
RAG
- RAG:检索增强生成,分为向量创建、向量存储、向量召回应用
func embeddingRag(ctx context.Context) {// embedding生成测试llm, err := openai.New(openai.WithEmbeddingModel("text-embedding-ada-002"),openai.WithBaseURL(conf.LLMHubConfig.Openai.Host),openai.WithToken(conf.LLMHubConfig.Openai.Key),)if err != nil {log.Fatal(err)}// 创建embedderopenAiEmbedder, err := embeddings.NewEmbedder(llm)if err != nil {log.Fatal(err)}// 基于redis存储向量redisStore, err := redisvector.New(ctx,redisvector.WithConnectionURL(conf.LLMHubConfig.Redis.Url),redisvector.WithIndexName("test_vector_idx", true),redisvector.WithEmbedder(openAiEmbedder),)if err != nil {log.Fatalln(err)}// 插入测试数据data := []schema.Document{{PageContent: "狸花猫", Metadata: nil},{PageContent: "金渐层猫", Metadata: nil},{PageContent: "松狮犬", Metadata: nil},}_, err = redisStore.AddDocuments(ctx, data)if err != nil {log.Fatalln(err)}docs, err := redisStore.SimilaritySearch(ctx, "猫", 3,vectorstores.WithScoreThreshold(0.5),)fmt.Println(docs)// 将vector检索接入chains中result, err := chains.Run(ctx,chains.NewRetrievalQAFromLLM(llm,vectorstores.ToRetriever(redisStore, 3, vectorstores.WithScoreThreshold(0.8)),),"有哪些猫?",)fmt.Println(result)
}
Agent
- Agent = LLM + Memory + Tools
- 已集成工具使用
func agent_math_and_search(ctx context.Context) {llm, err := openai.New(openai.WithModel("gpt-3.5-turbo"),openai.WithBaseURL(conf.LLMHubConfig.Openai.Host),openai.WithToken(conf.LLMHubConfig.Openai.Key),)if err != nil {log.Fatal(err)}wikiTool := wikipedia.New("test")agentTools := []tools.Tool{tools.Calculator{},wikiTool,}agent := agents.NewOneShotAgent(llm, agentTools)executor := agents.NewExecutor(agent,agentTools,agents.WithCallbacksHandler(callbacks.LogHandler{}),)// 计算result, err := chains.Run(ctx, executor, "计算1024除以2并加1024的结果")if err != nil {log.Fatal(err)}fmt.Println(result)// 搜索result, err = chains.Run(ctx, executor, "今天的日期以及中国在去年今天发生了什么大事")if err != nil {log.Fatal(err)}fmt.Println(result)
}
- 自定义工具
type randomNumberTool struct{}func (r randomNumberTool) Name() string {return "随机数计算工具"
}func (r randomNumberTool) Description() string {return "用于获取随机数"
}func (r randomNumberTool) Call(ctx context.Context, input string) (string, error) {return "1024", nil
}func agent_diy(ctx context.Context) {llm, err := openai.New(openai.WithModel("gpt-3.5-turbo"),openai.WithBaseURL(conf.LLMHubConfig.Openai.Host),openai.WithToken(conf.LLMHubConfig.Openai.Key),)if err != nil {log.Fatal(err)}agentTools := []tools.Tool{randomNumberTool{},}agent := agents.NewOneShotAgent(llm, agentTools)executor := agents.NewExecutor(agent,agentTools,agents.WithCallbacksHandler(callbacks.LogHandler{}),)result, err := chains.Run(ctx, executor, "告诉我一个随机数")if err != nil {log.Fatal(err)}fmt.Println(result)
}
相关文章:
大模型应用:LangChain-Golang核心模块使用
1.简介 LangChain是一个开源的框架,它提供了构建基于大模型的AI应用所需的模块和工具。它可以帮助开发者轻松地与大型语言模型(LLM)集成,实现文本生成、问答、翻译、对话等任务。LangChain的出现大大降低了AI应用开发的门槛,使得任何人都可以…...
【Tkinter界面】Canvas 图形绘制(03/5)
文章目录 一、说明二、画布和画布对象2.1 画布坐标系2.2 鼠标点中画布位置2.3 画布对象显示的顺序2.4 指定画布对象 三、你应该知道的画布对象操作3.1 什么是Tag3.2 操作Tag的函数 https://www.cnblogs.com/rainbow-tan/p/14852553.html 一、说明 Canvas(画布&…...
【CS.PL】Lua 编程之道: 基础语法和数据类型 - 进度16%
2 初级阶段 —— 基础语法和数据类型 文章目录 2 初级阶段 —— 基础语法和数据类型2.0 关键字(keywords) 🔥2.1 注释与标识符2.1.1 注释2.1.2 标识符 2.2 变量与赋值2.2.1 所有变量默认是全局变量 ≠ local, 有一个例外2.2.2 local变量是局部变量, 以end作为边界2.…...
centos7 xtrabackup mysql 基本测试(3)---虚拟机环境 安装mysql
centos7 xtrabackup mysql 基本测试(3)—虚拟机环境 安装mysql centos7 安装 mysql5.7 可以在运行安装程序之前导入密钥: sudo rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2022第一步、下载MySQL 安装包: sudo w…...
Java Native Interface 使用指南
我们知道Java本身的实现,很大一部分是用C写的。实际上,Java也允许我们和原生平台的代码进行交互。 Java定义了一个接口规范,就叫做Java Native Interface,通过这个接口规范,我们就可以让Java代码运行原生平台的代码。…...
代码随想录算法训练营第三十九天 | 62.不同路径、63. 不同路径 II、343. 整数拆分、96.不同的二叉搜索树
62.不同路径 题目链接:https://leetcode.cn/problems/unique-paths/ 文档讲解:https://programmercarl.com/0062.%E4%B8%8D%E5%90%8C%E8%B7%AF%E5%BE… 视频讲解:https://www.bilibili.com/video/BV1ve4y1x7Eu/ 思路 确定dp数组以及下标的含…...
C/C++函数指针、C#委托是什么?
函数指针 #include<stdio.h>//声明函数指针 typedef int(*Calc)(int a, int b); int Add(int a, int b) {return a b; } int Sub(int a, int b) {return a - b; }int main() {Calc funcPoint1 &Add;Calc funcPoint2 ⋐int x 120;int y 140;int z 0;z …...
红队攻防渗透技术实战流程:组件安全:JacksonFastJsonXStream
红队攻防渗透实战 1. 组件安全1.1 J2EE-组件Jackson-本地demo&CVE1.1.1 代码执行 (CVE-2020-8840)1.1.2 代码执行(CVE-2020-35728)1.2 J2EE-组件FastJson-本地demo&CVE1.2.1 FastJson <= 1.2.241.2.2 FastJson <= 1.2.471.2.3 FastJson <= 1.2.801.3 J2EE-组…...
Perl 语言学习进阶
一、如何深入 要深入学习Perl语言的库和框架,可以按照以下步骤进行: 了解Perl的核心模块:Perl有许多核心模块,它们提供了许多常用的功能。了解这些模块的功能和用法是深入学习Perl的第一步。一些常用的核心模块包括:S…...
LangGraph实战:从零分阶打造人工智能航空客服助手
❝ 通过本指南,你将学习构建一个专为航空公司设计的客服助手,它将协助用户查询旅行信息并规划行程。在此过程中,你将掌握如何利用LangGraph的中断机制、检查点技术以及更为复杂的状态管理功能,来优化你的助手工具,同时…...
R可视化:R语言基础图形合集
R语言基础图形合集 欢迎大家关注全网生信学习者系列: WX公zhong号:生信学习者Xiao hong书:生信学习者知hu:生信学习者CDSN:生信学习者2 基础图形可视化 数据分析的图形可视化是了解数据分布、波动和相关性等属性必…...
mysql导入sql文件失败及解决措施
1.报错找不到表 1.1 原因 表格创建失败,编码问题mysql8相较于mysql5出现了新的编码集 1.2解决办法: 使用vscode打开sql文件ctrlh,批量替换,替换到你所安装mysql支持的编码集。 2.timestmp没有设置默认值 Error occured at:20…...
JS:获取鼠标点击位置
一、获取鼠标在目标元素中的点击位置 getClickPos.ts: export const getClickPos (e: MouseEvent) > {return {x: e.offsetX,y: e.offsetY,}; };二、获取鼠标在页面中的点击位置 getClickPos.ts: export const getPageClickPos (e: MouseEvent) > {return {x: e.pa…...
使用开源的zip.cpp和unzip.cpp实现压缩包的创建与解压(附源码)
目录 1、使用场景 2、压缩包的创建 3、压缩包的解压 4、CloseZipZ和CloseZipU两接口的区别...
npm 异常:peer eslint@“>=1.6.0 <7.0.0“ from eslint-loader@2.2.1
node 用16版本 npm install npm6.14.15 -g将版本降级到6...
Docker|了解容器镜像层(2)
引言 容器非常神奇。它们允许简单的进程表现得像虚拟机。在这种优雅的底层是一组模式和实践,最终使一切运作起来。在设计的根本是层。层是存储和分发容器化文件系统内容的基本方式。这种设计既出人意料地简单,同时又非常强大。在今天的帖子[1]中…...
使用Python爬取temu商品与评论信息
【🏠作者主页】:吴秋霖 【💼作者介绍】:擅长爬虫与JS加密逆向分析!Python领域优质创作者、CSDN博客专家、阿里云博客专家、华为云享专家。一路走来长期坚守并致力于Python与爬虫领域研究与开发工作! 【&…...
mybatis学习--自定义映射resultMap
1.1、resultMap处理字段和属性的映射关系 如果字段名和实体类中的属性名不一致的情况下,可以通过resultMap设置自定义映射。 常规写法 /***根据id查询员工信息* param empId* return*/ Emp getEmpByEmpId(Param("empId") Integer empId);<select id…...
Elasticsearch之写入原理以及调优
1、ES 的写入过程 1.1 ES支持四种对文档的数据写操作 create:如果在PUT数据的时候当前数据已经存在,则数据会被覆盖,如果在PUT的时候加上操作类型create,此时如果数据已存在则会返回失败,因为已经强制指定了操作类型…...
python中装饰器的用法
最近发现装饰器是一个非常有意思的东西,很高级! 允许你在不修改函数或类的源代码的情况下,为它们添加额外的功能或修改它们的行为。装饰器本质上是一个接受函数作为参数的可调用对象(通常是函数或类),并返…...
(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)
题目:3442. 奇偶频次间的最大差值 I 思路 :哈希,时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况,哈希表这里用数组即可实现。 C版本: class Solution { public:int maxDifference(string s) {int a[26]…...
【WiFi帧结构】
文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成:MAC头部frame bodyFCS,其中MAC是固定格式的,frame body是可变长度。 MAC头部有frame control,duration,address1,address2,addre…...
Mac下Android Studio扫描根目录卡死问题记录
环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中,提示一个依赖外部头文件的cpp源文件需要同步,点…...
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中,新增了一个本地验证码接口 /code,使用函数式路由(RouterFunction)和 Hutool 的 Circle…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
如何应对敏捷转型中的团队阻力
应对敏捷转型中的团队阻力需要明确沟通敏捷转型目的、提升团队参与感、提供充分的培训与支持、逐步推进敏捷实践、建立清晰的奖励和反馈机制。其中,明确沟通敏捷转型目的尤为关键,团队成员只有清晰理解转型背后的原因和利益,才能降低对变化的…...
【SpringBoot自动化部署】
SpringBoot自动化部署方法 使用Jenkins进行持续集成与部署 Jenkins是最常用的自动化部署工具之一,能够实现代码拉取、构建、测试和部署的全流程自动化。 配置Jenkins任务时,需要添加Git仓库地址和凭证,设置构建触发器(如GitHub…...
CSS3相关知识点
CSS3相关知识点 CSS3私有前缀私有前缀私有前缀存在的意义常见浏览器的私有前缀 CSS3基本语法CSS3 新增长度单位CSS3 新增颜色设置方式CSS3 新增选择器CSS3 新增盒模型相关属性box-sizing 怪异盒模型resize调整盒子大小box-shadow 盒子阴影opacity 不透明度 CSS3 新增背景属性ba…...
初级程序员入门指南
初级程序员入门指南 在数字化浪潮中,编程已然成为极具价值的技能。对于渴望踏入程序员行列的新手而言,明晰入门路径与必备知识是开启征程的关键。本文将为初级程序员提供全面的入门指引。 一、明确学习方向 (一)编程语言抉择 编…...
宠物车载安全座椅市场报告:解读行业趋势与投资前景
一、什么是宠物车载安全座椅? 宠物车载安全座椅是一种专为宠物设计的车内固定装置,旨在保障宠物在乘车过程中的安全性与舒适性。它通常由高强度材料制成,具备良好的缓冲性能,并可通过安全带或ISOFIX接口固定于车内。 近年来&…...
