从0开始认识langChain

langChain在我理解是一个集成了开发,测试,部署功能的一个llm大语言模型的框架

官方描述:

LangChain​​ 是一个用于构建基于大型语言模型(LLM)应用的框架,旨在简化 LLM 的集成、增强其能力,并支持复杂交互。它由 Harrison Chase 开发,已成为 AI 应用开发的重要工具,尤其适用于需要结构化数据处理、多步推理和外部知识检索的场景。​

在学习langchain的时候,你肯定已经了解过大模型并使用过基本的llm啦,接下来一起初步探究langchain

1,创建与大模型的对话

import os

from dotenv import load_dotenv
load_dotenv()
from langchain_openai import ChatOpenAI
from langchain_core.prompts import  ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser

prompt = ChatPromptTemplate.from_messages([
    ("system",  "你叫当当,别人问你的时候,你 always 回复:当当,你叫什么名字?"),
    ("user","{input}")
])
print(prompt)
# 初始化模型
langchainModel = ChatOpenAI(
    model="qwen-plus",
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1"
)
# langchainModel = Tongyi(model="qwen-plus",api_key=os.getenv("DASHSCOPE_API_KEY"))
repose =  langchainModel.invoke("你叫什么名字")
print(repose)
output_info = StrOutputParser()
chain = prompt | langchainModel | output_info
# repose =  langchainModel.invoke("你叫什么名字")
repose = chain.invoke({"input": "你叫什么名字"})
print(repose)

1.与llm的区别PromptTemplate生成提示词模板 其中可以用{input} 注入值,最后用invoke调用填值, 2.其中涉及到一个 | 链式调用方法 把左边的值交给右边处理  prompt | langchainModel | output_info 就是把prompt提示词交给 langchainModel 创建好的大模型 最后交给output_info去处理返回值, 3.图中大模型创建方式也有所不同 区别就是 图中大模型的返回值会带有一些额外的信息,比如 token 的消耗量以及明细

2,下面一起做一个小项目

首先,需要创建文本向量处理方式 在非langchain代码中,我们是这样处理的client为初始化的llm

repose = client.embeddings.create(
        model="text-embedding-v3",
        input=text
    ).data

在langchain中,我是这样处理的

 embeddings = OpenAIEmbeddings(
     model="text-embedding-v3",
     api_key=os.getenv("DASHSCOPE_API_KEY"),
     base_url="https://dashscope.aliyuncs.com/compatible-mode/v1"
 )

这样报错了创建失败,网上查询得知

DashScope Embeddings 是阿里云推出的一款先进的文本嵌入服务,能够将文本转换为高质量的向量表示,广泛应用于自然语言处理(NLP)和机器学习任务,如文本分类、相似度计算和信息检索

如果使用阿里的框架必须要使用DashScope

embeddings = DashScopeEmbeddings(
    model="text-embedding-v3",  # 阿里云支持的模型
    dashscope_api_key=os.getenv("DASHSCOPE_API_KEY"),
)

这样就可以创建出来

联想一下如果这样,那么初始化大模型的代码是不是也需要测试一下两种创建方式

langchainModel = ChatOpenAI(
    model="qwen-plus",
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1"
)

这个通过ChatOpenAI经过测试是可以正常使用的

那么用DashScope的创建方式呢

把ChatOpenAI替换成Tongyi就可以了也是可以正常使用的

利用这个向量处理来写代码如下

import requests
from bs4 import BeautifulSoup
import os

from dotenv import load_dotenv
from langchain_community.embeddings import DashScopeEmbeddings
from langchain_core.documents import Document

load_dotenv()
#爬取数据
url = "https://www.shuzhaige.com/douluodalu/"
header = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36"
}
# Send a GET request to the URL
res = requests.get(url, headers=header)
res.encoding = "utf-8"
documents = []
# Check if the request was successful
if res.status_code == 200:
    # Parse the HTML content using BeautifulSoup
    soup = BeautifulSoup(res.text, 'html.parser')
    # Find all <li> elements with the class 'line3'
    chapters = soup.find_all('li', class_='line3')
    # Extract the chapter title and URL from each <li> element
    documents = [chapter.find('a').get('title') for chapter in chapters]
else:
    print(f"Failed to retrieve the webpage. Status code: {res.status_code}")
