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

news2024/11/25 11:45:05

在这里插入图片描述

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)
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Vue引入element-plus-04

我们这次开发是使用vue的脚手架来进行开发,前面我们已经使用过最原生的方式去编写我们的vue的语法,从今天开始就使用vue的脚手架,但是前提是你需要用于node的环境 在我们开始之前&#xff0c;我们至少需要有node npm是什么&#xff1f; npm是一个强大的包管理工具&#xff0c;它…

监控神器vnStat初探

文章目录 一、概述二、官方docker部署1. vnStat守护进程和HTTP服务器在同一容器中运行2. 双容器运行&#xff0c;vnstat容器收集数据&#xff0c;vnstati容器提供web服务 三、修改后的编排文件四、运行结果五、停止监控不感兴趣的网卡 一、概述 vnStat是一款网络流量监测工具&…

智慧监狱技术解决方案

1. **建设背景**&#xff1a;介绍了智慧监狱建设的战略部署&#xff0c;包括司法部提出的“数字法治、智慧司法”信息化体系建设&#xff0c;以及智慧监狱建设的总体目标、重点任务和实施步骤。 2. **建设需求**&#xff1a;分析了当前监狱系统存在的问题&#xff0c;如子系统…

Java新特性与性能调优

引言 Java不断演进&#xff0c;每个新版本都引入了新的特性和改进&#xff0c;帮助开发者在提高生产力的同时&#xff0c;也能更好地优化程序性能。本文将详细介绍Java新版本中的重要特性&#xff0c;如从Java 8到Java 17&#xff0c;并探讨性能调优的方法&#xff0c;包括JVM调…

沃尔玛自养号测评:优势与技术要求解析

沃尔玛自养号测评是一种卖家在沃尔玛平台上提升店铺权重和排名的营销手段。传统运营策略的局限性日益显现&#xff0c;如营销手段单一、难以应对市场竞争等。因此&#xff0c;许多卖家为了提升店铺权重和排名&#xff0c;选择了自养号测评这一技术手段。 以下是对沃尔玛自养号…

C++ 46 之 关系运算符的重载

#include <iostream> #include <string> using namespace std;class Students06{ public:string m_name;int m_age;Students06(string name, int age){this->m_name name;this->m_age age;}// 重载了 bool operator(Students06 &stu){if(this->m_na…

CNN学习(7):用C++实现简单不同参数的卷积模型

目录 一、参数说明和计算公式 1、符号约定 2、输出大小计算公式 二、不同类型的卷积 1、输入3*3*1&#xff0c;卷积核3*3*1&#xff0c;输出1*1*1 &#xff08;1&#xff09;实现代码 &#xff08;2&#xff09;代码说明 2、输入4*4*1&#xff0c;卷积核3*3*1&#xff…

如何避免销售飞单私单!教你如何巧妙避开陷阱,业绩飙升!

明明投入了大量的时间和精力&#xff0c;客户却悄无声息地消失了&#xff1f;或是突然有一天&#xff0c;你发现原本属于你的订单被同事悄悄抢走&#xff1f;这背后&#xff0c;很可能隐藏着销售飞单私单的陷阱。今天&#xff0c;就让我们一起探讨如何巧妙避开这些陷阱&#xf…

MySQL-----InnoDB的自适应哈希索引

InnoDB存储引擎监测到同样的二级索引不断被使用&#xff0c;那么它会根据这个二级索引&#xff0c;在内存上根据二级索引树(B树)上的二级索引值&#xff0c;在内存上构建一个哈希索引&#xff0c;来加速搜索。 查看是否开启自适应哈希索引 show variables like innodb_adapti…

2024年【安全生产监管人员】试题及解析及安全生产监管人员考试试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 安全生产监管人员试题及解析是安全生产模拟考试一点通总题库中生成的一套安全生产监管人员考试试题&#xff0c;安全生产模拟考试一点通上安全生产监管人员作业手机同步练习。2024年【安全生产监管人员】试题及解析及…

LLM资料大全:文本多模态大模型、垂直领域微调模型、STF数据集、训练微调部署框架、提示词工程等

