大模型应用: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中装饰器的用法
最近发现装饰器是一个非常有意思的东西,很高级! 允许你在不修改函数或类的源代码的情况下,为它们添加额外的功能或修改它们的行为。装饰器本质上是一个接受函数作为参数的可调用对象(通常是函数或类),并返…...

php实现一个简单的MySQL分页
一、案例演示: 二、php 代码 <?php $servername "localhost"; // MySQL服务器名称或IP地址 $username "root"; // MySQL用户名 $password "123456"; // MySQL密码 $dbname "test"; // 要连接…...

算法训练营day23补签
题目1:530. 二叉搜索树的最小绝对差 - 力扣(LeetCode) class Solution { public:int reslut INT_MAX;TreeNode* pre NULL;void trackingback(TreeNode* node) {if(node NULL) return;trackingback(node->left);if(pre ! NULL) {reslut…...

国密SM2JS加密后端解密
1.前端加密 前端加密开源库 sm-crypto 1.1 传统web,下载 sm-crypto 进行打包为 dist/sm2.js 相关打包命令 npm install --save sm-crypto npm install npm run prepublish在web页面引用打包后的文件 <script type"text/javascript" src"<%path %>…...

Cheat Engine.exe修改植物大战僵尸阳光与冷却
Cheat Engine.exe修改植物大战僵尸阳光与冷却 打开Cheat Engine.exe和植物大战僵尸,点CE中文件下面红框位置,选择植物大战僵尸,点击打开 修改冷却: 等冷却完毕,首次扫描0安放植物,再次扫描变动值等冷却完…...

python内置模块之queue(队列)用法
queue是python3的内置模块,创建堆栈队列,用来处理多线程通信,队列对象构造方法如下: queue.Queue(maxsize0) 是先进先出(First In First Out: FIFO)队列。 入参 maxsize 是一个整数,用于设置…...

Spring Security——结合JWT实现令牌的验证与授权
目录 JWT(JSON Web Token) 项目总结 新建一个SpringBoot项目 pom.xml PayloadDto JwtUtil工具类 MyAuthenticationSuccessHandler(验证成功处理器) JwtAuthenticationFilter(自定义token过滤器) W…...

Vector的底层结构剖析
vector的介绍: 1.Vector实现了List接口的集合。 2.Vector的底层也是一个数组,protected Object[] elementData; 3.Vector 是线程同步的,即线程安全,Vector类的操作方法带有Synchronized. 4.在开发中,需要线程同步时࿰…...

实现抖音视频滑动功能vue3+swiper
首先,你需要安装和引入Swiper库。可以使用npm或者yarn进行安装。 pnpm install swiper然后在Vue组件中引入Swiper库和样式。 // 导入Swiper组件和SwiperSlide组件,用于创建轮播图 import {Swiper, SwiperSlide } from swiper/vue; // 导入Swiper的CSS样式,确保轮播图的正确…...

Linux文件系统【真的很详细】
目录 一.认识磁盘 1.1磁盘的物理结构 1.2磁盘的存储结构 1.3磁盘的逻辑存储结构 二.理解文件系统 2.1如何管理磁盘 2.2如何在磁盘中找到文件 2.3关于文件名 哈喽,大家好。今天我们学习文件系统,我们之前在Linux基础IO中研究的是进程和被打开文件…...

JAVA学习笔记DAY5——Spring_Ioc
文章目录 Bean配置注解方式配置注解配置文件调用组件 注解方法作用域 DI注入注解引用类型自动装配文件结构自动装配实现 基本数据类型DI装配 Bean配置 注解方式配置 类上添加Ioc注解配置文件中告诉SpringIoc容器要检查哪些包 注解仅是一个标记 注解 不同注解仅是为了方便开…...