CDA Ⅲ LangChain框架初探大语言模型

包含考纲内容:
在这里插入图片描述

LangChain模型组件提供了与各种模型的集成,并为所有模型提供一个精简的统一接口。

本文参考链接 https://zhuanlan.zhihu.com/p/627833537
LangChain官方文档:https://www.langchain.com.cn/

# 首先需要安装langchain和OpenAI
# pip install openai
# pip install langchain
# 导入OpenAI API服务,申请serpapi token
import os
os.environ["OPENAI_API_KEY"] = "自己的key"
os.environ["SERPAPI_API_KEY"] = "自己的key"
# 导入OpenAI模型
from langchain.llms import OpenAI

让openai讲一个笑话

llm = OpenAI(model_name="text-davinci-003", n=2, temperature=0.3)
llm("给我讲一个笑话")
'\n\n一个人去买面包,店员问他:“你要几个面包?”顾客回答:“一个就够了,我只有一个嘴巴。”'

使用generate方法可以同时接收多个输入,并且返回token使用信息

llm.generate(["给我讲一个故事", "给我讲一个笑话"])
聊天模型
# 导入ChatOpenAI 模型
from langchain.chat_models import ChatOpenAI
from langchain.schema import (
    AIMessage,  # 用来保存LLM的响应,以便在下次请求时把这些信息传回给LLM
    HumanMessage,   # 给llm的提示信息,比如“实现一个快速排序方法”
    # ChatMessage,    # ChatMessage可以接收任意形式的值,但是在大多数时间,我们应该使用其余三种类型
    SystemMessage   # 设置LLM模型的行为方式和目标。你可以在这里给出具体的指示,比如“作为一个代码专家”,或者“返回json格式”
)
# 让OpenAI查询ModelY的尺寸数据,并且指定json格式返回
chat = ChatOpenAI(temperature=0)
messages = [
        SystemMessage(content="返回json object,不要纯文本,按照每项参数拆分,不要说明和解释信息"),
        HumanMessage(content="告诉我model Y汽车的尺寸参数")
]
chat(messages)
AIMessage(content='以下是Model Y汽车的尺寸参数:\n\n1. 车身长度(Overall Length):187英寸(4,750毫米)\n2. 车身宽度(Overall Width):75.6英寸(1,920毫米)\n3. 车身高度(Overall Height):63.9英寸(1,620毫米)\n4. 轴距(Wheelbase):113.8英寸(2,891毫米)\n5. 最小离地间隙(Ground Clearance):6.6英寸(168毫米)\n6. 车重(Curb Weight):4,416磅(2,003千克)\n7. 车内空间(Interior Space):可容纳5至7名乘客\n8. 车厢容积(Cargo Volume):68立方英尺(1,925升)\n\n请注意,这些尺寸参数可能会因不同的配置和选装件而有所变化。')
提示模板
from langchain.chat_models import ChatOpenAI
from langchain.prompts import (
    ChatPromptTemplate,
    PromptTemplate,
    SystemMessagePromptTemplate,
    AIMessagePromptTemplate,
    HumanMessagePromptTemplate,
)
from langchain.schema import (
    AIMessage,
    HumanMessage,
    SystemMessage
)
system_template="你是一个把{input_language}翻译成{output_language}的助手"
system_message_prompt = SystemMessagePromptTemplate.from_template(system_template)
human_template="{text}"
human_message_prompt = HumanMessagePromptTemplate.from_template(human_template)

chat_prompt = ChatPromptTemplate.from_messages([system_message_prompt, human_message_prompt])
messages = chat_prompt.format_prompt(input_language="英语", output_language="汉语", text="I love programming.")

print(messages)
messages=[SystemMessage(content='你是一个把英语翻译成汉语的助手'), HumanMessage(content='I love programming.')]

把messages传给ChatOpenAI 模型

chat = ChatOpenAI(temperature=0)
chat(messages.to_messages())
AIMessage(content='我喜欢编程。')
文本嵌入模型
from langchain.embeddings import OpenAIEmbeddings
# 实现文本嵌入:
embeddings = OpenAIEmbeddings()
text = "这是一个测试文档。"

query_result = embeddings.embed_query(text)
doc_result = embeddings.embed_documents([text])

# query_result, doc_result

embed_query和embed_documents两个方法,它们最大的不同是embed_query接收一个字符串作为输入,而embed_documents可以接收一组字符串,一些模型自身划分了这两个方法,LangChain也保留了下来

