用langchain搭配最新模型ollama打造属于自己的gpt
langchain
前段时间去玩了一下langchain,熟悉了一下大模型的基本概念,使用等。前段时间meta
的ollama
模型发布了3.0,感觉还是比较强大的,在了解过后,自己去用前后端代码,调用ollama
模型搭建了一个本地的gpt应用。
核心逻辑
开始搭建
首先本地需要安装ollama的模型,这里有两种方式,大家自己选择即可,第一种选择官网下载[ollama], 第二种可以去docker hub里面下载,里面有ollama的镜像包, 这里为了方便我就用第一种了。
ollama
下载好之后,我们直接执行
ollama serve
命令即可, 出现下面的样子,代表执行成功了。
这时候ollama会运行在11434
端口,这样我们的后端可以通过端口连接到ollama的服务了。
ollama run llama3
直接执行这个命令就可以在本地终端里起一个gpt, llama3
是ollama
最新的模型
后端代码实现
后端我们用nestjs
来搭建
首先我们需要安装一个langchain的包 @langchain/community
, 我这里选用的社区版,支持度比较好,模型也比较多。
!!!注意点
推荐用npm和yarn安装, pnpm安装会导致失败,官网上面也有说明这个,楼主踩过坑,如果非要用pnpm安装的话,按照官网指示的操作来
import { Controller, Post, Body, Sse, Header } from '@nestjs/common';import { Observable, Subject } from 'rxjs';import { Ollama } from '@langchain/community/llms/ollama';@Controller()export class AppController {private messageSubject = new Subject<MessageEvent>();private model: Ollama;constructor() {this.model = new Ollama({baseUrl: 'http://localhost:11434',model: 'llama3',});}@Sse('sse')@Header('Content-Type', 'text/event-stream')sse(): Observable<MessageEvent> {return this.messageSubject.asObservable();}@Post('question')async addList(@Body() body: { question: string }): Promise<any> {const stream = await this.model.stream(body.question);for await (const str of stream) {this.messageSubject.next({data: JSON.stringify({ answer: str, end: false }),} as MessageEvent);
Å
}this.messageSubject.next({data: JSON.stringify({ answer: '', end: true }),} as MessageEvent);}}
sse技术
是一种基于HTTP协议的服务器到客户端的单向数据通信技术,允许服务器向浏览器实时推送更新,而不需要客户端通过轮询等方式反复请求数据。很多gpt应用服务端向客户端发送消息都是利用这种方式去做的。SSE协议本质上就是一个Http的get请求,也支持Https,服务端在接到该请求后,返回状态。同时请求头设置也变为流形式。
Content-Type: text/event-stream,
这里因为只是示例demo,逻辑就写在controller层了,标准一点的还是抽到service层。
nest的sse接口返回值是一个Observable(可观察对象)
, 刚好在rxjs中,我们的suject(主体)也是一种Observable
suject和普通的Observable区别在于,suject是多播,并且像EventEmitters
,像维护着多个监听器的一张注册表,当我们在请求到ollama返回的数据后,就可以调用next方法,将值多播到Observale中,这样就可以做到结果的接收
这个next方法,其实也就是迭代器方法,不断的调用next,会不断的输出值,直到没有值为止, 这里的end属性是控制我们客户端什么时候和服务端断开连接。
前端实现
前端的逻辑就很简单了,当我们发送问题后,监听到服务端发过来的结果收集起来展示即可,我这里的样式写的比较简陋,功能也只是最基本的,大家可以自己完善
import { useRef, useState } from "react";type Message = {answer: string;end: boolean;};export default function Layout() {const [message, setMessage] = useState<Message[]>([]);const [question, setQuestion] = useState<string>("");const ref = useRef<any>();const send = () => {const question = ref.current.value as string;if (!question) return;fetch("http://localhost:3000/question", {method: "POST",headers: {"Content-Type": "application/json",},body: JSON.stringify({question,}),});setQuestion(question);ref.current.value = "";setMessage((prev) => [...prev, { answer: "", end: false }]);const eventSource = new EventSource("http://localhost:3000/sse");eventSource.onmessage = ({ data }) => {const { answer, end } = JSON.parse(data);if (!end) {setMessage((prev) => {const newMessages = [...prev];newMessages[newMessages.length - 1].answer += answer;return newMessages;});}if (end) {eventSource.close();}};};return (<div className="h-screen w-screen overflow-hidden bg-orange-400"><nav className="w-full h-16 flex items-center justify-between bg-indigo-400 px-4"><span className="w-10 h-10"><img src="public/ollama.png" className="w-full h-full" /></span><span>ollama大模型</span><span className="">欢迎使用</span></nav><div className="w-full h-[calc(100%-64px)] relative"><aside className="w-[200px] bg-red-400 h-full p-4 absolute top-0 flex justify-center">todo</aside><main className="w-full h-full absolute left-[200px] top-0 px-2"><div className="w-full h-[calc(100%-64px)] py-4 overflow-y-auto"><divstyle={{display: question ? "block" : "none",}}className="human min-h-[100px] w-[calc(100%-200px)] p-4 rounded-lg text-white bg-yellow-300">{question}</div><divstyle={{display: message?.[message.length - 1]?.answer? "block": "none",}}className="ai min-h-[100px] text-white w-[calc(100%-200px)] bg-indigo-500 mt-5 rounded-lg p-4 ">{message?.[message.length - 1]?.answer}</div></div><footer className="rounded-lg relative bottom-2 w-[calc(100%-200px)] h-[64px] border-red-300 border-solid border-[1px]"><inputref={ref}type="text"className="rounded-lg w-full px-4 text-lg h-full caret-red-300 outline-none focus:border-[1px] focus:border-solid focus:border-red-500"/><buttononClick={() => send()}className="z-10 focus:text-red-700 absolute right-0 top-0 w-[64px] h-[62px] bg-red-300">发送</button></footer></main></div></div>);}
看下实现效果
总结
ollama
的中文支持度不是很好,看视频效果也能看得出来,不过功能还是很强大的。 功能实现的比较基础,不过核心功能都有,大家可以参考代码自行拓展,动动手,你我都有属于自己的gpt
那么,我们该如何学习大模型?
作为一名热心肠的互联网老兵,我决定把宝贵的AI知识分享给大家。 至于能学习到多少就看你的学习毅力和能力了 。我已将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。
一、大模型全套的学习路线
学习大型人工智能模型,如GPT-3、BERT或任何其他先进的神经网络模型,需要系统的方法和持续的努力。既然要系统的学习大模型,那么学习路线是必不可少的,下面的这份路线能帮助你快速梳理知识,形成自己的体系。
L1级别:AI大模型时代的华丽登场
L2级别:AI大模型API应用开发工程
L3级别:大模型应用架构进阶实践
L4级别:大模型微调与私有化部署
一般掌握到第四个级别,市场上大多数岗位都是可以胜任,但要还不是天花板,天花板级别要求更加严格,对于算法和实战是非常苛刻的。建议普通人掌握到L4级别即可。
以上的AI大模型学习路线,不知道为什么发出来就有点糊,高清版可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费
】

