RAG
存在意义使用langchain或者其他框架操作prompts,总是希望模型能够记忆之前用户和模型对话的关键信息,但是大模型作为一个续写的深度学习模型不会自带记忆,需要有对应的外加操作来保存历史对话和从历史对话中检索相似或者有关的信息拼接prompts,存储消息的方式可以和后端存储数据一样,于是有了向量数据库,将历史对话做分词,分词映射成向量,组合形成向量数组,存储到向量数据库中并检索匹配的操作,即RAG 基本流程包裹索引, 检索和生成 索引阶段 将用户的语言按照一定数据源(可以自己定义),将其切分成标准长度的文本块(chunk),进行向量化嵌入(embedding),存储在向量数据库中 加载文件 内容提取 文本切割 文本向量化 存向量数据库 检索在向量数据库检索相似的前topk个文本块,将文本块拼接在调用的message里面,询问大模型 生成对应的response,根据自己定义的数据格式或者根据返回可以做后续操作 embedding向量化的细节操作 离线流程: 知识和信息 -> 嵌入化 -> 存入数据库 在线流程: 询问 ...
langchain基本使用
LangChain 基础入门:模型调用、Prompt 模板与链式编排环境准备1pip install langchain langchain-community langchain-ollama dashscope chromadb 各依赖的作用如下: langchain:LangChain 核心框架 langchain-community:社区维护的模型、工具、加载器等 langchain-ollama:调用本地 Ollama 模型 dashscope:调用通义千问、DashScope 相关能力 chromadb:向量数据库,常用于文档检索和记忆存储 如果你使用 OpenAI 或其他在线模型,还需要额外安装对应 SDK,并配置 API Key。例如 OpenAI 通常需要设置环境变量 OPENAI_API_KEY。 如果你调用的是通义千问,通常需要提前配置 DASHSCOPE_API_KEY,并注意网络代理问题;有些环境下开代理可能会导致请求失败。 LangChain 是什么LangChain 可以理解为一个“LLM...
openai库基本使用 --其他框架的起源
介绍openai库提供了各种语言调用llm的基本操作,封装了网络请求,消息序列化等中间操作LangChain 或 OpenAI SDK 在底层调用模型时,使用的是 HTTP + JSON 的方式进行通信。请求会被序列化为 JSON 格式,通过 HTTP POST 发送到模型服务端;服务端返回的结果同样是 JSON,再由 SDK 解析成 Python 对象。在流式输出场景下(stream=True),则采用 Server-Sent Events(SSE)协议,将模型生成的内容按 token 分块传输,每一块依然是 JSON 格式。这种“HTTP + JSON”的组合已经成为大模型 API 的事实标准,原因在于其简单、通用、易调试,并且方便不同厂商之间做兼容实现。 基本调用12345678910111213141516171819202122232425import os from openai import OpenAI from pprint import pprint try: client = OpenAI( #...
分布式事务
为什么要有分布式事务? 跨服务协同时候,例如订单从提交到检测到调用财务系统到更新用户系统,这些操作需要保证原子性,没有事务串起来的话中间崩了会导致操作丢失 数据库过大,做了分库分表,要统一对多个数据库进行操作 分布式事务解决方案 2PCprepare() commit() 准备和提交阶段,操作时候,服务端向本次事务的参与端发送一个prepare()命令,参与者准备完毕返回ack,所有参与者准备完毕了才可以进行下一阶段操作第二阶段是commit / abort操作,分为回滚和提交,协调者检查第一阶段参与者提交的prepare消息,如果第一阶段有任何一个参与者ack返回的是失败状态,返回参与者abort状态,否则执行commit返回结果 2PC作为强一致性协议,存在单点阻塞问题,因为协调者是单点的,如果协调者出现故障,也有几个情况 如果所有参与者事物都提交了prepare,且此时事务没有提交,那么可以选举新的协调者提交 如果由于网络原因部分参与者提交,部分没有成功提交,此时换上新的协调者并不能得到所有参与者的prepare消息,但是网络原因参与者的prepare...
HTTP缓存
缓存前端要控制请求接口的次数时候使用,当某个接口短时间内不断读取,但是数据却不需要一直变化,频繁请求接口会使性能下降,应该采取一些缓存策略 强制缓存http1.0 强制缓存通过请求头的expires实现,看一个例子![[{0178FA88-3861-452D-B53D-C26F03351AB6}.png]]访问/img/01.jpg 时候,在请求后返回了头expires的时间,expires是一个时间戳,当当前时间戳大于expires,就重新请求接口并写expires,否则直接使用缓存的数据返回,这样有一个问题,这个时间是根据客户端的手机时间进行判断,但是客户端和服务端的时间可能出现不一致,例如手机设定或者客户端自己修改时间等,这样太过依赖时间戳,于是映入了cache-control http1.1...
操作系统 --进程补充
...
操作系统 --进程补充
线程是一个基本的CPU执行单元,也是程序执行流的最小单位。引入线程之后,不仅是进程之间可以并发,进程内的各线程之间也可以并发,从而进一步提升了系统的并发度,使得一个进程内也可以并发处理各种任务(如QQ视频、文字聊天、传文件) 1. 用户级线程用户级线程是由用户态线程库创建、调度和管理的线程,内核对其不可见,内核只知道进程的存在。 常见线程库: 早期 POSIX 线程实现 协程(coroutine) Go 的 goroutine(本质是用户级调度) 从内核视角看,只能看到进程A, 而从用户视角看可以看到进程A,以及下面的线程1, 2, 3… 2. 内核级线程内核级线程是由操作系统内核直接创建、调度和管理的线程,每个线程都是内核调度的基本单位。 操作系统是可以明确感知内核级线程的存在的,实际上再linux系统里面,内核级线程是轻量的进程,都是用clone出来的,只是分配的资源少? 3. 二者比较用户级线程:...
redis+lua
Lua 的定位 轻量级脚本语言 解释执行 极其简单 嵌入式友好(Redis / Nginx / 游戏引擎) 最常见的 3 个地方 场景 用途 Redis 原子操作、事务逻辑 Nginx (OpenResty) 鉴权、限流、灰度 游戏服务器 配置、热更新 其操作保证原子性 基础语法变量&类型1234local a = 10 --numberlocal b = "hello" --stringlocal c = true -- boollocal d = nil -- nil Lua只有4种基本类型,string -> int用tonumber Lua没有struct,map之类,全靠table实现: 当数组用 12local arr = {1, 2, 3}print(arr[1]) -- 1(下标从1开始) 当map用 12local m = {}m["xx"] =...