提示

零样本提示:
像GPT这样的大语言模型,它们训练了大量的数据,能够执行一些零样本任务

小样本提示:
当模型理解不了提示,我们就要在提示中提供引导或示例,对模型进行训练,这就是小样本提示

提示工程

虽然大语言模型接收的是自然语言,但是需要对提示进行很多优化调整,才能获得我们想要的输出结果,这个调整的过程叫做提示工程

一旦你有了一个起作用的提示,你可能想把它作为一个模板用于解决其他问题,LangChain就提供了PromptTemplates组件,它可以帮助你更方便的构建提示。

from langchain import PromptTemplate
from langchain.llms import OpenAI

template = "我的邻居姓{lastname},他生了个儿子,给他儿子起个名字"

prompt = PromptTemplate(
    input_variables=["lastname"],
    template=template,
)
prompt_text = prompt.format(lastname="王")
prompt_text
'我的邻居姓王,他生了个儿子,给他儿子起个名字'
# 调用OpenAI
llm = OpenAI(temperature=0.9)
llm(prompt_text)
'叫王智。'

这个例子很简单,是一个零样本提示,LangChain的PromptTemplate组件做了文本替换,把lastname替换成了用户输入,模型接收提示,返回了结果

我们再看一个例子,需求是根据用户输入,让模型返回对应的反义词,我们要通过示例来告诉模型什么是反义词,这是一个小样本提示,我们就用到了LangChain的FewShotPromptTemplate 组件。

from langchain import PromptTemplate, FewShotPromptTemplate
from langchain.llms import OpenAI

examples = [
    {"word": "开心", "antonym": "难过"},
    {"word": "高", "antonym": "矮"},
]

example_template = """
    单词: {word}
    反义词: {antonym}\\n
    """

example_prompt = PromptTemplate(
    input_variables=["word", "antonym"],
    template=example_template,
)

few_shot_prompt = FewShotPromptTemplate(
    examples=examples,
    example_prompt=example_prompt,
    prefix="给出每个单词的反义词",
    suffix="单词: {input}\\n反义词:",
    input_variables=["input"],
    example_separator="\\n",
)

prompt_text = few_shot_prompt.format(input="粗")
prompt_text
'给出每个单词的反义词\\n\n    单词: 开心\n    反义词: 难过\\n\n    \\n\n    单词: 高\n    反义词: 矮\\n\n    \\n单词: 粗\\n反义词:'
# 调用OpenAI
llm = OpenAI(temperature=0.9)
print(llm(prompt_text))  # 细

LangChain中的链描述了将LLM与其他组件结合起来完成一个应用程序的过程,这也是LangChain名字的由来

# 改写上述提示模板的例子:
from langchain import PromptTemplate
from langchain.llms import OpenAI
from langchain.chains import LLMChain

template = "我的邻居姓{lastname},他生了个儿子,给他儿子起个名字"

prompt = PromptTemplate(
    input_variables=["lastname"],
    template=template,
)
llm = OpenAI(temperature=0.9)

chain = LLMChain(llm = llm, prompt = prompt)
chain.run("王")
'\n\n可以取名为王硕、王凯、王弘或者王铭等。'

如果我们想把第一个模型的输出,作为第二个模型的输入,可以使用LangChain的SimpleSequentialChain

from langchain import PromptTemplate
from langchain.llms import OpenAI
from langchain.chains import LLMChain, SimpleSequentialChain

template = "我的邻居姓{lastname},他生了个儿子,给他儿子起个名字"

prompt = PromptTemplate(
    input_variables=["lastname"],
    template=template,
)
llm = OpenAI(temperature=0.9)

chain = LLMChain(llm = llm, 
                  prompt = prompt)
# 创建第二条链
second_prompt = PromptTemplate(
    input_variables=["child_name"],
    template="邻居的儿子名字叫{child_name},给他起一个小名",
)

chain_two = LLMChain(llm=llm, prompt=second_prompt)

# 链接两条链 
overall_chain = SimpleSequentialChain(chains=[chain, chain_two], verbose=True)
# 执行链,只需要传入第一个参数
catchphrase = overall_chain.run("王")
catchphrase
> Entering new SimpleSequentialChain chain...

王文慧
可以叫他“文慧”或“文文”,也可以变一下叫“慧文”或“文哲”等等。