二、640套AI大模型报告合集
这套包含640份报告的合集,涵盖了AI大模型的理论研究、技术实现、行业应用等多个方面。无论您是科研人员、工程师,还是对AI大模型感兴趣的爱好者,这套报告合集都将为您提供宝贵的信息和启示。
三、大模型经典PDF籍
随着人工智能技术的飞速发展,AI大模型已经成为了当今科技领域的一大热点。这些大型预训练模型,如GPT-3、BERT、XLNet等,以其强大的语言理解和生成能力,正在改变我们对人工智能的认识。 那以下这些PDF籍就是非常不错的学习资源。
四、AI大模型商业化落地方案
作为普通人,入局大模型时代需要持续学习和实践,不断提高自己的技能和认知水平,同时也需要有责任感和伦理意识,为人工智能的健康发展贡献力量。
相关文章:

用langchain搭配最新模型ollama打造属于自己的gpt
langchain 前段时间去玩了一下langchain,熟悉了一下大模型的基本概念,使用等。前段时间meta的ollama模型发布了3.0,感觉还是比较强大的,在了解过后,自己去用前后端代码,调用ollama模型搭建了一个本地的gpt应用。 核心逻辑 开始搭…...

工业互联网基本概念及关键技术(295页PPT)
资料介绍: 工业互联网的核心是通过工业互联网平台把设备、生产线、工厂、供应商、产品和客户紧密地连接融合起来。这种连接能够形成跨设备、跨系统、跨厂区、跨地区的互联互通,从而提高效率,推动整个制造服务体系智能化。同时,工…...

Python pandas openpyxl excel合并单元格,设置边框,背景色
Python pandas openpyxl excel合并单元格,设置边框,背景色 1. 效果图2. 源码参考 1. 效果图 pandas设置单元格背景色,字体颜色,边框 openpyxl合并单元格,设置丰富的字体 2. 源码 # excel数字与列名互转 import o…...

