langchain是一个框架,用以
集成大语言模型、其他数据源(文档、数据库、应用库等)
让不同来源的数据进行交互
支持链,一连串的动作
langchain的基础数据类型
texts 自然语言交互
chat messages 特定消息分类
system:提供背景信息,告诉AI需要做什么
human:用户信息
AI:AI给出的回应
documents 文本和元数据
examples 例子(代表了函数的输入以及预期输出
langchain的组件
模型-IO输入输出
数据连接
文档加载器:加载不同来源的文档
文档转换器:拆分文档,将文档转换为QA格式等
文本嵌入模型:将非结构化的文档转换为浮点数列表
向量存储:存储和检索嵌入数据
检索器:查询数据
链:将chain定义为对组件的一系列的调用
记忆:记忆上下文,如聊天机器人
代理:使用多种工具,比如API
windows配置环境
下载anaconda与navigator,打开vscode
在anaconda prompt中创建虚拟环境
1 2 3 4 5 6 7 8 # 创建虚拟环境 conda create -n deepseek python=3.13 # 切换虚拟环境 conda activate deepseek # 安装langchain与deepseek相关组件 pip install langchain==0.3.17 langchain-community==0.3.16 langchain-core==0.3.34 langchain-deepseek==0.1.1 langchain-openai==0.3.3 faiss-cpu==1.10.0 rich==13.9.4
创建项目目录
vscode或pycharm切换解释器为虚拟环境
写入.env与python文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 from langchain_core.prompts import ChatMessagePromptTemplatefrom langchain_deepseek import ChatDeepSeekfrom rich import print from dotenv import load_dotenvload_dotenv() llm = ChatDeepSeek(model="deepseek-chat" ) prompt = "我可以解决{subject}的问题" chat_message_prompt = ChatMessagePromptTemplate.from_template(role="销售顾问" ,template=prompt) formatted_prompt = chat_message_prompt.format (subject="产品咨询" ) prompts = [str (formatted_prompt)] response = llm.generate(prompts) print (response)
linux配置环境 使用python直接创建虚拟环境
1 2 3 4 python3 -m venv ~/venv/lanchain/ source ~/venv/lanchain/bin /activate
使用miniconda创建虚拟环境
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 cd ~ wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh chmod +x Miniconda3-latest-Linux-x86_64.sh ./Miniconda3-latest-Linux-x86_64.sh conda tos accept --override-channels --channel https://repo.anaconda.com/pkgs/main conda tos accept --override-channels --channel https://repo.anaconda.com/pkgs/r conda create -n langchain python=3.12 -y conda activate langchain pip3 install langchain-huggingface langchain==0.3 .17 langchain-community==0.3 .16 langchain-core==0.3 .34 langchain-deepseek==0.1 .1 faiss-cpu==1.10 .0 rich==13.9 .4 sentence-transformers chromadb --upgrade-strategy only-if -needed --force-reinstall pip freeze > requirements.txt
词向量嵌入embedding与简单案例 embedding:将词语、短语、句子转换为数值向量的过程,这个是计算机可以识别的
最终会变成一个向量数据库
词向量嵌入的最终目的是让机器能理解文本
embedding的过程
初始化:每个词分配一个随机的向量
上下文学习:相似的向量靠近
优化:梯度下降的方式调整向量
embedding的作用
文本分类:将一段文本的词向量相加或平均,从而判断文本的分类,例如情感分析积极/消极
文本相似度:两段文本的相似度
消除文本歧义:确定一个词在上下文中的含义
机器翻译:源语言的词会与目标语言的词向量相似
之后就可以使用数学方法,对其进行比较、运算,从而知道词与词、句子与句子之间的关系
嵌入向量数据库
将词向量保存到一个库中,就是嵌入向量数据库,用以节省算力与时间
生成向量数据库的步骤 首先需要一些数据,可以是文本或大量文件
文本→文本切割: 大语言模型通常有一个固定的输入长度限制,将文本分割得更小,可以确保模型能够处理所有输入
选择嵌入模型: 使用一个向量模型,用来将词转换成向量
将文本保存到向量数据库中: 指定向量模型、文本、存储路径等参数
1 2 3 4 5 6 7 8 9 10 from langchain_community.vectorstores import Chromafrom langchain_huggingface import HuggingFaceEmbeddingsembeddings = HuggingFaceEmbeddings( model_name="sentence-transformers/all-MiniLM-L6-v2" , model_kwargs={'device' : 'cpu' } ) db = Chroma.from_documents(texts, embeddings,persist_directory="./chroma_db" ) print ("向量数据库创建完成!" )
使用向量数据库 使用向量数据库需要使用retirever,,将它们插入到一个提示中
然后再将该提示传递给LLM
1 2 3 4 5 6 7 8 9 10 11 12 retirever = docsearch.as_retirever() chain = RetrievalQAWithSourcesChain.from_chain_type( llm=llm, chain_type = "stuff" , retriever = retriever, return_source_document = True ) question = '小明在哪' result = chain({"question" : question})
model IO-简单案例 通过提示语Prompt进行输入
Prompt可以附带Template模板
模板中可以自定义输入的内容与输出的格式,形成Prompt template
最普通的prompt
1 2 3 4 5 6 7 8 9 10 11 12 13 14 from langchain_deepseek import ChatDeepSeekfrom dotenv import load_dotenvload_dotenv() llm = ChatDeepSeek(model="deepseek-chat" ) prompt = "今天11月12号,明天几号?" response = llm.invoke(prompt) print (response.content)
使用prompt模板
这种模板可以用变量(占位符)接受用户输入,然后转换为模板之后向llm提问
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 from langchain_deepseek import ChatDeepSeekfrom langchain.prompts import PromptTemplatefrom dotenv import load_dotenvload_dotenv() llm = ChatDeepSeek(model="deepseek-chat" ) template = """ 你是一个导游,帮我回答以下问题,每次回答不超过两句话。 我想去{location}旅游,有什么景点可以推荐? """ prompt = PromptTemplate( input_variables=["location" ], template=template ) final_prompt = prompt.format (location='浙江绍兴越城区' ) print (final_prompt)response = llm.invoke(final_prompt) print (response.content)你是一个导游,帮我回答以下问题,每次回答不超过两句话。 我想去浙江绍兴越城区旅游,有什么景点可以推荐? 我推荐您游览鲁迅故里和沈园,它们都位于绍兴越城区。鲁迅故里可以了解文学巨匠的成长足迹,沈园则以其古典园林和陆游诗词闻名。
格式化输出器,告诉llm用何种格式进行相应
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 from langchain.output_parsers import StructuredOutputParser,ResponseSchemafrom langchain.prompts import ChatMessagePromptTemplate,HumanMessagePromptTemplatefrom langchain.prompts import PromptTemplatefrom langchain_deepseek import ChatDeepSeekfrom dotenv import load_dotenvload_dotenv() llm = ChatDeepSeek(model="deepseek-chat" ) response_schemas = [ ResponseSchema(name="错误的文字" ,description="这里输入错误的问题" ), ResponseSchema(name="正确的文字" ,description="纠正后正确的文字" ) ] output_parser = StructuredOutputParser.from_response_schemas(response_schemas) format_instrustions = output_parser.get_format_instructions() print (format_instrustions)tempalte = """你是一个语文老师,需要帮助用户修改错别字:识别并修改用户输入的语句中的错别字,并且确保输出的文字是正确的 用户输入:{user_input} 以{output_format}的格式输出""" prompt = PromptTemplate( input_variables = ["user_input" ], partial_variables = {"output_format" : format_instrustions}, template = tempalte ) final_prompt = prompt.format (user_input="今天天奇振豪啊" ) print (final_prompt)response = llm.invoke(final_prompt) print (response.content)你是一个语文老师,需要帮助用户修改错别字:识别并修改用户输入的语句中的错别字,并且确保输出的文字是正确的 用户输入:今天天奇振豪啊 以The output should be a markdown code snippet formatted in the following schema, including the leading and trailing "```json" and "```" : "错误的文字" : string // 这里输入错误的问题 "正确的文字" : string // 纠正后正确的文字 的格式输出 "错误的文字" : "今天天奇振豪啊" , "正确的文字" : "今天天气真好啊"
链接数据-文件加载、分割简单案例
文档加载器loader:通过网络、本地的方式将文件加载到加载器中,便于处理和传送给大模型
文档分割器text splitters:大模型无法一次输入大量token,所以需要对文档进行分割,然后再传入向量数据库
文本搜索器retriever:在向量数据库中进行搜索
从本地加载文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 from langchain.output_parsers import StructuredOutputParser,ResponseSchemafrom langchain.prompts import ChatMessagePromptTemplate,HumanMessagePromptTemplatefrom langchain.prompts import PromptTemplatefrom langchain_deepseek import ChatDeepSeekfrom dotenv import load_dotenvfrom transformers import AutoTokenizerfrom langchain_community.document_loaders import WebBaseLoaderfrom langchain.text_splitter import RecursiveCharacterTextSplitterwith open ('./test.txt' ) as f: doc = f.read() tokenizer = AutoTokenizer.from_pretrained("deepseek-ai/deepseek-llm-7b-chat" ) tokens = tokenizer.encode(doc) token_count = len (tokens) print (f"Token 数量: {token_count} " )text_splitter = RecursiveCharacterTextSplitter( chunk_size = 150 , chunk_overlap = 20 ) texts = text_splitter.create_documents([doc]) print (f"一共有{len (texts)} 个小文档" )