> Finished chain.
'可以叫他“文慧”或“文文”,也可以变一下叫“慧文”或“文哲”等等。'
代理

代理负责控制整段代码的逻辑和执行,代理暴露了一个接口,用来接收用户输入,并返回AgentAction或AgentFinish,AgentAction决定使用哪个工具,AgentFinish意味着代理的工作完成了,返回给用户结果

尽管大语言模型非常强大,它们也有一些局限性,它们不能回答实时信息,它们没有上下文的概念,导致无法保存状态,它们处理数学逻辑问题仍然非常初级,我们只能借助于第三方的工具来完成这些需求,比如使用搜索引擎或者数据库,LangChain中代理的作用就是根据用户需求,来去访问这些工具。

create_csv_agent 可以使用模型解读csv文件

from langchain.agents import create_csv_agent
from langchain.llms import OpenAI
agent = create_csv_agent(OpenAI(temperature=0), './test.csv', verbose=True)  # verbose=True打印详细信息
agent.run("一共有多少行数据?")
> Entering new AgentExecutor chain...
Thought: 我需要知道dataframe的行数
Action: python_repl_ast
Action Input: df.shape[0]
Observation: 7
Thought: 我现在知道最终答案
Final Answer: 一共有7行数据。

> Finished chain.

'一共有7行数据。'

明确了这些概念,我们看个使用代理的例子,假如我们在北京,想让大语言模型告诉我们明天穿什么衣服,由于大语言模型不知道明天的天气,我们借助于serpapi 来查询天气,并传递给模型,代码如下

需要申请serpapi token,并且设置到环境变量SERPAPI_API_KEY ,然后安装依赖包google-search-results

from langchain.agents import load_tools
from langchain.agents import initialize_agent
from langchain.agents import AgentType
from langchain.llms import OpenAI

llm = OpenAI(temperature=0)
tools = load_tools(["serpapi"], llm=llm)
agent = initialize_agent(tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True)

agent.run("明天在北京穿什么衣服合适?")
> Entering new AgentExecutor chain...
 I need to find out what the weather will be like tomorrow in Beijing.
Action: Search
Action Input: "Beijing weather tomorrow"
Observation: {'type': 'weather_result', 'temperature': '75', 'unit': 'Fahrenheit', 'precipitation': '0%', 'humidity': '46%', 'wind': '5 mph', 'location': 'Beijing, China', 'date': 'Tuesday', 'weather': 'Partly cloudy'}
Thought: Based on the weather, I should wear something light and comfortable.
Final Answer: Wear something light and comfortable, such as a t-shirt and shorts.

> Finished chain.

'Wear something light and comfortable, such as a t-shirt and shorts.'
记忆

大语言模型是无状态的,它并不保存上次交互的内容,chatGPT能够和人正常对话,因为它做了一层包装,把历史记录传回给了模型。
为了解决这个问题,LangChain提供了记忆组件。记忆有两种类型:短期和长期记忆。短期记忆一般指单一会话时传递数据,长期记忆则是处理多个会话时获取和更新信息

# 目前记忆组件只需要考虑ChatMessageHistory
from langchain.memory import ChatMessageHistory
history = ChatMessageHistory()
history.add_user_message("在吗?")
history.add_ai_message("有什么事?")

history.messages
[HumanMessage(content='在吗?'), AIMessage(content='有什么事?')]
# 和OpenAI结合,直接使用ConversationChain
from langchain import ConversationChain
from langchain.llms import OpenAI

llm = OpenAI(temperature=0)
conversation = ConversationChain(llm=llm, verbose=True)
conversation.predict(input="小明有1只猫")
conversation.predict(input="小刚有2只狗")
conversation.predict(input="小明和小刚一共有几只宠物?")
> Entering new ConversationChain chain...
Prompt after formatting:
The following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.

Current conversation:

Human: 小明有1只猫
AI:

> Finished chain.


> Entering new ConversationChain chain...
Prompt after formatting:
The following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.

Current conversation:
Human: 小明有1只猫
AI:  哇,真的吗?小明有多久了呢?
Human: 小刚有2只狗
AI:

> Finished chain.


> Entering new ConversationChain chain...
Prompt after formatting:
The following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.

Current conversation:
Human: 小明有1只猫
AI:  哇,真的吗?小明有多久了呢?
Human: 小刚有2只狗
AI:  哇,真的吗?小刚有多久了呢?他们是什么品种的狗呢?
Human: 小明和小刚一共有几只宠物?
AI:

> Finished chain.

' 小明和小刚一共有3只宠物,1只猫和2只狗。'
# 如果要像chatGPT一样,长期保存历史消息,,可以使用messages_to_dict 方法
from langchain.memory import ChatMessageHistory
from langchain.schema import messages_from_dict, messages_to_dict

history = ChatMessageHistory()
history.add_user_message("hi!")
history.add_ai_message("whats up?")

dicts = messages_to_dict(history.messages)
dicts
[{'type': 'human',
  'data': {'content': 'hi!',
   'additional_kwargs': {},
   'type': 'human',
   'example': False,
   'is_chunk': False}},
 {'type': 'ai',
  'data': {'content': 'whats up?',
   'additional_kwargs': {},
   'type': 'ai',
   'example': False,
   'is_chunk': False}}]
# 读取历史消息
new_messages = messages_from_dict(dicts)
new_messages
[HumanMessage(content='hi!'), AIMessage(content='whats up?')]
索引

索引组件为LangChain提供了文档处理的能力,包括文档加载、检索等等,这里的文档是广义的文档,不仅仅是txt、epub、pdf等文本类的内容,还包括email、区块链、telegram、Notion甚至是视频内容

索引组件主要有以下四种类型:
文档加载器(文档加载器主要基于Unstructured 包,Unstructured 是一个python包,可以把各种类型的文件转换成文本);
文本分割器(由于模型对输入的字符长度有限制,我们在碰到很长的文本时,需要把文本分割成多个小的文本片段。文本分割最简单的方式是按照字符长度进行分割,但是这会带来很多问题,比如说如果文本是一段代码,一个函数被分割到两段之后就成了没有意义的字符,所以整体的原则是把语义相关的文本片段放在一起);
VectorStores(VectorStores是一种特殊类型的数据库,它的作用是存储由嵌入创建的向量,提供相似查询等功能);
检索器(检索器是一种便于模型查询的存储数据的方式,LangChain约定检索器组件至少有一个方法get_relevant_texts,这个方法接收查询字符串,返回一组文档)

# 文档加载器使用起来很简单,只需要引入相应的loader工具
from langchain.document_loaders import TextLoader
loader = TextLoader('./HUAWEI_MATE60_PRO.txt', encoding='utf8')
documents = loader.load()
documents
[Document(page_content='HUAWEI Mate 60 Pro\n华为于2023年8月发售的一款手机\nHUAWEI Mate 60 Pro是华为技术有限公司于2023年8月29日上架的一款智能手机, 前代产品为2022年9月6日发布的HUAWEI Mate 50 Pro。\n华为Mate 60 Pro为全球首款支持卫星通话的大众智能手机,即使在没有地面网络信号的情况下,也可以拨打接听卫星电话,同时其将首发第二代昆仑玻璃,\n另外该手机还将上线AI隔空操控、智感支付、注视不熄屏等智慧功能,并将接入盘古人工智能大模型。 同时,设备还搭载了海思麒麟9000s八核处理器,预装华为自主研发的HarmonyOS 4.0操作系统,\n前置1300万像素超广角摄像头+3D深感摄像头,后置5000万像素超光变摄像头+1200万像素超广角摄像头+4800万像素超微距长焦摄像头,搭载5000毫安时不可拆卸式电池,支持88W快充。 \nHUAWEI Mate 60 Pro 长度是163.65mm,宽度是79mm,厚度是8.1mm,重量约225g(含电池)。 机型共有四款配色方案,分别是雅川青,白沙银,南糯紫,雅丹黑。', metadata={'source': './HUAWEI_MATE60_PRO.txt'})]
# LangChain中最基本的文本分割器是CharacterTextSplitter ,它按照指定的分隔符(默认“\n\n”)进行分割,并且考虑文本片段的最大长度
from langchain.text_splitter import CharacterTextSplitter

# 初始字符串
with open('./上林赋.txt', encoding='utf-8') as f:
    text1s = f.read()
