大模型应用: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)
    }

    // 创建embedder
    openAiEmbedder, 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)
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/711861.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C++ UML建模

starUML UML图转C代码 数据流图 E-R图 流程图 整体架构图 ORM关系图 参考 app.asar附件资源可免激活 JHBlog/设计模式/设计模式/1、StarUML使用简明教程.md at master SunshineBrother/JHBlog GitHub C程序员UML实务手册代码 - 开发实例、源码下载 - 好例子网 GitHub -…

RK3568平台(触摸篇)触摸屏基本原理

一.触摸屏概述 触摸屏作为一种新的输入设备&#xff0c;它是目前最简单、方便、自然的一种人机交互方式。 触摸屏又称为“触控屏”、“触控面板”&#xff0c;是一种可接收触头等输入讯号的感应式液晶显示装置&#xff1b;当接触了屏幕上的图形按钮时&#xff0c;屏幕上的触觉…

python保存文件后打不开的原因是什么

引入数据集&#xff0c;奇怪的是怎么也打不开&#xff0c;显示不存在这个文件&#xff1a; 但是&#xff0c;我将文件改个名字&#xff0c;就打开了&#xff0c;难道csv的文件命名必须有一定合法性&#xff1f; import pandas users pandas.read_csv("H:\python\data an…

MySQL基础——函数和约束

目录 1函数 1.1字符串函数 1.2数值函数 1.3日期函数 1.4流程函数 2约束 2.1约束概述和演示 2.2外键约束&#xff08;表连接键&#xff09; 1函数 函数是指一段可以直接被另一段程序调用的程序或代码。 1.1字符串函数 MySQL中内置了很多字符串函数&#xff0c;常用的…

PCtoLCD2002 图片取模教程

记录一下取模软件&#xff0c;自己也是经常忘记怎么用&#xff0c;比较烦 按照下面这张图来就可以了&#xff0c;STM32的OLED屏幕可以直接用来显示图片。

VisionOS的未来愿景:苹果VisionPro创业者的愿望清单

随着苹果公司在增强现实(AR)领域的不断探索,VisionPro作为其前沿产品,已经开始展现出改变我们与数字世界互动方式的潜力。作为一名VisionPro创业者,对未来VisionOS的更新充满了期待,并提出了一系列愿望清单,这些愿望不仅代表了个人的需求,也反映了用户社区对苹果AR生态的…

算法设计与分析 实验2 分治法求最近点对

目录 一、实验目的 二、实验概述 一、实验目的 掌握分治法思想。学会最近点对问题求解方法。 二、实验概述 分治法也称为分解法、分治策略等。分治法算法思想如下&#xff1a; (1) 将一个问题划分为同一类型的若干子问题&#xff0c;子问题最好规模相同。 (2) 对这些子问题…

微信监控销售防飞单系统,让你的团队业绩稳如泰山!

团队中偶尔出现的私单、飞单问题而烦恼不已&#xff1f;你是否渴望拥有一个神器&#xff0c;能够实时监控销售过程&#xff0c;确保团队业绩的稳健增长&#xff1f;今天&#xff0c;就让我们一起探索这款神奇的“微信监控销售防飞单系统”&#xff0c;让你的销售团队如虎添翼&a…

scrapy爬取豆瓣书单存入MongoDB数据库

scrapy爬取豆瓣书单存入MongoDB数据库 一、安装scrapy库二、创建scrapy项目三、创建爬虫四、修改settings,设置UA,开启管道五、使用xpath解析数据六、完善items.py七、在douban.py中导入DoubanshudanItem类八、爬取所有页面数据九、管道中存入数据,保存至csv文件十、将数据写…

永磁同步直线电机(PMLSM)控制与仿真4-永磁同步直线电机数学三环闭环控制仿真

文章目录 1、参数设置及脚本2、相电流波形3、位置波形4、速度波形5、控制电流波形6、永磁同步直线电机在实际控制中如何控制参考 写在前面&#xff1a;原本为一篇文章写完了永磁同步直线电机数学模型介绍&#xff0c;永磁同步直线电机数学模型搭建&#xff0c;以及永磁同步直线…

《Nest系列 - 1. 运行一个Nest项目以及整体目录学习》