前言 自ChatGPT为代表的大语言模型&#xff08;Large Language Model, LLM&#xff09;出现以后&#xff0c;由于其惊人的类通用人工智能&#xff08;AGI&#xff09;的能力&#xff0c;掀起了新一轮[自然语言处理]领域的研究和应用的浪潮。尤其是以ChatGLM、LLaMA等平民玩家都…

Qwen-Agent:Qwen2加持,强大的多代理框架 - 函数调用、代码解释器以及 RAG!

✨点击这里✨&#xff1a;&#x1f680;原文链接&#xff1a;&#xff08;更好排版、视频播放、社群交流、最新AI开源项目、AI工具分享都在这个公众号&#xff01;&#xff09; Qwen-Agent&#xff1a;Qwen2加持&#xff0c;强大的多代理框架 - 函数调用、代码解释器以及 RAG&…

全局解决SpringBoot框架中的application.properties/yml注解中文乱码问题(一劳永逸)

问题原因 Spring Boot在加载application.properties/yml配置文件时&#xff0c;默认使用ISO-8859-1编码。这种编码方式并不支持中文字符&#xff0c;因此当配置文件中包含中文字符时&#xff0c;就会出现乱码&#xff0c;现象如下&#xff1a; 问题解决 本解决方法是全局设置…

最快安装zabbix

部署zabbix 6.x 建议使用红帽系统。 https://download.rockylinux.org/pub/rocky/8/isos/x86_64/Rocky-8.9-x86_64-minimal.iso1> 配置安装yum源 [rootzabbix ~]# yum install https://mirrors.huaweicloud.com/zabbix/zabbix/6.2/rhel/8/x86_64/zabbix-release-6.2-3.el8…

PMS助力制造企业高效运营︱PMO大会

全国PMO专业人士年度盛会 北京易贝恩项目管理科技有限公司副总经理朱洪泽女士受邀为PMO评论主办的2024第十三届中国PMO大会演讲嘉宾&#xff0c;演讲议题为“PMS助力制造企业高效运营”。大会将于6月29-30日在北京举办&#xff0c;敬请关注&#xff01; 议题简要&#xff1a; …

DeepDriving | CUDA编程-05:流和事件

本文来源公众号“DeepDriving”&#xff0c;仅用于学术分享&#xff0c;侵权删&#xff0c;干货满满。 原文链接&#xff1a;CUDA编程-05&#xff1a;流和事件 1 CUDA流 在CUDA中有两个级别的并发&#xff1a;内核级并发和网格级并发。前面的文章DeepDriving | CUDA编程-04&…

基于System-Verilog点亮LED灯

文章目录 一、System-Verilog介绍1.1System-Verilog 二、简单的语法介绍2.1接口实例2.2全局声明和语句实例2.3时间单位和精度2.4用户定义的类型2.5 枚举类型 三、流水灯参考 一、System-Verilog介绍 1.1System-Verilog SystemVerilog是一种硬件描述和验证语言&#xff08;HDV…

数据分析必备:一步步教你如何用matplotlib做数据可视化(2)

1、Matplotlib Anaconda Anaconda是Python和R编程语言的免费开源发行版&#xff0c;用于大规模数据处理&#xff0c;预测分析和科学计算。 该分发使包管理和部署变得简单容易。 Matplotlib和许多其他有用的(数据)科学工具构成了分发的一部分。 包版本由包管理系统Conda管理。 …

50【Aseprite 作图】模糊工具 笔刷

1 模糊工具 2 笔刷 然后 选中 后 Ctrl B&#xff0c;就变成笔刷了 可以按住shift &#xff0c;像画一条线一样 或者用矩形、圆形工具、油漆桶工具 在上方可以选择笔刷的不同形式&#xff0c;如果是“图案与来源对齐”&#xff0c;就是来源不变&#xff0c;笔刷不会覆盖之前…

Vue3【十五】标签的Ref属性

Vue3【十五】标签的Ref属性 标签的ref属性 用于注册模板引用 用在dom标签上&#xff0c;获取的是dom节点 用在组件上&#xff0c;获取的是组件实例对象 案例截图 目录结构 代码 app.vue <template><div class"app"><h1 ref"title2">你…