state_of_the_union = ''.join(text1s)
# state_of_the_union
text_splitter = CharacterTextSplitter(        
    separator = "\n\n",    # 用于指定文本的分隔符。在这种情况下,文本会根据两个连续的换行符(\n\n)作为分隔符进行拆分
    chunk_size = 1000,     # 表示每个拆分块的大小。在这种情况下,每个拆分块的大小为 1000 个字符
    chunk_overlap  = 100,  # 200 个字符的重叠
    length_function = len, # 这是一个函数,用于计算文本的长度。在这种情况下,len 函数会被用于计算文本的长度
)
texts = text_splitter.create_documents([state_of_the_union])
texts
[Document(page_content='亡是公听然而笑曰:“楚则失矣,而齐亦未为得也。夫使诸侯纳贡者,非为财币,所以述职也。封疆画界者,非为守御,所以禁淫也。今齐列为东藩,而外私肃慎,捐国逾限,越海而田,其于义固未可也。且二君之论,不务明君臣之义,正诸侯之礼,徒事争于游戏之乐,苑囿之大,欲以奢侈相胜,荒淫相越。此不可以扬名发誉,而适足以贬君自损也。且夫齐楚之事,又乌足道乎?君未睹夫巨丽也,独不闻天子之上林乎?\n\n左苍梧,右西极;丹水更其南,紫渊径其北。终始灞浐,出入泾渭;酆镐潦潏,纡馀委蛇,经营乎其内。荡荡乎八川分流,相背而异态。东西南北,驰骛往来,出乎椒丘之阙,行乎洲淤之浦,经乎桂林之中,过乎泱漭之野。汩乎混流,顺阿而下,赴隘狭之口,触穹石,激堆埼,沸乎暴怒,汹涌澎湃。滭弗宓汩,逼侧泌瀄,横流逆折,转腾潎冽,滂濞沆溉。穹隆云桡,宛潬胶盭。逾波趋浥,涖涖下濑。批岩冲拥,奔扬滞沛。临坻注壑,瀺灂霣坠,沈沈隐隐,砰磅訇礚,潏潏淈淈,湁潗鼎沸。驰波跳沫,汩濦漂疾。悠远长怀,寂漻无声,肆乎永归。然后灏溔潢漾,安翔徐回,翯乎滈滈,东注太湖,衍溢陂池。\n\n于是乎鲛龙赤螭,䱭䲛渐离,鰅鳙鳍鮀,禺禺魼鳎,揵鳍掉尾,振鳞奋翼,潜处乎深岩,鱼鳖讙声,万物众伙。明月珠子,的皪江靡。蜀石黄碝,水玉磊砢,磷磷烂烂,采色澔汗,藂积乎其中。鸿鹔鹄鸨,鴐鹅属玉,交精旋目,烦鹜庸渠,箴疵䴔卢,群浮乎其上,泛淫泛滥,随风澹淡,与波摇荡,奄薄水渚,唼喋菁藻,咀嚼菱藕。\n\n于是乎崇山矗矗,巃嵷崔巍,深林巨木,崭岩㟥嵳,九嵕嶻嶭。南山峨峨,岩陁甗崎,摧崣崛崎。振溪通谷,蹇产沟渎,谽呀豁閕。阜陵别岛,崴磈葨廆,丘虚堀礨,隐辚郁垒,登降陁靡,陂池貏豸,沇溶淫鬻,散涣夷陆,亭皋千里,靡不被筑。揜以绿蕙,被以江蓠,糅以蘪芜,杂以留夷。布结缕,攒戾莎,揭车衡兰,槀本射干,茈姜蘘荷,葴持若荪,鲜支黄砾,蒋苎青薠,布濩闳泽,延曼太原。离靡广衍,应风披靡,吐芳扬烈,郁郁菲菲,众香发越,肸蚃布写,晻薆咇茀。\n\n于是乎周览泛观,缜纷轧芴,芒芒恍忽。视之无端,察之无涯,日出东沼,入乎西陂。其南则隆冬生长,涌水跃波。其兽则㺎旄貘嫠,沈牛麈麋,赤首圜题,穷奇象犀。其北则盛夏含冻裂地,涉冰揭河。其兽则麒麟角端,騊駼橐驼,蛩蛩驒騱,駃騠驴骡。'),
 Document(page_content='于是乎离宫别馆,弥山跨谷,高廊四注,重坐曲阁,华榱璧珰,辇道纚属,步櫩周流,长途中宿。夷嵕筑堂,累台增成,岩窔洞房,頫杳眇而无见,仰攀橑而扪天,奔星更于闺闼,宛虹扡于楯轩,青龙蚴蟉于东箱,象舆婉僤于西清,灵圄燕于闲馆,偓佺之伦,暴于南荣。醴泉涌于清室,通川过于中庭。盘石振崖,嵚岩倚倾。嵯峨磼礏,刻削峥嵘。玫瑰碧琳,珊瑚丛生,琘玉旁唐,玢豳文鳞,赤瑕驳荦,杂臿其间,晁采琬琰,和氏出焉。\n\n于是乎卢橘夏熟,黄甘橙楱,枇杷橪柿,亭奈厚朴,梬枣杨梅,樱桃蒲陶,隐夫薁棣,荅遝离支,罗乎后宫,列乎北园。貤丘陵,下平原,扬翠叶,扤紫茎,发红华,垂朱荣,煌煌扈扈,照曜钜野。沙棠栎槠,华枫枰栌,留落胥邪,仁频并闾,欃檀木兰,豫章女贞,长千仞,大连抱,夸条直畅,实叶葰楙,攒立丛倚,连卷欐佹,崔错癹骫,坑衡閜砢,垂条扶疏,落英幡纚,纷溶箾蔘,猗狔从风,藰莅卉歙,盖象金石之声,管籥之音。偨池茈虒,旋还乎后宫,杂袭累辑,被山缘谷,循阪下隰,视之无端,究之无穷。\n\n于是乎玄猨素雌,蜼玃飞鸓,蛭蜩蠼猱,獑胡豰蛫,栖息乎其间。长啸哀鸣,翩幡互经。夭蟜枝格,偃蹇杪颠。隃绝梁,腾殊榛,捷垂条,掉希间,牢落陆离,烂漫远迁。若此者数百千处。娱游往来,宫宿馆舍,庖厨不徙,后宫不移,百官备具。\n\n于是乎背秋涉冬,天子校猎。乘镂象,六玉虬,拖蜺旌,靡云旗,前皮轩,后道游。孙叔奉辔,卫公参乘,扈从横行,出乎四校之中。鼓严簿,纵猎者,河江为阹,泰山为橹,车骑雷起,殷天动地,先后陆离,离散别追。淫淫裔裔,缘陵流泽,云布雨施。生貔豹,搏豺狼,手熊罴,足壄羊,蒙鹖苏,绔白虎,被班文,跨壄马,凌三嵕之危,下碛历之坻。径峻赴险,越壑厉水。椎蜚廉,弄獬豸,格虾蛤,鋋猛氏,羂騕褭,射封豕。箭不苟害,解脰陷脑,弓不虚发,应声而倒。'),
 Document(page_content='于是乘舆弭节徘徊,翱翔往来,睨部曲之进退,览将帅之变态。然后侵淫促节,儵夐远去,流离轻禽,蹴履狡兽。轊白鹿,捷狡兔,轶赤电,遗光耀。追怪物,出宇宙,弯蕃弱,满白羽,射游枭,栎蜚遽。择肉而后发,先中而命处,弦矢分,艺殪仆。然后扬节而上浮,凌惊风,历骇猋,乘虚无,与神俱。躏玄鹤,乱昆鸡,遒孔鸾,促鵔鸃,拂翳鸟,捎凤凰,捷鹓鶵,揜焦明。道尽途殚,回车而还。消遥乎襄羊,降集乎北纮,率乎直指,晻乎反乡。蹷石阙,历封峦,过鳷鹊,望露寒,下棠梨,息宜春,西驰宣曲,濯鹢牛首,登龙台,掩细柳。观士大夫之勤略,均猎者之所得获,徒车之所轥轹,步骑之所蹂若,人臣之所蹈籍,与其穷极倦谻,惊惮詟伏,不被创刃而死者,他他籍籍,填坑满谷,掩平弥泽。\n\n于是乎游戏懈怠,置酒乎颢天之台,张乐乎轇輵之宇。撞千石之钟,立万石之虡,建翠华之旗,树灵鼍之鼓,奏陶唐氏之舞,听葛天氏之歌,千人唱,万人和,山陵为之震动,川谷为之荡波。巴渝宋蔡,淮南干遮,文成颠歌,族居递奏,金鼓迭起,铿鎗闛鞈,洞心骇耳。荆吴郑卫之声,韶濩武象之乐,阴淫案衍之音,鄢郢缤纷,激楚结风。俳优侏儒,狄鞮之倡,所以娱耳目乐心意者,丽靡烂漫于前,靡曼美色于后。若夫青琴、宓妃之徒,绝殊离俗,妖冶娴都,靓妆刻饰,便嬛绰约,柔桡嫚嫚,妩媚纤弱。曳独茧之褕绁,眇阎易以恤削,便姗嫳屑,与俗殊服,芬芳沤郁,酷烈淑郁;皓齿粲烂,宜笑的皪;长眉连娟,微睇绵藐,色授魂与,心愉于侧。\n\n于是酒中乐酣,天子芒然而思,似若有亡,曰:“嗟乎!此大奢侈。朕以览听馀闲,无事弃日,顺天道以杀伐,时休息于此。恐后叶靡丽,遂往而不返,遂往而不返,非所以为继嗣创业垂统也。\n\n于是乎乃解酒罢猎,而命有司曰:“地可垦辟,悉为农郊,以赡萌隶,隤墙填堑,使山泽之人得至焉。实陂池而勿禁,虚宫馆而勿仞,发仓廪以救贫穷,补不足,恤鳏寡,存孤独,出德号,省刑罚,改制度,易服色,革正朔,与天下为更始。'),
 Document(page_content='于是历吉日以斋戒,袭朝服,乘法驾,建华旗,鸣玉鸾,游于六艺之囿,驰骛乎仁义之涂,览观《春秋》之林,射《狸首》,兼《驺虞》,弋玄鹤,舞干戚,载云䍐,揜群雅,悲《伐檀》,乐乐胥,修容乎礼园,翱翔乎书圃,述《易》道,放怪兽,登明堂,坐清庙,次群臣,奏得失,四海之内,靡不受获。于斯之时,天下大说,乡风而听,随流而化,卉然兴道而迁义,刑错而不用,德隆于三王,而功羡于五帝。若此故猎,乃可喜也。若夫终日驰骋,劳神苦形,罢车马之用,抏士卒之精,费府库之财,而无德厚之恩,务在独乐,不顾众庶,亡国家之政,贪雉兔之获,则仁者不由也。从此观之,齐楚之事,岂不哀哉!地方不过千里,而囿居九百,是草木不得垦辟,而人无所食也。夫以诸侯之细,而乐万乘之侈,仆恐百姓被其尤也。\n\n于是二子愀然改容,超若自失,逡巡避席,曰:“鄙人固陋,不知忌讳,乃今见教,谨受命矣。”')]