初识Nest心路历程 作为一名前端开发&#xff0c;说实话&#xff0c;学习Nest后端技术, 会有一定的成本。我试着阅读文档&#xff0c;安装项目&#xff0c;把项目跑起来&#xff0c; 当我看到久违的Hellow world 后&#xff0c;还来不及欣喜&#xff0c;就困惑了, 作为一个后端…

cs与msf权限传递,以及mimikatz抓取明文密码

cs与msf权限传递&#xff0c;以及mimikatz抓取win10明文密码 1、环境准备2、Cobalt Strike ------> MSF2.1 Cobalt Strike拿权限2.2 将CS权限传递给msf 3、MSF ------> Cobalt Strike3.1 msf拿权限3.2 将msf权限传递给CS 4、使用mimikatz抓取明文密码 1、环境准备 攻击&…

使用libpurple函数库接入服务器

代码; #define CUSTOM_USER_DIRECTORY "/dev/null" // 定义用户目录 #define CUSTOM_PLUGIN_PATH "" // 定义插件目录 #define PLUGIN_SAVE_PREF "/purple/nullclient/plugins/saved" // 定义插件头目录 #define UI_ID "nullc…

如何实现电脑监视员工的电脑屏幕?六个方法偷偷分享给你

实现电脑监视员工的电脑屏幕&#xff0c;通常需要借助专业的监控软件或系统&#xff0c;这些工具旨在帮助企业管理者监督员工的工作状态&#xff0c;确保工作效率&#xff0c;同时保护公司资产和数据安全。以下是几种常见的实现方式。 1. 使用专业的远程监控软件 安企神软件&a…

如何进行LLM大模型推理优化

解密LLM大模型推理优化本质 一、LLM推理的本质以及考量点 LLM推理聚焦Transformer架构的Decoder以生成文本。过程分两步&#xff1a;首先&#xff0c;模型初始化并加载输入文本&#xff1b;接着&#xff0c;进入解码阶段&#xff0c;模型自回归地生成文本&#xff0c;直至满足…

微服务feign组件学习

手写不易&#xff0c;对您有帮助。麻烦一键三连。也欢饮各位大料指正&#xff0c;交流。 微服务feign组件学习 1.概念1.1 feign 概念1.2 Ribbon概念 2.使用2.1 集成feign2.1.1 maven依赖2.1.2 项目结构 2.2 使用2.2.1 定义feign接口2.2.2 消费端服务调用2.2.3 消费端扫描feig…

基于scikit-learn的机器学习分类任务实践——集成学习

一、传统机器学习分类流程与经典思想算法简述 传统机器学习是指&#xff0c;利用线性代数、数理统计与优化算法等数学方式从设计获取的数据集中构建预测学习器&#xff0c;进而对未知数据分类或回归。其主要流程大致可分为七个部分&#xff0c;依次为设计获取数据特征集&#x…

20240615给飞凌的OK3588-C开发板刷Rockchip原厂的Buildroot后的测试报告

20240615给飞凌的OK3588-C开发板刷Rockchip原厂的Buildroot后的测试报告&#xff1a; 【切记&#xff0c;由于没有替换DTS的&#xff0c;开发板发热量巨大&#xff01;因此配备鼓风机进行加强散热了】 0、adb 默认没有 1、HDMI IN 4K 2024/6/15 20:32 4K全屏 2、HDMI OUT …

博客论坛系统java博客管理系统基于springboot+vue的前后端分离博客论坛系统

文章目录 博客论坛系统一、项目演示二、项目介绍三、部分功能截图四、部分代码展示五、底部获取项目源码&#xff08;9.9&#xffe5;带走&#xff09; 博客论坛系统 一、项目演示 博客论坛系统 二、项目介绍 基于springbootvue的前后端分离博客论坛系统 系统角色&#xff1a…

【Arthas案例】某应用依赖两个GAV不同但包含两个相同全限定类名StaticLoggerBinder,引起log4j.Level类找不到异常

3分钟内解决问题 两个不同的GAV依赖冲突&#xff0c;包含相同全限定类名&#xff0c;引起ClassNotFoundException Maven依赖的三坐标体系GAV(G-groupId&#xff0c;A-artifactId&#xff0c;V-version) 【案例1】某应用依赖两个GAV不同的jar&#xff0c;但包含两个相同全限定类…