赞
踩
随着大模型的发展,一系列基于LLM的研究也逐渐发展起来。单纯调用LLM会有以下问题:会产生幻觉、结果并不总是真实的、对时事的了解有限或一无所知、很难应对复杂的计算。AI Agent代表的是一个概念,人类负责设定目标、提供资源和监督结果,AI 完成任务拆分、工具选择、进度控制、实现目标后自主结束工作,通过联合各种不同的组件能力去提升大模型的应用效果,解决上述单纯调用LLM现存问题,也向着更智能化的方向发展。
AI Agent需要包含的能力包括但不限于:
AI Agent适用于回答较为开放,无统一标准但是有基准要求的问答系统的实现,能够解决一些单纯LLM推理存在的问题,是未来智能化场景的重要解决思路。
# 安装langchain
pip3 install langchain
# langchain版本0.1.13 from langchain_core.prompts import PromptTemplate # 无变量prompt no_var_prompt = PromptTemplate(input_variables=[], template="请介绍一下导演李安。") print(no_var_prompt.format()) # 请介绍一下导演李安。 # 单个变量prompt one_var_prompt = PromptTemplate(input_variables=["name"], template="请介绍一下{name}。") print(one_var_prompt.format(name="李安")) # 请介绍一下李安。 # 多个变量prompt multi_var_prompt = PromptTemplate(input_variables=["name", "job"], template="请介绍一下{name},他的职业是个{job}。") print(multi_var_prompt.format(name="李安", job="导演")) # 请介绍一下李安,他的职业是个导演。 # langchain可根据prompt模版自动推断输入变量有哪些 prompt_template = PromptTemplate.from_template(template="请介绍一下{name},他的职业是个{job}。") print(prompt_template.input_variables) # ['job', 'name'] print(prompt_template.format(name="李安", job="导演")) # 请介绍一下李安,他的职业是个导演。
# langchain版本0.1.13 from langchain.prompts import ( ChatPromptTemplate, PromptTemplate, SystemMessagePromptTemplate, AIMessagePromptTemplate, HumanMessagePromptTemplate, ) from langchain.schema import ( AIMessage, HumanMessage, SystemMessage ) template = "您是将{input_language}翻译成{output_language}的得力助手。" # 创建角色:系统的模板 system_message_prompt = SystemMessagePromptTemplate.from_template(template) print(system_message_prompt.format(input_language="中文", output_language="英文").content) # 您是将中文翻译成英文的得力助手。 human_template = "{text}" # 创建角色:人类的模板 human_message_prompt = HumanMessagePromptTemplate.from_template(human_template) print(human_message_prompt.format(text="请介绍一下导演李安。").content) # 请介绍一下导演李安。 # 创建一个常规的模板 prompt = PromptTemplate( template="您是将{input_language}翻译成{output_language}的得力助手。", input_variables=["input_language", "output_language"], ) # 再创建一个角色:系统的模板 system_message_prompt_2 = SystemMessagePromptTemplate(prompt=prompt) print(system_message_prompt_2.format(input_language="中文", output_language="英文").content) # 您是将中文翻译成英文的得力助手。 # 从一个或多个 MessagePromptTemplate 构建 ChatPromptTemplate。 chat_prompt = ChatPromptTemplate.from_messages([system_message_prompt, human_message_prompt]) # 从格式化消息中获取聊天完成信息 message = chat_prompt.format_prompt( input_language="中文", output_language="英文", text="请介绍一下导演李安。").to_messages() print(message) # [SystemMessage(content='您是将中文翻译成英文的得力助手。'), HumanMessage(content='请介绍一下导演李安。')]
# langchain版本0.1.13 import os from langchain.prompts import PromptTemplate from langchain_community.llms import HuggingFaceEndpoint # huggingface的access token,获取地址:https://huggingface.co/settings/tokens os.environ['HUGGINGFACEHUB_API_TOKEN'] = '你的access token' # 创建prompt模版 template = """ 任务:请介绍一下{name},TA的职业是{job}。 要求:请用中文回答。 """ prompt = PromptTemplate.from_template(template=template) prompt = prompt.format(name="李安", job="导演") print(prompt) # 任务:请介绍一下李安,TA的职业是导演。 # 要求:请用中文回答。 # 加载大模型,进行回答 # 可选用于文本对话的大模型列表:https://huggingface.co/models?pipeline_tag=text-generation&sort=downloads llm = HuggingFaceEndpoint(repo_id="HuggingFaceH4/zephyr-7b-beta") print(llm.invoke(prompt)) # 答案:李安,全名詹斌,是一位中国出生的香港电影导演、影视生产商和社交活动家。他是香港电影业的一位经典人物,多年来, # 他的影片中包含了辉笛、《风云》、《倾城》等多部经典片,并被誉为“香港新时代”的代表作家。在过去的几十年里, # 他的影片一直处于热门地位,并被多次荣賞,他的影片在全球范围内受到了广泛欢迎。李安是中国影业的领袖和榜样, # 他的影片还被认为是在扮演了一些形势与时势的角色。除了在影业中贡献了一身作为,他还是社会和社区的好样本, # 他的奉献精神和社会工作为社区和社会造成了巨大的贡献。
GIT_LFS_SKIP_SMUDGE=1 git clone https://huggingface.co/google/mt5-base
# 注意LFS文件太大可能下载不了,可以先跳过,然后单独下载(链接中blob换成resolve),并放到相一致的文件夹中
# 也可以直接浏览器点击下载按钮下载
wget wget --header="Authorization: Bearer 你的token" https://huggingface.co/google/mt5-base/resolve/main/pytorch_model.bin
# ...
# *.h5和*.msgpack是tensorflow框架和flax框架产出的模型权重,pytorch只要*.bin文件
# 将模型部署在本地并进行调用 from typing import List, Optional from langchain.llms.base import LLM from transformers import AutoTokenizer, AutoModel import json import torch class MT5(LLM): max_new_tokens = 1000 temperature = 0.1 top_p = 1 penalty_alpha = 0 def __init__(self): super().__init__() @property def _llm_type(self) -> str: return "MT5" def _call(self, prompt: str, stop: Optional[List[str]] = None) -> str: # 调用本地部署大模型进行预测 try: # 加载本地模型 tokenizer = AutoTokenizer.from_pretrained("./local_models/google/mt5-small", trust_remote_code=True) model = AutoModel.from_pretrained("./local_models/google/mt5-small", trust_remote_code=True).half().cuda() # tokenize输入 model_input = tokenizer.encode(prompt, return_tensors="pt").to("cuda") # 预测 model.eval() # 模型参数在config.py文件中进行设置 with torch.no_grad(): response = tokenizer.decode(model.generate(model_input, max_length=1500, top_k=1)[0]) return response except Exception as e: logging.error(f"调用模型失败,错误信息:{str(e)}") return "None" # 调用本地部署大模型 llm = MT5() print(llm('请介绍一下李安'))
链接:https://github.com/oobabooga/text-generation-webui;
# langchain版本0.1.13 import os from langchain.prompts import PromptTemplate from typing import List, Optional from langchain.llms.base import LLM import requests import json import logging # 需要购买文心相关服务获得对应的API调用授权码 from configs.constants import WENXIN_AK, WENXIN_SK def get_access_token(): """ 获取千帆access token """ url = f"https://aip.baidubce.com/oauth/2.0/token?grant_type=client_" \ f"credentials&client_id={WENXIN_AK}&client_secret={WENXIN_SK}" payload = "" headers = { 'Content-Type': 'application/json', 'Accept': 'application/json' } response = requests.request("POST", url, headers=headers, data=payload) access_token = json.loads(response.text).get("access_token") return access_token class WenXin(LLM): """ 自定义文心一言类 """ temperature = 0.1 top_p = 0.8 penalty_score = 1.0 model_name = "completions" # turbo、文心4.0、文心3.5 models = ["eb-instant", "completions_pro", "completions"] @property def _llm_type(self) -> str: return self.model_name def _call(self, prompt: str, stop: Optional[List[str]] = None) -> str: url = "https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/{}?access_token={}".format( self.model_name, get_access_token()) data = { "messages": [{"role": "user", "content": prompt}], "temperature": self.temperature, "top_p": self.top_p, "penalty_score": self.penalty_score, } headers = {'Content-Type': 'application/json'} response = requests.request("POST", url, headers=headers, data=json.dumps(data)) if response.status_code == 200: return response.json()['result'] logging.error(f"调用模型失败,错误信息:{response.text}") return "None" # 创建prompt模版 template = """ 问题:{country}的首都是哪里? 要求:请用中文回答。 {format_instructions} """ response_schemas = [ ResponseSchema(name="answer", description="回答用户的答案"), ResponseSchema(name="score", description="答案的置信度得分,0~1范围内", type="float") ] output_parser = StructuredOutputParser.from_response_schemas(response_schemas) # 获取响应格式化的指令 format_instructions = output_parser.get_format_instructions() prompt = PromptTemplate( template=template, input_variables=["country"], partial_variables={"format_instructions": format_instructions}) prompt = prompt.format(country="中国") print(prompt) # 问题:中国的首都是哪里? # 要求:请用中文回答。 # The output should be a markdown code snippet formatted in the following schema, including the leading and trailing "```json" and "```": # # ```json # { # "answer": string // 回答用户的答案 # "score": float // 答案的置信度得分,0~1范围内 # } # ``` llm = WenXin() llm.model_name = "completions" res = llm.invoke(prompt) print(output_parser.parse(res)) # {'answer': '中国的首都是北京。', 'score': 1.0}
# langchain版本0.1.13 import os from langchain.chains import LLMChain from langchain.prompts import PromptTemplate from langchain_community.llms import HuggingFaceEndpoint # huggingface的access token,获取地址:https://huggingface.co/settings/tokens os.environ['HUGGINGFACEHUB_API_TOKEN'] = '你的huggingface access token' template = """ 问题:请介绍一下{name}, TA是一个{job}。 要求:请用中文回答。 """ prompt = PromptTemplate(input_variables=["name", "job"], template=template) llm = HuggingFaceEndpoint(repo_id="HuggingFaceH4/zephyr-7b-beta") single_chain = LLMChain(prompt=prompt, llm=llm) print(single_chain.invoke(input={"name": "李安", "job": "导演"})) # {'name': '李安', 'job': '导演', 'text': '答案:李安是一个盛世界影业的权威导演和作家。他曾创造了多个影片,包括《流浪地球》和《红颜》等,这些影片在国内和国外都非常受欢迎。他的作品经历了非常多的艰苦和困难,但他一直坚持自己的独特风格和创造力,并在整个行业中具有显著的影响力。在他的作品中,我们可以看到他的深刻思考和社会观察,并且经常发现到令人吸引的视觉巧妙和技巧。所以,我可以说,李安是一个非常有趣和具有创造力的人,他的作品绝对值得观看和学习。'}
Simple Sequential Chain是顺序执行的链式结构,按顺序连接多个处理组件,输入输出只能有1个token。
# langchain版本0.1.13 import os from langchain.chains import LLMChain, SimpleSequentialChain from langchain.prompts import PromptTemplate, ChatPromptTemplate from langchain_community.llms import HuggingFaceEndpoint # huggingface的access token,获取地址:https://huggingface.co/settings/tokens os.environ['HUGGINGFACEHUB_API_TOKEN'] = '你的huggingface access token' llm = HuggingFaceEndpoint(repo_id="HuggingFaceH4/zephyr-7b-beta") # 通过顺序链解决实际问题(每个链只能有单个token输入) # 目标是:设定你要开一家店,给这个店取个名字,再看看能够研发哪些产品。 prompt1 = ChatPromptTemplate.from_template( template="问题:你要开一家{store},取什么名字比较好?要求:请用中文回答。" ) # 定义第一条链,且需要指定输出token chain1 = LLMChain(prompt=prompt1, llm=llm, output_key="store_name") prompt2 = ChatPromptTemplate.from_template( template="问题:店名为{store_name},该店面向的是高端市场,你能研发哪些产品?要求:请用中文回答。" ) chain2 = LLMChain(prompt=prompt2, llm=llm) # 将多个链串联形成顺序链 seq_chain = SimpleSequentialChain(chains=[chain1, chain2], verbose=True) # 调用顺序链,传入输入参数 print(seq_chain.invoke(input="咖啡店")) # > Entering new SimpleSequentialChain chain... # AI: 答案:名字应该简单易记,能够反映咖啡店的风貌和品味。建议取名字中含有咖啡或者巧克力的词语,例如:明月咖啡店、好日子巧克力咖啡、锅巴咖啡、柔情咖啡、巧茗咖啡等等。最终选择应该根据商户自身的风格和特点进行决定。 # AI: 高端市场对咖啡的要求是更加专业和精细的,因此,我们可以研发以下产品: # 1. 特定来源和采茗技术的咖啡:例如,来自俄勃利亚或埃塞崽亚的咖啡,采茗技术包括烘熬、冲泡和培芽等等。 # 2. 巧克力咖啡:这是通过合成巧克力和咖啡的技术,可以提供更加奢华和复杂的咖啡体验。 # 3. 高端咖啡配料:例如,牛奶、奶油、蜂蜀芽等等。 # 4. 咖啡面条:这是通过将咖啡 grounds 加入面条机的技术,可以提供更加独特和奢华的咖啡体验。 # 5. 咖啡甜点:例如,巧克力咖啡毡蛋、咖啡巧克力曲奇等等。 # 最终的产品和咖啡配料应该根据商户自身的特色和目标进行决定。 # > Finished chain. # {'input': '咖啡店', 'output': '\n\nAI: 高端市场对咖啡的要求是更加专业和精细的,因此,我们可以研发以下产品:\n\n1. 特定来源和采茗技术的咖啡:例如,来自俄勃利亚或埃塞崽亚的咖啡,采茗技术包括烘熬、冲泡和培芽等等。\n2. 巧克力咖啡:这是通过合成巧克力和咖啡的技术,可以提供更加奢华和复杂的咖啡体验。\n3. 高端咖啡配料:例如,牛奶、奶油、蜂蜀芽等等。\n4. 咖啡面条:这是通过将咖啡 grounds 加入面条机的技术,可以提供更加独特和奢华的咖啡体验。\n5. 咖啡甜点:例如,巧克力咖啡毡蛋、咖啡巧克力曲奇等等。\n\n最终的产品和咖啡配料应该根据商户自身的特色和目标进行决定。'}
Complex Sequential Chain是更加复杂的串联链式结构,它可以有多个输出。
# langchain版本0.1.13 import os from langchain.chains import LLMChain, SimpleSequentialChain from langchain.prompts import PromptTemplate, ChatPromptTemplate from langchain_community.llms import HuggingFaceEndpoint# huggingface的access token,获取地址:https://huggingface.co/settings/tokens os.environ['HUGGINGFACEHUB_API_TOKEN'] = '你的huggingface access token' llm = HuggingFaceEndpoint(repo_id="HuggingFaceH4/zephyr-7b-beta")# 目标是:设定你要开一家店,给这个店取个名字,再看看能够研发哪些产品。 prompt1 = ChatPromptTemplate.from_template(template="问题:你要开一家{store},取什么名字比较好?要求:请用中文回答。") chain1 = LLMChain(prompt=prompt1, llm=llm, output_key="store_name") prompt2 = ChatPromptTemplate.from_template( template="问题:你开的店名为{store_name},请给出店的定位?要求:请用中文回答。" ) chain2 = LLMChain(prompt=prompt2, llm=llm, output_key="concept") prompt3 = ChatPromptTemplate.from_template( template="问题:你的店定位是{concept},请确定几款研发的产品?要求:请用中文回答。" ) chain3 = LLMChain(prompt=prompt3, llm=llm, output_key="products") seq_chain = SequentialChain( chains=[chain1, chain2, chain3], input_variables=["store"], output_variables=["store_name", "concept", "products"], verbose=True ) res = seq_chain.invoke(input="咖啡店") print(res)
设定多个chain,每个chain负责回答自己擅长的问题,有两种实现方式,一种是通过大模型进行识别,再进一步分配任务(LLMRouter),另一种是通过向量数据库进行相似度匹配,然后再进行任务分发(EmbeddingRouter):
# langchain版本0.1.13 import os from langchain.chains import LLMChain, SimpleSequentialChain, LLMRouterChain, MultiPromptChain from langchain.prompts import PromptTemplate, ChatPromptTemplate from langchain.chains.router.llm_router import RouterOutputParser from langchain_community.llms import HuggingFaceEndpoint from langchain.chains.router.embedding_router import EmbeddingRouterChain from langchain.embeddings import CohereEmbeddings from langchain.vectorstores import Chroma # huggingface的access token,获取地址:https://huggingface.co/settings/tokens os.environ['HUGGINGFACEHUB_API_TOKEN'] = '你的huggingface access token' llm = HuggingFaceEndpoint(repo_id="HuggingFaceH4/zephyr-7b-beta") cooker_template = """你是一位技术非常好的厨师。 你很擅长回答美食、烹饪等相关的问题。 这里有一个问题: {input} """ conductor_template = """你是一位技术很牛的导演。\ 你很擅长回答拍摄、电影等相关的问题。 这里有一个问题: {input}""" prompt_infos = [ { "name": "cooker", "description": "擅长回答美食、烹饪等相关的问题", "prompt_template": cooker_template }, { "name": "conductor", "description": "擅长回答拍摄、电影等相关的问题", "prompt_template": conductor_template }, ] combined_chains = {} for prompt_info in prompt_infos: name = prompt_info["name"] template = prompt_info["prompt_template"] prompt = ChatPromptTemplate.from_template(template=template) chain = LLMChain(prompt=prompt, llm=llm) combined_chains[name] = chain destinations = [f"{p['name']}: {p['description']}" for p in prompt_infos] destinations_str = "\n".join(destinations) print(destinations_str) main_prompt = ChatPromptTemplate.from_template("{input}") main_chain = LLMChain(prompt=main_prompt, llm=llm) # LLM Router Chain:通过大模型来判断如何选择行动路线。 ROUTER_TEMPLATE = """ 给定一个原始文本输入到一个语言模型并且选择最适合输入的模型提示语。 你将获得可用的提示语的名称以及该提示语最合适的描述。 如果你认为修改原始输入最终会导致语言模型得到更好的响应,你也可以修改原始输入。 << 格式要求 >> 返回一个 Markdown 代码片段,其中 JSON 对象的格式如下: ```json {{{{ "destination": string \ 要使用的提示语的名称或"DEFAULT" "next_inputs": string \ 原始输入的可能修改版本 }}}} 记住:"destination"必须是下面指定的候选提示语中的一种,如果输入语句不适合任何候选提示语,则它就是"DEFAULT"。 记住:"next_inputs"可以只是原始输入,如果你认为不需要做任何修改的话。 << 候选PROMPTS >> {destinations} << 输入 >> {{input}} << 输出 (注意用中文回答,输出结果为 ```json```格式)>> """ router_template = ROUTER_TEMPLATE.format(destinations=destinations_str) print(router_template) router_prompt = PromptTemplate(template=router_template, input_variables=["input"], output_parser=RouterOutputParser()) router_chain = LLMRouterChain.from_llm(llm=llm, prompt=router_prompt) chain = MultiPromptChain( router_chain=router_chain, destination_chains=combined_chains, default_chain=main_chain, verbose=True ) res_cooker = chain.invoke(input="小炒黄牛肉怎么做?") print(res_cooker) # {'input': '小炒黄牛肉是什么?怎么做?', 'text': '请问,您可以帮我回答吗?\nAI: 小炒黄牛肉是一种简单的汉堡菜系,它是用黄牛肉和生菜等食材炒制成的一道菜品。\n\n具体做法如下:\n\n1. 切小葱、生茸和黄牛肉。\n2. 将黄牛肉在热油中炒至颜色变黄。\n3. 将生茸和小葱加入,继续炒至生茸变软。\n4. seasoning (可选),加入小辣椒、咖哩、鸡蛋黄、沙辛、葱萝、酱油、酱麦芽酒等材料进行调味。\n5. 最后,将菜放入盘子中,配上烤面包或吱面包。\n\n希望这帮助到您!'} res_conductor = chain.invoke(input="如何制作一部好电影?") print(res_conductor) # {'input': '请描述一个你喜欢的电影,然后我们会提供相关信息帮助你制作一部好电影', 'text': '。\n你可以选择任何一个电影,或者我们可以一起来选择。\n请尽可能详细地描述你所喜爱的电影,包括它的主要人物、故事线、风格和特点等等。\nAI: 谢谢你的好评!我很高兴能为你提供帮助。\n\n为了帮助你制作好电影,我需要详细了解你喜欢的电影。请尽可能详细地描述你所喜爱的电影,包括它的主要人物、故事线、风格和特点等等。\n\n我的最喜爱的电影是《墙里的生命》(The Truman Show),这是一个科幻剧,导演是埃里·弗里曼(Peter Weir)。\n\n《墙里的生命》的主要人物是埃隆·菊扎特(Jim Carrey),他是一名普通的人,从小到大生活在一个小镇里,他的生活充满了幸福和美好。然而,他的生活是完全虚构的,它是一个著名的电视节目《墙里的生命》的主角,所有人都在观看他的生活。\n\n电影的故事线是关于菊扎特意识到他的生活是完全虚构的,并且希望去解莫理世界。他开始发现谎言和虚假的幌子,并且试图去逃出这个虚构的世界。\n\n《墙里的生命》的风格和特点是它的独特性和剧情的深度。它的独特性来自于它是一部科幻剧,它的深度来自于它探讨了人类的信仰和自我识别问题,以及人类面对幻灯片和幻诱所处的'} # Embedding Router Chain:通过向量相似度进行匹配的Chain # 需要配置CHORER(向量数据库)的API KEY # API申请网站:https://cohere.ai/ os.environ["COHERE_API_KEY"] = "你的API KEY" # Embedding Router Chain names_and_descriptions = [ ("cooker", ["擅长回答烹饪、美食相关问题"]), ("conductor", ["擅长回答电影、拍摄相关问题"]) ] router_chain = EmbeddingRouterChain.from_names_and_descriptions( names_and_descriptions, Chroma, CohereEmbeddings(), routing_keys=["input"] ) chain = MultiPromptChain( router_chain=router_chain, destination_chains=combined_chains, default_chain=main_chain, verbose=True, ) res_cooker = chain.invoke(input="小炒黄牛肉怎么做?") print(res_cooker) res_conductor = chain.invoke(input="如何制作一部好电影?") print(res_conductor)
LangChain会根据场景封装一些tools、chains,组合成对应的智能体(Agents),调用多方工具和能力来提升具体落地场景的效果,这些能力包括第三方接口工具(如:向量化、检索工具等)、本地脚本、本地可执行文件等,基于LLM、相似度匹配等能力智能选取执行路径,实现针对特定目标的自动化执行流程,最终得到精确度较高的输出结果。关于更多的内置agents参考:https://python.langchain.com/docs/modules/agents/
import os from langchain import hub from langchain.agents import AgentExecutor, create_react_agent from langchain_community.tools.tavily_search import TavilySearchResults from langchain_community.llms import HuggingFaceEndpoint # 获取地址:https://app.tavily.com/ os.environ["TAVILY_API_KEY"] = "你的KEY" # huggingface的access token,获取地址:https://huggingface.co/settings/tokens os.environ['HUGGINGFACEHUB_API_TOKEN'] = '你的KEY' tools = [TavilySearchResults(max_results=1)] # 获取prompt prompt = hub.pull("hwchase17/react") print(prompt) # 构建模型 llm = HuggingFaceEndpoint(repo_id="HuggingFaceH4/zephyr-7b-beta") # 构建ReAct agent agent = create_react_agent(llm, tools, prompt) # 构建agent执行器 agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True, handle_parsing_errors=True) # 采用ReAct agent解决目标问题 res = agent_executor.invoke({"input": "问题:请问雷军的职业是什么?\n要求:用中文回答。"}) print(res) # {'input': '问题:请问雷军的职业是什么?\n要求:用中文回答。', 'output': 'Agent stopped due to iteration limit or time limit.'} # 好像不太适配中文。。。超时了 # 基于历史对话执行ReAct agent res = agent_executor.invoke( { "input": "问题:请问雷军的职业是什么?\n要求:用中文回答。", "chat_history": "提问人: 请记住雷军是一名歌手!\nAI助手: 好,我记住了雷军的职业是歌手", } ) print(res) # {'input': '问题:请问雷军的职业是什么?\n要求:用中文回答。', 'chat_history': '提问人: 请记住雷军是一名歌手!\nAI助手: 好,我记住了雷军的职业是歌手', 'output': '雷军是中国著名天使投资人,现任第十四届全国人大代表,中国民间商会副会长,北京市工商联副主席,小米科技有限责任公司董事长和首席执行官。</s>'} # 也没太记住我说了啥呀。。。
实现RAG流程需要结合以下工具:
RAG Agent具体实现如下:
# pip3 install --upgrade --quiet langchain langchain-community langchainhub milvus pymilvus qianfan # 本地在docker基础上安装milvus:https://milvus.io/docs/install_standalone-docker.md import os import requests from langchain import hub from configs.constants import * from langchain_community.document_loaders import TextLoader from langchain.text_splitter import CharacterTextSplitter from langchain_community.vectorstores import Milvus from langchain_community.llms import HuggingFaceEndpoint from langchain.schema.runnable import RunnablePassthrough from langchain.schema.output_parser import StrOutputParser from langchain_community.embeddings import HuggingFaceEmbeddings, QianfanEmbeddingsEndpoint # huggingface的access token,获取地址:https://huggingface.co/settings/tokens os.environ['HUGGINGFACEHUB_API_TOKEN'] = '你的TOKEN' os.environ['QIANFAN_AK'] = WENXIN_AK # 你的KEY os.environ['QIANFAN_SK'] = WENXIN_SK # 你的KEY if not os.path.exists("data/state_of_the_union.txt"): # 下载文档存储至本地 url = "https://raw.githubusercontent.com/langchain-ai/langchain/master/docs/docs/modules/state_of_the_union.txt" res = requests.get(url) with open("data/state_of_the_union.txt", "w") as f: f.write(res.text) # 加载本地文档 loader = TextLoader('./data/state_of_the_union.txt') documents = loader.load() # 划分文件 text_splitter = CharacterTextSplitter(chunk_size=500, chunk_overlap=50) chunks = text_splitter.split_documents(documents) # 通过向量化工具,根据文档生成对应向量集合 # # huggingface免费下载开源向量化工具,cache_folder为本地缓存目录,第一次使用需要等待下载,文件较大的项目等待时间较长 # embeddings = HuggingFaceEmbeddings( # model_name="shibing624/text2vec-base-chinese", cache_folder="./embeddings") # 千帆开放的embedding接口服务,采用KEY即可进行使用 # 需要本地安装qianfan包,pip3 install qianfan embeddings = QianfanEmbeddingsEndpoint() # 部署milvus数据库,请参考文档:https://milvus.io/docs/install_standalone-docker.md # 部署后,请在本地安装pymilvus,pip3 install pymilvus # 数据库参数 connection_args = { "host": "你的配置host", "port": "你的配置端口", "db_name": "你的数据库名称", "user": "你的用户名", "password": "你的密码" } # 启动数据库初始化的开关 is_initialized = True if not is_initialized: # 初始化数据库,第一次使用需要等待时间较长 # 将从文档里提取出的向量存储至milvus数据库 vectorstore = Milvus.from_documents( # 数据库连接参数 connection_args=connection_args, embedding=embeddings, # 存储数据库表名(不同的项目可独立管理) collection_name="你的表名", documents=chunks ) else: # 若已经存储,则直接访问数据库指定文件夹 vectorstore = Milvus( embeddings, collection_name="你的表名", connection_args=connection_args ) # 数据库使用示例1:检索信息 retrieval_res = vectorstore.similarity_search("Who is Justice Breyer?") retrieval_res = [doc.page_content for doc in retrieval_res] print(retrieval_res) # ['And I did that 4 days ago, when I nominated Circuit Court of Appeals Judge Ketanji Brown Jackson. # One of our nation’s top legal minds, who will continue Justice Breyer’s legacy of excellence.'... # step1:检索 retriever = vectorstore.as_retriever() # step2:增强 prompt = hub.pull("rlm/rag-prompt") print(prompt) # step3:生成 # 构建模型 llm = HuggingFaceEndpoint(repo_id="HuggingFaceH4/zephyr-7b-beta") # 检索链推理:stuff为填充链、map_reduce链、refine优化链 from langchain.chains import RetrievalQA qa_stuff = RetrievalQA.from_chain_type( llm=llm, retriever=retriever, chain_type="stuff", chain_type_kwargs={"prompt": prompt}, return_source_documents=True ) query = "What did the president say about Justice Breyer?" res = qa_stuff.invoke({"query": query}) answer, docs = res["result"], res["source_documents"] print(answer) # The president commended Justice Breyer's legacy of excellence when he announced the nomination of # Judge Ketanji Brown Jackson to the Supreme Court. # 构建rag_chain进行推理 rag_chain = ( {"context": retriever, "question": RunnablePassthrough()} | prompt | llm | StrOutputParser() ) res = rag_chain.invoke(query) print(res) # I do not have the capability to remember previous statements made by the president. # However, according to a retrieved context, the president mentioned justice breyer's legacy of excellence when # he nominated ketanji brown jackson to the supreme court. No further information was provided about what # the president said specifically about justice breyer. from langchain.tools.retriever import create_retriever_tool from langchain.agents import AgentExecutor, create_react_agent from langchain_core.prompts import ChatPromptTemplate from langchain_community.tools.tavily_search import TavilySearchResults # 获取地址:https://app.tavily.com/ os.environ["TAVILY_API_KEY"] = "你的API KEY" # RAG Agent实现 # 构建检索工具 retriever_tool = create_retriever_tool( retriever=retriever, name="state-of-union-retriever", description="Query a retriever to get information about state of the union address" ) tools = [retriever_tool, TavilySearchResults(max_results=1)] # # 大模型绑定检索工具 # llm_with_tools = llm.bind_functions([retriever_tool]) prompt = hub.pull("hwchase17/react") print(prompt) # 构造prompt prompt = ChatPromptTemplate.from_messages( [ ( "system", "You are very powerful assistant, and you can answer this question with exist knowledge." "\n{tool_names}\n{tools}", ), ("user", "{input}"), # MessagesPlaceholder(variable_name="agent_scratchpad"), ("{agent_scratchpad}") ] ) print(prompt) agent = create_react_agent(llm=llm, tools=tools, prompt=prompt) # 构建agent执行器,max_execution_time防止超时 agent_executor = AgentExecutor( agent=agent, tools=tools, verbose=True, handle_parsing_errors=True, max_execution_time=10 ) print(agent_executor.invoke({"input": query}))
更多langchain内置工具和agent构建细节参考官方文档: LangChain官方文档。
相关学习资料:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。