# 使用其中一个Chroma 组件作为例子
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.text_splitter import CharacterTextSplitter
from langchain.vectorstores import Chroma

# pku.txt内容:<https://www.pku.edu.cn/about.html>
with open('./pku.txt', encoding='utf-8') as f:
    state_of_the_union = f.read()
text_splitter = CharacterTextSplitter(chunk_size=100, chunk_overlap=0)
texts = text_splitter.split_text(state_of_the_union)

embeddings = OpenAIEmbeddings()

docsearch = Chroma.from_texts(texts, embeddings)

query = "1937年北京大学发生了什么?"
docs = docsearch.similarity_search(query, k=1)  # 返回与查询最相似的文档列表, k限制个数
docs
[Document(page_content='1937年卢沟桥事变后,北京大学与清华大学、南开大学南迁长沙,共同组成国立长沙临时大学。1938年,临时大学又西迁昆明,更名为国立西南联合大学。抗日战争胜利后,北京大学于1946年10月在北平复员。')]
from langchain.document_loaders import TextLoader
from langchain.text_splitter import CharacterTextSplitter
from langchain.vectorstores import FAISS
from langchain.embeddings import OpenAIEmbeddings

loader = TextLoader('./HUAWEI_MATE60_PRO.txt', encoding='utf-8')
documents = loader.load()
text_splitter = CharacterTextSplitter(chunk_size=50, chunk_overlap=0, separator="\n")
texts = text_splitter.split_documents(documents)
embeddings = OpenAIEmbeddings()
db = FAISS.from_documents(texts, embeddings)
# db = FAISS.from_documents(documents, embeddings)
retriever = db.as_retriever()
docs = retriever.get_relevant_documents("HUAWEI Mate 60 Pro是什么时候上架的?")  # 返回与查询相关的文档列表
docs[0]  # 最相关答案
Document(page_content='HUAWEI Mate 60 Pro是华为技术有限公司于2023年8月29日上架的一款智能手机, 前代产品为2022年9月6日发布的HUAWEI Mate 50 Pro。', metadata={'source': './HUAWEI_MATE60_PRO.txt'})
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值