用langchain搭配最新模型ollama打造属于自己的gpt

用langchain搭配最新模型ollama打造属于自己的gpt

langchain

前段时间去玩了一下langchain,熟悉了一下大模型的基本概念,使用等。前段时间metaollama模型发布了3.0,感觉还是比较强大的,在了解过后,自己去用前后端代码,调用ollama模型搭建了一个本地的gpt应用。

www.zeeklog.com  - 用langchain搭配最新模型ollama打造属于自己的gpt

核心逻辑

www.zeeklog.com  - 用langchain搭配最新模型ollama打造属于自己的gpt

开始搭建

首先本地需要安装ollama的模型,这里有两种方式,大家自己选择即可,第一种选择官网下载, 第二种可以去docker hub里面下载,里面有ollama的镜像包, 这里为了方便我就用第一种了。

ollama

下载好之后,我们直接执行

ollama serve

命令即可, 出现下面的样子,代表执行成功了。

www.zeeklog.com  - 用langchain搭配最新模型ollama打造属于自己的gpt

这时候ollama会运行在11434端口,这样我们的后端可以通过端口连接到ollama的服务了。

ollama run llama3

直接执行这个命令就可以在本地终端里起一个gpt, llama3ollama最新的模型

www.zeeklog.com  - 用langchain搭配最新模型ollama打造属于自己的gpt

后端代码实现

后端我们用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中,这样就可以做到结果的接收

www.zeeklog.com  - 用langchain搭配最新模型ollama打造属于自己的gpt

这个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">

<div

style={{

display: question ? "block" : "none",

}}

className="human min-h-[100px] w-[calc(100%-200px)] p-4 rounded-lg text-white bg-yellow-300"

>

{question}

</div>

<div

style={{

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]">

<input

ref={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"

/>

<button

onClick={() => 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>

);

}

看下实现效果

www.zeeklog.com  - 用langchain搭配最新模型ollama打造属于自己的gpt

总结

ollama的中文支持度不是很好,看视频效果也能看得出来,不过功能还是很强大的。 功能实现的比较基础,不过核心功能都有,大家可以参考代码自行拓展,动动手,你我都有属于自己的gpt

如何学习AI大模型?

大模型时代,火爆出圈的LLM大模型让程序员们开始重新评估自己的本领。 “AI会取代那些行业?”“谁的饭碗又将不保了?”等问题热议不断。

不如成为「掌握AI工具的技术人」,毕竟AI时代,谁先尝试,谁就能占得先机!

想正式转到一些新兴的 AI 行业,不仅需要系统的学习AI大模型。同时也要跟已有的技能结合,辅助编程提效,或上手实操应用,增加自己的职场竞争力。

但是LLM相关的内容很多,现在网上的老课程老教材关于LLM又太少。所以现在小白入门就只能靠自学,学习成本和门槛很高

那么我作为一名热心肠的互联网老兵,我意识到有很多经验和知识值得分享给大家,希望可以帮助到更多学习大模型的人!至于能学习到多少就看你的学习毅力和能力了 。我已将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。

Read more

前端防范 XSS(跨站脚本攻击)

目录 一、防范措施 1.layui util  核心转义的特殊字符 示例 2.js-xss.js库 安装 1. Node.js 环境(npm/yarn) 2. 浏览器环境 核心 API 基础使用 1. 基础过滤(默认规则) 2. 自定义过滤规则 (1)允许特定标签 (2)允许特定属性 (3)自定义标签处理 (4)自定义属性处理 (5)转义特定字符 常见场景示例 1. 过滤用户输入的评论内容 2. 允许特定富文本标签(如富文本编辑器内容) 注意事项 更多配置 XSS(跨站脚本攻击)是一种常见的网络攻击手段,它允许攻击者将恶意脚本注入到其他用户的浏览器中。

详细教程:如何从前端查看调用接口、传参及返回结果(附带图片案例)

详细教程:如何从前端查看调用接口、传参及返回结果(附带图片案例)

目录 1. 打开浏览器开发者工具 2. 使用 Network 面板 3. 查看具体的API请求 a. Headers b. Payload c. Response d. Preview e. Timing 4. 实际操作步骤 5. 常见问题及解决方法 a. 无法看到API请求 b. 请求失败 c. 跨域问题(CORS) 作为一名后端工程师,理解前端如何调用接口、传递参数以及接收返回值是非常重要的。下面将详细介绍如何通过浏览器开发者工具(F12)查看和分析这些信息,并附带图片案例帮助你更好地理解。 1. 打开浏览器开发者工具 按下 F12 或右键点击页面选择“检查”可以打开浏览器的开发者工具。常用的浏览器如Chrome、Firefox等都内置了开发者工具。下面是我选择我的一篇文章,打开开发者工具进行演示。 2. 使用

Cursor+Codex隐藏技巧:用截图秒修前端Bug的保姆级教程(React/Chakra UI案例)

Cursor+Codex隐藏技巧:用截图秒修前端Bug的保姆级教程(React/Chakra UI案例) 前端开发中最令人头疼的莫过于那些难以定位的UI问题——元素错位、样式冲突、响应式失效...传统调试方式往往需要反复修改代码、刷新页面、检查元素。现在,通过Cursor编辑器集成的Codex功能,你可以直接用截图交互快速定位和修复这些问题。本文将带你从零开始,掌握这套革命性的调试工作流。 1. 环境准备与基础配置 在开始之前,确保你已经具备以下环境: * Cursor编辑器最新版(v2.5+) * Node.js 18.x及以上版本 * React 18项目(本文以Chakra UI 2.x为例) 首先在Cursor中安装Codex插件: 1. 点击左侧扩展图标 2. 搜索"Codex"并安装 3. 登录你的OpenAI账户(需要ChatGPT Plus订阅) 关键配置项: // 在项目根目录创建.