【vue3|第7期】 toRefs 与 toRef 的深入剖析
日期:2024年6月6日 作者:Commas 签名:(ง •_•)ง 积跬步以致千里,积小流以成江海…… 注释:如果您觉得有所帮助,帮忙点个赞,也可以关注我,我们一起成长;如果有不对的地方ÿ…...

git代码冲突处理软件P4Merge
文章目录 1. 下载安装2. 配置脚本参考链接 1. 下载安装 下载地址:https://www.perforce.com/downloads/helix-visual-client-p4v 下载教程:http://blog.csdn.net/wirelessqa/article/details/9035215 这里下载之前需要注册。 2. 配置脚本 编写一个全局…...

Unity物体材质属性Offset动态偏移
Unity物体材质属性Offset动态偏移 MeshRenderer mr;float offset;public float scrollSpeed 0.5F;private void Start(){mr GetComponent<MeshRenderer>();}void Update(){offset -Time.time * scrollSpeed;mr.material.mainTextureOffset new Vector2(0, -offset);}…...

【数据结构】筛选法建堆
💞💞 前言 hello hello~ ,这里是大耳朵土土垚~💖💖 ,欢迎大家点赞🥳🥳关注💥💥收藏🌹🌹🌹 💥个人主页&#x…...

DevExpress Installed
一、What’s Installed 统一安装程序将DevExpress控件和库注册到Visual Studio中,并安装DevExpress实用工具、演示应用程序和IDE插件。 Visual Studio工具箱中的DevExpress控件 Visual Studio中的DevExpress菜单 Demo Applications 演示应用程序 Launch the Demo…...

解决QT QMessageBox 弹出需点击两次才能关闭问题
放个链接不迷路:添加链接描述...

Milvus--向量数据库
Milvus 是一个开源的向量数据库,专为高维向量数据的存储、查询和检索而设计。它支持多种类型的向量数据,如浮点数向量、整数向量等,并且提供了强大的向量相似度计算功能。Milvus采用分布式架构,可以轻松地扩展到大规模数据集&…...

php质量工具系列之PHPCPD
PHPCPD 用于检测重复代码,直观的说就是复制粘贴再稍微改改 该工具作者已经 停止维护 安装 composer global require --dev sebastian/phpcpd执行 phpcpd --log-pmd phpcpd_result.xml ./app参数介绍 --log-pmd 将结果保存在phpcpd_result.xml 中 ./app 是phpcpd扫…...

Android14 WMS-窗口绘制之relayoutWindow流程(二)-Server端
本文接着如下文章往下讲 Android14 WMS-窗口绘制之relayoutWindow流程(一)-Client端-CSDN博客 然后就到了Server端WMS的核心实现方法relayoutWindow里 WindowManagerService.java - OpenGrok cross reference for /frameworks/base/services/core/java/com/android/server…...

安全测试 之 安全漏洞:SQL注入
1. 背景 持续学习安全测试ing,安全测试是在IT软件产品的生命周期中,特别是产品开发基本完成到发布阶段,对产品进行检验以验证产品是否符合安全需求定义和产品质量标准的过程。也就是说安全测试是建立在功能测试的基础上进行的测试。 2. SQL…...

CUDA和驱动版本之间的对应关系
这个之前总结过,可是不太好找,专门写一篇博客再总结一下: 1. CUDA 12.5 Release Notes — Release Notes 12.5 documentation 相信很多朋友有一样的需求。...

MDK(μVsion3)问题总结及解决方法
问题 1:MDK 工具的 CARM 编译器? 我原来对 CARM 编译器比较熟悉,想用 CARM 编译器编译工程,但是却弹出一个不能执 行“cc”的错误,到 KEIL 网站查下才知道原因:由于 CARM 编译器是比较老的编译器࿰…...

手眼标定学习笔记
目录 标定代码: 手眼标定原理学习 什么是手眼标定 手眼标定的目的 eye in hand eye to hand AXXB问题的求解 标定代码: GitHub - pumpkin-ws/HandEyeCalib 推荐博文: https://zhuanlan.zhihu.com/p/486592374 手眼标定原理学习 参…...

Dell戴尔XPS 16 9640 Intel酷睿Ultra9处理器笔记本电脑原装出厂Windows11系统包,恢复原厂开箱状态oem预装系统
下载链接:https://pan.baidu.com/s/1j_sc8FW5x-ZreNrqvRhjmg?pwd5gk6 提取码:5gk6 戴尔原装系统自带网卡、显卡、声卡、蓝牙等所有硬件驱动、出厂主题壁纸、系统属性专属联机支持标志、系统属性专属LOGO标志、Office办公软件、MyDell、迈克菲等预装软…...