print(documents)
documents_list = [Document(page_content=title, metadata={"source": "斗罗大陆"}) for title in documents]
print(documents_list)
from langchain_openai import OpenAIEmbeddings
# embeddings = OpenAIEmbeddings(
#     model="text-embedding-v3",
#     api_key=os.getenv("DASHSCOPE_API_KEY"),
#     base_url="https://dashscope.aliyuncs.com/compatible-mode/v1"
# )
embeddings = DashScopeEmbeddings(
    model="text-embedding-v3",  # 阿里云支持的模型
    dashscope_api_key=os.getenv("DASHSCOPE_API_KEY"),
)

from langchain_community.vectorstores import FAISS
from langchain_text_splitters import RecursiveCharacterTextSplitter
text_splitter =RecursiveCharacterTextSplitter(chunk_size=25, chunk_overlap=10)
texts = text_splitter.split_text(str(documents))
for text in texts:
    print(text)
vector1 = FAISS.from_texts(texts, embeddings)
print(vector1)
texts = text_splitter.split_documents(documents_list)
print("texts",texts)
# vectorEmbedding =  embeddings.embedding("hello")
# print(vectorEmbedding)
vector = FAISS.from_documents(texts, embeddings)
print(vector)
query = "唐三的第一魂技是什么?"
results = vector.similarity_search(query, k=5)
for result in results:
    print(result.page_content)

RecursiveCharacterTextSplitter是langchain提供的一种文本滑动框切割方式 25 是每次切割多少字符,10是滑动保留几个字符
例如:如果这两个参是 3 2 的话 切割 123456 就是 123 234 456 。

RecursiveCharacterTextSplitter创建分割方式后调用split_text进行文本分割,最后FAISS.from_texts获得向量 代码中也使用了document

进入源码可以看到text  和  document的区别就是document  进行了一个封装 可以接收文档的集合源码如下

图中爬虫代码是自己写的,langchain也有爬虫框架,感兴趣可以自己了解一下我爬的数据只有斗罗大陆的目录
最后similarity_search查询的结果为

下面列举几个langchain常用的提示词模板内容很简单就不做解释了直接上代码

from langchain.prompts import PromptTemplate
prompt = "你叫当当,别人问你的时候,你 always 回复:当当,你叫什么名字?用户:{input}"
promptTemplate = PromptTemplate.from_template(prompt)
print(promptTemplate)
print("="*50)
print(promptTemplate.format(input="你叫什么名字?"))

from langchain.prompts import ChatPromptTemplate

sysMessage = "你叫{name1},别人问你的时候,你 always 回复:你叫什么名字,{name2}?"
humanMessage = "你叫什么名字{input}?"
prompt = ChatPromptTemplate.from_messages([
    ("system", sysMessage),
    ("user", humanMessage)
])
print(prompt)
print("="*50)
print(prompt.format(input="你叫什么名字?", name1="当当", name2="你"))

from langchain.prompts import ChatPromptTemplate,SystemMessagePromptTemplate,HumanMessagePromptTemplate
sysTemplate = "你叫{name1},别人问你的时候,你 always 回复:你叫什么名字,{name2}?"
sysPrompt =  SystemMessagePromptTemplate.from_template(sysTemplate)
humanTemplate = "你叫什么名字{input}?"
humanPrompt = HumanMessagePromptTemplate.from_template(humanTemplate)
prompt = ChatPromptTemplate.from_messages([sysPrompt,humanPrompt])
print(prompt)
print("="*50)
print(prompt.format(input="你叫什么名字?", name1="当当", name2="你"))

from langchain.prompts import FewShotPromptTemplate, PromptTemplate

examples = [
    {"input": "张三", "output": "张"},
    {"input": "王强", "output": "王"},
    {"input": "诸葛亮", "output": "诸葛"},
]

prompt_sample = "{input}性什么?{output}"

prompt = FewShotPromptTemplate(
    examples=examples,
    example_prompt=PromptTemplate.from_template(prompt_sample),
    suffix="{input}性什么?",
    prefix="请根据输入的名字,给出姓。",  # 取消注释以添加说明
    input_variables=["input"]
)

print(prompt)
print("="*50)
print(prompt.format(input="刘备"))

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值