【第8章】SpringBoot实战篇之文章分类(上)
文章目录 前言一、后端代码1. CategoryController2. service3. CategoryMapper4. Category 二、测试1. 失败(校验)2.正常 总结 前言 从这开始进入文章相关的接口开发,本章主要介绍定义文章分类接口和新增文章分类 建表语句和测试用例,在SpringBoot专栏首…...

【QT】Qt Plugin开发
目录 插件是什么QT插件是什么 为什么要有插件开发插件开发优势插件和动态库区别 Qt PluginQT插件类型QT插件开发流程QT插件应用QT插件JSON文件 参考文章 插件是什么 插件(Plug-in,又称addin、add-in、addon或add-on,又译外挂)是一种遵循一定规范的应用程序接口编写出来的程序。…...

快速了解GPU分布通信技术:PCIe、NVLink与NVSwitch
在现代高性能计算和深度学习领域,GPU的强大计算能力使其成为不可或缺的工具。然而,随着模型复杂度的增加,单个GPU已经无法满足需求,需要多个GPU甚至多台服务器协同工作。这就要求高效的GPU互联通信技术,以确保数据传输…...

Python对获取数据的举例说明
当使用Python来获取数据时,有许多不同的方法和库可以根据你的需求来选择。以下是一些常见的示例,说明如何使用Python来从各种来源获取数据。 1. 从网站或API获取JSON数据 你可以使用requests库从网站或API获取JSON格式的数据。例如,从某个API…...

JVMの垃圾回收
在上一篇中,介绍了JVM组件中的运行时数据区域,这一篇主要介绍垃圾回收器 JVM架构图: 1、垃圾回收概述 在第一篇中介绍JVM特点时,有提到过内存管理,即Java语言相对于C,C进行的优化,可以在适当的…...

人工智能就业方向有哪些?
人工智能就业方向有哪些? 随着人工智能技术的不断发展,其应用领域也越来越广泛。对于想要进入人工智能领域的年轻人来说,选择一个合适的职业方向是至关重要的。今天给大家介绍六个热门的人工智能就业方向,分别是机器学习工程师、自然语言处理…...

自定义类型:枚举和联合体
在之前我们已经深入学习了自定义类型中的结构体类型 ,了解了结构体当中的内存对齐,位段等知识,接下来在本篇中将继续学习剩下的两个自定义类型:枚举类型与联合体类型,一起加油!! 1.枚举类型 …...

负载均衡加权轮询算法
随机数加权轮询算法 public int select() {int[] weights {10, 20, 50};int totalWeight weights[0] weights[1] weights[2];// 取随机数int offset ThreadLocalRandom.current().nextInt(totalWeight);for (int i 0; i < weights.length; i) {offset - weights[i];i…...

PyTorch 相关知识介绍
一、PyTorch和TensorFlow 1、PyTorch PyTorch是由Facebook开发的开源深度学习框架,它在动态图和易用性方面表现出色。它以Python为基础,并提供了丰富的工具和接口,使得构建和训练神经网络变得简单快捷。 发展历史和背景 PyTorch 是由 Fac…...

1千2初中英语语法题库ACCESS\EXCEL数据库
英语语法是针对英语语言进行研究后,系统地总结归纳出来的一系列语言规则。英语语法的精髓在于掌握语言的使用。比如词类有名词、代词、数词、感叹词等,时态有一般状态、进行状态、完成状态和完成进行状态四种,语态有主动语态、被动语态等。 …...

高德面试:为什么Map不能插入null?
在 Java 中,Map 是属于 java.util 包下的一个接口(interface),所以说“为什么 Map 不能插入 null?”这个问题本身问的不严谨。Map 部分类关系图如下: 所以,这里面试官其实想问的是:为…...

MySQL数据库主从配置
MySQL主从配置 1. 修改数据库my.cnf文件 修改数据库my.cnf文件,在文件中添加如下内容,其中主数据库的server-id必须要比从库的更小。 # 注册集群id server-id101 # 开启二进制日志文件 log-binmysql-bin # 设置日志格式 binlog-formatrow # 开启中继日…...

测试工程师经常使用的Python中的库,以及对应常用的函数
os (操作系统接口) 该库提供了许多与操作系统交互的函数,如文件处理、目录操作、进程管理等。 常用功能包括: os.name: 获取操作系统的名称。 os.path: 用于操作文件路径的模块,如os.path.join拼接路径。 os.mkdir: 创建目录。 os.remove: 删…...