├── 00_开篇词_奇点时刻 ├── 01_简单文本生成.py └── 02_看图说话.py ├── 01_LangChain快速入门 ├── 01_TextModel.py ├── 02_ChatModel.py ├── 03_TextLangChain.py ├── 03_TextLangChain_v0.2.py ├── 04_ChatLongChain.py └── 04_ChatLongChain_v0.2.py ├── 02_文档QA系统 ├── DocQA_v0.1.py ├── DocQA_v0.2.py ├── OneFlower │ ├── 易速鲜花员工手册.pdf │ ├── 易速鲜花运营指南.docx │ └── 花语大全.txt ├── static │ └── flower.png └── templates │ └── index.html ├── 03_模型IO ├── 01_模型IO.py ├── 02_模型IO_循环调用.py ├── 03_OpenAI_IO.py ├── 04_模型IO_HuggingFace.py ├── 05_模型IO_输出解析.py └── flowers_with_descriptions.csv ├── 04_提示模板上 ├── 00_ImportTemplates.py ├── 01_PromptTemplate.py ├── 02_ChatPromptTemplate.py └── 03_FewShotPrompt.py ├── 05_提示模板下 └── CoT.py ├── 06_调用模型 ├── 01_HugggingFace_Llama.py ├── 02_LangChain_HFHub.py ├── 03_LangChain_HFPipeline.py └── 04_LangChain_CustomizeModel.py ├── 07_解析输出 ├── 01_Pydantic_Parser.py ├── 02_OutputFixParser.py └── 03_RetryParser.py ├── 08_链上 ├── 01_Without_Chain.py ├── 02_With_LLMChain.py ├── 03_Running_Chain.py └── 04_SequentialChain.py ├── 09_链下 └── Rounter_Chain.py ├── 10_记忆 ├── 01_ConversationChain.py ├── 02_ConversationBufferMemory.py ├── 03_ConversationBufferWindowMemory.py ├── 04_ConversationSummaryMemory.py └── 05_ConversationSummaryBufferMemory.py ├── 11_代理上 └── ReActAgent.py ├── 12_代理中 └── ReActAgent_with_Debug.py ├── 13_代理下 ├── Plan&Execute.py ├── SelfAskwithSearch.py └── StructedToolChat.py ├── 14_工具 ├── 01_arxiv.py ├── 02_GmailToken.py └── 03_GmailToolkit.py ├── 15_RAG应用 ├── 01_Embedding.py ├── 02_InMemoryStore.py └── 03_VectorstoreIndex.py ├── 16_操作数据库 ├── 01_DBCreation.py ├── 02_SQL_LLM.py └── 03_SQL_Agent.py ├── 17_回调函数 ├── 01_Callback.py ├── 02_Async_Callback.py ├── 03_LangChainOpenAICallback.py └── 04_LangChainCustomCallback.py ├── 18_CAMEL └── CAMEL_CN.py ├── 19_BabyAGI └── BabyAGI_CN.py ├── 20_人脉工具上 ├── socializer_v1 │ ├── agents │ │ ├── __pycache__ │ │ │ └── weibo_agent.cpython-311.pyc │ │ └── weibo_agent.py │ ├── findbigV.py │ └── tools │ │ ├── __pycache__ │ │ ├── general_tool.cpython-311.pyc │ │ └── search_tool.cpython-311.pyc │ │ ├── general_tool.py │ │ └── search_tool.py └── socializer_v2 │ ├── agents │ ├── __pycache__ │ │ └── weibo_agent.cpython-311.pyc │ └── weibo_agent.py │ ├── findbigV.py │ └── tools │ ├── __pycache__ │ ├── general_tool.cpython-311.pyc │ ├── scraping_tool.cpython-311.pyc │ └── search_tool.cpython-311.pyc │ ├── general_tool.py │ ├── scraping_tool.py │ └── search_tool.py ├── 21_人脉工具下 ├── socializer_v3 │ ├── agents │ │ ├── __pycache__ │ │ │ └── weibo_agent.cpython-311.pyc │ │ └── weibo_agent.py │ ├── findbigV.py │ └── tools │ │ ├── __pycache__ │ │ ├── general_tool.cpython-311.pyc │ │ ├── scraping_tool.cpython-311.pyc │ │ ├── search_tool.cpython-311.pyc │ │ └── textgen_tool.cpython-311.pyc │ │ ├── general_tool.py │ │ ├── scraping_tool.py │ │ ├── search_tool.py │ │ └── textgen_tool.py ├── socializer_v4 │ ├── __init__.py │ ├── agents │ │ ├── __init__.py │ │ ├── __pycache__ │ │ │ ├── __init__.cpython-311.pyc │ │ │ └── weibo_agent.cpython-311.pyc │ │ └── weibo_agent.py │ ├── findbigV.py │ └── tools │ │ ├── __init__.py │ │ ├── __pycache__ │ │ ├── __init__.cpython-311.pyc │ │ ├── general_tool.cpython-311.pyc │ │ ├── parsing_tool.cpython-311.pyc │ │ ├── scraping_tool.cpython-311.pyc │ │ ├── search_tool.cpython-311.pyc │ │ └── textgen_tool.cpython-311.pyc │ │ ├── general_tool.py │ │ ├── parsing_tool.py │ │ ├── scraping_tool.py │ │ ├── search_tool.py │ │ └── textgen_tool.py └── socializer_v5 │ ├── __init__.py │ ├── __pycache__ │ └── findbigV.cpython-311.pyc │ ├── agents │ ├── __init__.py │ ├── __pycache__ │ │ ├── __init__.cpython-311.pyc │ │ └── weibo_agent.cpython-311.pyc │ └── weibo_agent.py │ ├── app.py │ ├── findbigV.py │ ├── static │ └── css │ │ └── style.css │ ├── templates │ └── index.html │ └── tools │ ├── __init__.py │ ├── __pycache__ │ ├── __init__.cpython-311.pyc │ ├── general_tool.cpython-311.pyc │ ├── parsing_tool.cpython-311.pyc │ ├── scraping_tool.cpython-311.pyc │ ├── search_tool.cpython-311.pyc │ └── textgen_tool.cpython-311.pyc │ ├── general_tool.py │ ├── parsing_tool.py │ ├── scraping_tool.py │ ├── search_tool.py │ └── textgen_tool.py ├── 22_Chatbot上 ├── Chatbot_v1.0.py ├── Chatbot_v1.1.py ├── Chatbot_v2.0.py └── Chatbot_v3.0.py ├── 23_Chatbot下 ├── Chatbot_v4.0.py └── Chatbot_v5.2.py ├── README.md ├── img └── book.png ├── requirements_v0.1.txt └── requirements_v0.2.txt /00_开篇词_奇点时刻/01_简单文本生成.py: -------------------------------------------------------------------------------- 1 | '''欢迎来到LangChain实战课 2 | https://time.geekbang.org/column/intro/100617601 3 | 作者 黄佳''' 4 | 5 | from dotenv import load_dotenv # 用于加载环境变量 6 | load_dotenv() # 加载 .env 文件中的环境变量 7 | 8 | # import os 9 | # os.environ["OPENAI_API_KEY"] = '你的Open AI API Key' 10 | # from langchain.llms import OpenAI 11 | from langchain_openai import OpenAI 12 | # llm = OpenAI(model_name="text-davinci-003",max_tokens=200) 13 | llm = OpenAI(model_name="gpt-3.5-turbo-instruct",max_tokens=200) 14 | # text = llm("请给我写一句情人节红玫瑰的中文宣传语") 15 | text = llm.invoke("请给我写一句情人节红玫瑰的中文宣传语") 16 | print(text) -------------------------------------------------------------------------------- /00_开篇词_奇点时刻/02_看图说话.py: -------------------------------------------------------------------------------- 1 | '''欢迎来到LangChain实战课 2 | https://time.geekbang.org/column/intro/100617601 3 | 作者 黄佳''' 4 | 5 | from dotenv import load_dotenv # 用于加载环境变量 6 | load_dotenv() # 加载 .env 文件中的环境变量 7 | 8 | #---- Part 0 导入所需要的类 9 | import os 10 | import requests 11 | from PIL import Image 12 | from transformers import BlipProcessor, BlipForConditionalGeneration 13 | from langchain.tools import BaseTool 14 | # from langchain import OpenAI 15 | from langchain_openai import OpenAI 16 | from langchain.agents import initialize_agent, AgentType 17 | # from langchain.agents import create_react_agent # 未来需要改成下面的设计 18 | 19 | #---- Part I 初始化图像字幕生成模型 20 | # 指定要使用的工具模型(HuggingFace中的image-caption模型) 21 | hf_model = "Salesforce/blip-image-captioning-large" 22 | 23 | # 初始化处理器和工具模型 24 | # 预处理器将准备图像供模型使用 25 | processor = BlipProcessor.from_pretrained(hf_model) 26 | # 然后我们初始化工具模型本身 27 | model = BlipForConditionalGeneration.from_pretrained(hf_model) 28 | 29 | #---- Part II 定义图像字幕生成工具类 30 | class ImageCapTool(BaseTool): 31 | 32 | name = "Image captioner" 33 | description = "为图片创作说明文案." 34 | 35 | def _run(self, url: str): 36 | # 下载图像并将其转换为PIL对象 37 | image = Image.open(requests.get(url, stream=True).raw).convert('RGB') 38 | # 预处理图像 39 | inputs = processor(image, return_tensors="pt") 40 | # 生成字幕 41 | out = model.generate(**inputs, max_new_tokens=20) 42 | # 获取字幕 43 | caption = processor.decode(out[0], skip_special_tokens=True) 44 | return caption 45 | 46 | def _arun(self, query: str): 47 | raise NotImplementedError("This tool does not support async") 48 | 49 | #---- PartIII 初始化并运行LangChain智能体 50 | # 设置OpenAI的API密钥并初始化大语言模型(OpenAI的Text模型) 51 | # os.environ["OPENAI_API_KEY"] = '你的OpenAI API Key' 52 | llm = OpenAI(temperature=0.2) 53 | 54 | # 使用工具初始化智能体并运行 55 | tools = [ImageCapTool()] 56 | agent = initialize_agent( 57 | agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, 58 | tools=tools, 59 | llm=llm, 60 | verbose=True, 61 | ) 62 | # 未来需要改成下面的设计 63 | # agent = create_react_agent( 64 | # tools=tools, 65 | # llm=llm, 66 | # ) 67 | img_url = 'https://mir-s3-cdn-cf.behance.net/project_modules/hd/eec79e20058499.563190744f903.jpg' 68 | # agent.run(input=f"{img_url}\n请创作合适的中文推广文案") 69 | agent.invoke(input=f"{img_url}\n请创作合适的中文推广文案") -------------------------------------------------------------------------------- /01_LangChain快速入门/01_TextModel.py: -------------------------------------------------------------------------------- 1 | '''欢迎来到LangChain实战课 2 | https://time.geekbang.org/column/intro/100617601 3 | 作者 黄佳''' 4 | 5 | from dotenv import load_dotenv # 用于加载环境变量 6 | load_dotenv() # 加载 .env 文件中的环境变量 7 | 8 | # import os 9 | # os.environ["OPENAI_API_KEY"] = '你的OpenAI API Key' 10 | 11 | # import openai 12 | # # openai.api_key = '你的OpenAI API Key' 13 | 14 | # response = openai.Completion.create( 15 | # model="text-davinci-003", 16 | # temperature=0.5, 17 | # max_tokens=100, 18 | # prompt="请给我的花店起个名") 19 | 20 | # print(response.choices[0].text.strip()) 21 | 22 | from openai import OpenAI 23 | client = OpenAI() 24 | 25 | response = client.completions.create( 26 | model="gpt-3.5-turbo-instruct", 27 | temperature=0.5, 28 | max_tokens=100, 29 | prompt="请给我的花店起个名") 30 | 31 | print(response.choices[0].text.strip()) -------------------------------------------------------------------------------- /01_LangChain快速入门/02_ChatModel.py: -------------------------------------------------------------------------------- 1 | '''欢迎来到LangChain实战课 2 | https://time.geekbang.org/column/intro/100617601 3 | 作者 黄佳''' 4 | 5 | from dotenv import load_dotenv # 用于加载环境变量 6 | load_dotenv() # 加载 .env 文件中的环境变量 7 | 8 | # import os 9 | # os.environ["OPENAI_API_KEY"] = '你的OpenAI API Key' 10 | 11 | # import openai 12 | 13 | # response = openai.ChatCompletion.create( 14 | # model="gpt-4", 15 | # messages=[ 16 | # {"role": "system", "content": "You are a creative AI."}, 17 | # {"role": "user", "content": "请给我的花店起个名"}, 18 | # ], 19 | # temperature=0.8, 20 | # max_tokens=60 21 | # ) 22 | 23 | # print(response['choices'][0]['message']['content']) 24 | 25 | # print(response.choices) 26 | 27 | 28 | from openai import OpenAI 29 | client = OpenAI() 30 | 31 | response = client.chat.completions.create( 32 | model="gpt-4", 33 | messages=[ 34 | {"role": "system", "content": "You are a creative AI."}, 35 | {"role": "user", "content": "请给我的花店起个名"}, 36 | ], 37 | temperature=0.8, 38 | max_tokens=60 39 | ) 40 | 41 | print(response.choices[0].message.content) -------------------------------------------------------------------------------- /01_LangChain快速入门/03_TextLangChain.py: -------------------------------------------------------------------------------- 1 | '''欢迎来到LangChain实战课 2 | https://time.geekbang.org/column/intro/100617601 3 | 作者 黄佳''' 4 | 5 | # import os 6 | # os.environ["OPENAI_API_KEY"] = '你的OpenAI API Key' 7 | from langchain.llms import OpenAI 8 | llm = OpenAI( 9 | model="gpt-3.5-turbo-instruct", 10 | temperature=0.8, 11 | max_tokens=60,) 12 | response = llm.predict("请给我的花店起个名") 13 | print(response) -------------------------------------------------------------------------------- /01_LangChain快速入门/03_TextLangChain_v0.2.py: -------------------------------------------------------------------------------- 1 | '''欢迎来到LangChain实战课 2 | https://time.geekbang.org/column/intro/100617601 3 | 作者 黄佳''' 4 | 5 | # import os 6 | # os.environ["OPENAI_API_KEY"] = '你的OpenAI API Key' 7 | 8 | from langchain_openai import OpenAI 9 | llm = OpenAI( 10 | model="gpt-3.5-turbo-instruct", 11 | temperature=0.8, 12 | max_tokens=60,) 13 | response = llm.predict("请给我的花店起个名") 14 | print(response) -------------------------------------------------------------------------------- /01_LangChain快速入门/04_ChatLongChain.py: -------------------------------------------------------------------------------- 1 | '''欢迎来到LangChain实战课 2 | https://time.geekbang.org/column/intro/100617601 3 | 作者 黄佳''' 4 | 5 | import os 6 | os.environ["OPENAI_API_KEY"] = '你的OpenAI API Key' 7 | from langchain.chat_models import ChatOpenAI 8 | chat = ChatOpenAI(model="gpt-4", 9 | temperature=0.8, 10 | max_tokens=60) 11 | from langchain.schema import ( 12 | HumanMessage, 13 | SystemMessage 14 | ) 15 | messages = [ 16 | SystemMessage(content="你是一个很棒的智能助手"), 17 | HumanMessage(content="请给我的花店起个名") 18 | ] 19 | response = chat(messages) 20 | print(response) -------------------------------------------------------------------------------- /01_LangChain快速入门/04_ChatLongChain_v0.2.py: -------------------------------------------------------------------------------- 1 | '''欢迎来到LangChain实战课 2 | https://time.geekbang.org/column/intro/100617601 3 | 作者 黄佳''' 4 | 5 | # import os 6 | # os.environ["OPENAI_API_KEY"] = '你的OpenAI API Key' 7 | 8 | from langchain_openai import ChatOpenAI 9 | chat = ChatOpenAI(model="gpt-4", 10 | temperature=0.8, 11 | max_tokens=60) 12 | from langchain.schema import ( 13 | HumanMessage, 14 | SystemMessage 15 | ) 16 | messages = [ 17 | SystemMessage(content="你是一个很棒的智能助手"), 18 | HumanMessage(content="请给我的花店起个名") 19 | ] 20 | response = chat(messages) 21 | print(response) -------------------------------------------------------------------------------- /02_文档QA系统/DocQA_v0.1.py: -------------------------------------------------------------------------------- 1 | '''欢迎来到LangChain实战课 2 | https://time.geekbang.org/column/intro/100617601 3 | 作者 黄佳''' 4 | 5 | import os 6 | # os.environ["OPENAI_API_KEY"] = '你的OpenAI API Key' 7 | from dotenv import load_dotenv # 用于加载环境变量 8 | load_dotenv() # 加载 .env 文件中的环境变量 9 | 10 | # 1.Load 导入Document Loaders 11 | from langchain.document_loaders import PyPDFLoader 12 | from langchain.document_loaders import Docx2txtLoader 13 | from langchain.document_loaders import TextLoader 14 | 15 | # 加载Documents 16 | base_dir = '.\OneFlower' # 文档的存放目录 17 | documents = [] 18 | for file in os.listdir(base_dir): 19 | # 构建完整的文件路径 20 | file_path = os.path.join(base_dir, file) 21 | if file.endswith('.pdf'): 22 | loader = PyPDFLoader(file_path) 23 | documents.extend(loader.load()) 24 | elif file.endswith('.docx'): 25 | loader = Docx2txtLoader(file_path) 26 | documents.extend(loader.load()) 27 | elif file.endswith('.txt'): 28 | loader = TextLoader(file_path) 29 | documents.extend(loader.load()) 30 | 31 | # 2.Split 将Documents切分成块以便后续进行嵌入和向量存储 32 | from langchain.text_splitter import RecursiveCharacterTextSplitter 33 | text_splitter = RecursiveCharacterTextSplitter(chunk_size=200, chunk_overlap=10) 34 | chunked_documents = text_splitter.split_documents(documents) 35 | 36 | # 3.Store 将分割嵌入并存储在矢量数据库Qdrant中 37 | from langchain.vectorstores import Qdrant 38 | from langchain.embeddings import OpenAIEmbeddings 39 | vectorstore = Qdrant.from_documents( 40 | documents=chunked_documents, # 以分块的文档 41 | embedding=OpenAIEmbeddings(), # 用OpenAI的Embedding Model做嵌入 42 | location=":memory:", # in-memory 存储 43 | collection_name="my_documents",) # 指定collection_name 44 | 45 | # 4. Retrieval 准备模型和Retrieval链 46 | import logging # 导入Logging工具 47 | from langchain.chat_models import ChatOpenAI # ChatOpenAI模型 48 | from langchain.retrievers.multi_query import MultiQueryRetriever # MultiQueryRetriever工具 49 | from langchain.chains import RetrievalQA # RetrievalQA链 50 | 51 | # 设置Logging 52 | logging.basicConfig() 53 | logging.getLogger('langchain.retrievers.multi_query').setLevel(logging.INFO) 54 | 55 | # 实例化一个大模型工具 - OpenAI的GPT-3.5 56 | llm = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0) 57 | 58 | # 实例化一个MultiQueryRetriever 59 | retriever_from_llm = MultiQueryRetriever.from_llm(retriever=vectorstore.as_retriever(), llm=llm) 60 | 61 | # 实例化一个RetrievalQA链 62 | qa_chain = RetrievalQA.from_chain_type(llm,retriever=retriever_from_llm) 63 | 64 | # 5. Output 问答系统的UI实现 65 | from flask import Flask, request, render_template 66 | app = Flask(__name__) # Flask APP 67 | 68 | @app.route('/', methods=['GET', 'POST']) 69 | def home(): 70 | if request.method == 'POST': 71 | 72 | # 接收用户输入作为问题 73 | question = request.form.get('question') 74 | 75 | # RetrievalQA链 - 读入问题,生成答案 76 | result = qa_chain({"query": question}) 77 | 78 | # 把大模型的回答结果返回网页进行渲染 79 | return render_template('index.html', result=result) 80 | 81 | return render_template('index.html') 82 | 83 | if __name__ == "__main__": 84 | app.run(host='0.0.0.0',debug=True,port=5000) -------------------------------------------------------------------------------- /02_文档QA系统/DocQA_v0.2.py: -------------------------------------------------------------------------------- 1 | '''欢迎来到LangChain实战课 测试 2 | https://time.geekbang.org/column/intro/100617601 3 | 作者 黄佳''' 4 | 5 | import os 6 | # os.environ["OPENAI_API_KEY"] = '你的OpenAI API Key' 7 | from dotenv import load_dotenv # 用于加载环境变量 8 | load_dotenv() # 加载 .env 文件中的环境变量 9 | 10 | # 1.Load 导入Document Loaders 11 | from langchain_community.document_loaders import PyPDFLoader 12 | from langchain_community.document_loaders import Docx2txtLoader 13 | from langchain_community.document_loaders import TextLoader 14 | 15 | # 加载Documents 16 | base_dir = '02_文档QA系统/OneFlower' # 文档的存放目录 17 | documents = [] 18 | for file in os.listdir(base_dir): 19 | # 构建完整的文件路径 20 | file_path = os.path.join(base_dir, file) 21 | if file.endswith('.pdf'): 22 | loader = PyPDFLoader(file_path) 23 | documents.extend(loader.load()) 24 | elif file.endswith('.docx'): 25 | loader = Docx2txtLoader(file_path) 26 | documents.extend(loader.load()) 27 | elif file.endswith('.txt'): 28 | loader = TextLoader(file_path) 29 | documents.extend(loader.load()) 30 | 31 | # 2.Split 将Documents切分成块以便后续进行嵌入和向量存储 32 | from langchain.text_splitter import RecursiveCharacterTextSplitter 33 | text_splitter = RecursiveCharacterTextSplitter(chunk_size=200, chunk_overlap=10) 34 | chunked_documents = text_splitter.split_documents(documents) 35 | 36 | # 3.Store 将分割嵌入并存储在矢量数据库Qdrant中 37 | from langchain_community.vectorstores import Qdrant 38 | from langchain_openai import OpenAIEmbeddings 39 | vectorstore = Qdrant.from_documents( 40 | documents=chunked_documents, # 以分块的文档 41 | embedding=OpenAIEmbeddings(), # 用OpenAI的Embedding Model做嵌入 42 | location=":memory:", # in-memory 存储 43 | collection_name="my_documents",) # 指定collection_name 44 | 45 | # 4. Retrieval 准备模型和Retrieval链 46 | import logging # 导入Logging工具 47 | from langchain_openai import ChatOpenAI # ChatOpenAI模型 48 | from langchain.retrievers.multi_query import MultiQueryRetriever # MultiQueryRetriever工具 49 | from langchain.chains import RetrievalQA # RetrievalQA链 50 | 51 | # 设置Logging 52 | logging.basicConfig() 53 | logging.getLogger('langchain.retrievers.multi_query').setLevel(logging.INFO) 54 | 55 | # 实例化一个大模型工具 - OpenAI的GPT-3.5 56 | llm = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0) 57 | 58 | # 实例化一个MultiQueryRetriever 59 | retriever_from_llm = MultiQueryRetriever.from_llm(retriever=vectorstore.as_retriever(), llm=llm) 60 | 61 | # 实例化一个RetrievalQA链 62 | qa_chain = RetrievalQA.from_chain_type(llm,retriever=retriever_from_llm) 63 | 64 | # 5. Output 问答系统的UI实现 65 | from flask import Flask, request, render_template 66 | app = Flask(__name__) # Flask APP 67 | 68 | @app.route('/', methods=['GET', 'POST']) 69 | def home(): 70 | if request.method == 'POST': 71 | # 接收用户输入作为问题 72 | question = request.form.get('question') 73 | 74 | # RetrievalQA链 - 读入问题,生成答案 75 | result = qa_chain({"query": question}) 76 | 77 | # 把大模型的回答结果返回网页进行渲染 78 | return render_template('index.html', result=result) 79 | 80 | return render_template('index.html') 81 | 82 | if __name__ == "__main__": 83 | app.run(host='0.0.0.0',debug=True,port=5000) -------------------------------------------------------------------------------- /02_文档QA系统/OneFlower/易速鲜花员工手册.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huangjia2019/langchain-in-action/6a899d656b6afa4497c53c7a535e83d98a3b63ad/02_文档QA系统/OneFlower/易速鲜花员工手册.pdf -------------------------------------------------------------------------------- /02_文档QA系统/OneFlower/易速鲜花运营指南.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huangjia2019/langchain-in-action/6a899d656b6afa4497c53c7a535e83d98a3b63ad/02_文档QA系统/OneFlower/易速鲜花运营指南.docx -------------------------------------------------------------------------------- /02_文档QA系统/OneFlower/花语大全.txt: -------------------------------------------------------------------------------- 1 | Rose: Love, Passion, Beauty 2 | Carnation: Maternal Love, Innocence, Respect 3 | Lily: Purity, Nobility, Blessings 4 | Tulip: Perfect Love, Passion, Tenderness 5 | Daisy: Innocence, Beauty, Hope 6 | Peony: Prosperity, Wealth, Happiness 7 | Sunflower: Loyalty, Sunshine, Positivity 8 | Gypsophila: Purity, Romance, Beautiful Dreams 9 | Peach Blossom: Romantic Luck, Beautiful Fate, Happiness 10 | Hydrangea: Sincerity, Gratitude, Best Wishes 11 | Phalaenopsis: Noble, Elegant, Beautifully Moving 12 | Cherry Blossom: Beauty, Transience, Wonderful Moments 13 | Lily of the Valley: Happiness, Purity, Deep Love 14 | Chrysanthemum: Strength, Longevity, Sincere Friendship 15 | Marigold: Beauty, Blessings, Wellness 16 | Violet: Eternal Love, Purity, Chastity 17 | Edelweiss: Courage, Sincere Love, Preciousness 18 | Bellflower: Hope, Everlasting Love, Humility 19 | Forget-Me-Not: Loyalty, True Love, Beautiful Memories 20 | Paeonia: Fragrance, Wealth, Beautiful Posture 21 | Wisteria: Gentleness, Sentimentality, Protective Love 22 | Lavender: Tranquility, Innocence, Pursuit of Love 23 | Foxglove: Beauty, Joy, Blessings 24 | Dianthus: Delicate Thoughts, Sincerity, Romance 25 | Magnolia: Nobility, Elegance, Eternal Love 26 | Lilac: First Love, Youth, Beautiful Memories 27 | Lotus: Freshness, Purity, Excellence 28 | Ginkgo: Persistence, Friendship, Steadfast Heart 29 | Snowdrop: Hope, New Beginnings, First Bloom 30 | Anthurium: Passion, Attraction, Happy Love -------------------------------------------------------------------------------- /02_文档QA系统/static/flower.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huangjia2019/langchain-in-action/6a899d656b6afa4497c53c7a535e83d98a3b63ad/02_文档QA系统/static/flower.png -------------------------------------------------------------------------------- /02_文档QA系统/templates/index.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 |

易速鲜花内部问答系统

5 | flower logo 6 |
7 |
8 |
9 |
10 | 11 |
12 | {% if result is defined %} 13 |

Answer

14 |

{{ result.result }}

15 | {% endif %} 16 |
17 | 18 | -------------------------------------------------------------------------------- /03_模型IO/01_模型IO.py: -------------------------------------------------------------------------------- 1 | '''欢迎来到LangChain实战课 2 | https://time.geekbang.org/column/intro/100617601 3 | 作者 黄佳''' 4 | from dotenv import load_dotenv # 用于加载环境变量 5 | load_dotenv() # 加载 .env 文件中的环境变量 6 | 7 | # 导入LangChain中的提示模板 8 | from langchain.prompts import PromptTemplate 9 | # 创建原始模板 10 | template = """您是一位专业的鲜花店文案撰写员。\n 11 | 对于售价为 {price} 元的 {flower_name} ,您能提供一个吸引人的简短描述吗? 12 | """ 13 | # 根据原始模板创建LangChain提示模板 14 | prompt = PromptTemplate.from_template(template) 15 | # 打印LangChain提示模板的内容 16 | print(prompt) 17 | 18 | # 设置OpenAI API Key 19 | # import os 20 | # os.environ["OPENAI_API_KEY"] = '你的OpenAI API Key' 21 | 22 | # 导入LangChain中的OpenAI模型接口 23 | from langchain_openai import OpenAI 24 | # 创建模型实例 25 | model = OpenAI(model_name='gpt-3.5-turbo-instruct') 26 | # 输入提示 27 | input = prompt.format(flower_name=["玫瑰"], price='50') 28 | # 得到模型的输出 29 | output = model.invoke(input) 30 | # 打印输出内容 31 | print(output) 32 | -------------------------------------------------------------------------------- /03_模型IO/02_模型IO_循环调用.py: -------------------------------------------------------------------------------- 1 | '''欢迎来到LangChain实战课 2 | https://time.geekbang.org/column/intro/100617601 3 | 作者 黄佳''' 4 | from dotenv import load_dotenv # 用于加载环境变量 5 | load_dotenv() # 加载 .env 文件中的环境变量 6 | 7 | # 导入LangChain中的提示模板 8 | from langchain.prompts import PromptTemplate 9 | # 创建原始模板 10 | template = """您是一位专业的鲜花店文案撰写员。\n 11 | 对于售价为 {price} 元的 {flower_name} ,您能提供一个吸引人的简短描述吗? 12 | """ 13 | # 根据原始模板创建LangChain提示模板 14 | prompt = PromptTemplate.from_template(template) 15 | # 打印LangChain提示模板的内容 16 | print(prompt) 17 | 18 | # 设置OpenAI API Key 19 | # import os 20 | # os.environ["OPENAI_API_KEY"] = '你的OpenAI API Key' 21 | 22 | # 导入LangChain中的OpenAI模型接口 23 | from langchain_openai import OpenAI 24 | # 创建模型实例 25 | model = OpenAI(model_name='gpt-3.5-turbo-instruct') 26 | 27 | # 多种花的列表 28 | flowers = ["玫瑰", "百合", "康乃馨"] 29 | prices = ["50", "30", "20"] 30 | 31 | # 生成多种花的文案 32 | for flower, price in zip(flowers, prices): 33 | # 使用提示模板生成输入 34 | input_prompt = prompt.format(flower_name=flower, price=price) 35 | 36 | # 得到模型的输出 37 | output = model.invoke(input_prompt) 38 | 39 | # 打印输出内容 40 | print(output) 41 | -------------------------------------------------------------------------------- /03_模型IO/03_OpenAI_IO.py: -------------------------------------------------------------------------------- 1 | '''欢迎来到LangChain实战课 2 | https://time.geekbang.org/column/intro/100617601 3 | 作者 黄佳''' 4 | from dotenv import load_dotenv # 用于加载环境变量 5 | load_dotenv() # 加载 .env 文件中的环境变量 6 | import openai # 导入OpenAI 7 | # openai.api_key = '你的OpenAI API Key' # API Key 8 | 9 | prompt_text = "您是一位专业的鲜花店文案撰写员。对于售价为{}元的{},您能提供一个吸引人的简短描述吗?" # 设置提示 10 | 11 | flowers = ["玫瑰", "百合", "康乃馨"] 12 | prices = ["50", "30", "20"] 13 | 14 | # 循环调用Text模型的Completion方法,生成文案 15 | for flower, price in zip(flowers, prices): 16 | prompt = prompt_text.format(price, flower) 17 | response = openai.completions.create( 18 | model="gpt-3.5-turbo-instruct", 19 | prompt=prompt, 20 | max_tokens=100 21 | ) 22 | print(response.choices[0].text.strip()) # 输出文案 -------------------------------------------------------------------------------- /03_模型IO/04_模型IO_HuggingFace.py: -------------------------------------------------------------------------------- 1 | '''欢迎来到LangChain实战课 2 | https://time.geekbang.org/column/intro/100617601 3 | 作者 黄佳''' 4 | from dotenv import load_dotenv # 用于加载环境变量 5 | load_dotenv() # 加载 .env 文件中的环境变量 6 | 7 | # 导入LangChain中的提示模板 8 | from langchain.prompts import PromptTemplate 9 | # 创建原始模板 10 | template = """You are a flower shop assitiant。\n 11 | For {price} of {flower_name} ,can you write something for me? 12 | """ 13 | # 根据原始模板创建LangChain提示模板 14 | prompt = PromptTemplate.from_template(template) 15 | # 打印LangChain提示模板的内容 16 | print(prompt) 17 | 18 | # 设置HuggingFace API Token 19 | # import os 20 | # os.environ['HUGGINGFACEHUB_API_TOKEN'] = '你的HUGGINGFACEHUB API Token' 21 | 22 | # 导入LangChain中的OpenAI模型接口 23 | from langchain_community.llms import HuggingFaceHub 24 | # 创建模型实例 25 | model= HuggingFaceHub(repo_id="google/flan-t5-large") 26 | # 输入提示 27 | input = prompt.format(flower_name=["玫瑰"], price='50') 28 | # 得到模型的输出 29 | output = model.invoke(input) 30 | # 打印输出内容 31 | print(output) 32 | -------------------------------------------------------------------------------- /03_模型IO/05_模型IO_输出解析.py: -------------------------------------------------------------------------------- 1 | '''欢迎来到LangChain实战课 2 | https://time.geekbang.org/column/intro/100617601 3 | 作者 黄佳''' 4 | from dotenv import load_dotenv # 用于加载环境变量 5 | load_dotenv() # 加载 .env 文件中的环境变量 6 | 7 | # 导入OpenAI Key 8 | import os 9 | # os.environ["OPENAI_API_KEY"] = '你的OpenAI API Key' 10 | 11 | # 导入LangChain中的提示模板 12 | from langchain.prompts import PromptTemplate 13 | # 创建提示模板 14 | prompt_template = """您是一位专业的鲜花店文案撰写员。 15 | 对于售价为 {price} 元的 {flower_name} ,您能提供一个吸引人的简短描述吗? 16 | {format_instructions}""" 17 | 18 | # 通过LangChain调用模型 19 | from langchain_openai import OpenAI 20 | # 创建模型实例 21 | model = OpenAI(model_name='gpt-3.5-turbo-instruct') 22 | 23 | # 导入结构化输出解析器和ResponseSchema 24 | from langchain.output_parsers import StructuredOutputParser, ResponseSchema 25 | # 定义我们想要接收的响应模式 26 | response_schemas = [ 27 | ResponseSchema(name="description", description="鲜花的描述文案"), 28 | ResponseSchema(name="reason", description="问什么要这样写这个文案") 29 | ] 30 | # 创建输出解析器 31 | output_parser = StructuredOutputParser.from_response_schemas(response_schemas) 32 | 33 | # 获取格式指示 34 | format_instructions = output_parser.get_format_instructions() 35 | # 根据模板创建提示,同时在提示中加入输出解析器的说明 36 | prompt = PromptTemplate.from_template(prompt_template, 37 | partial_variables={"format_instructions": format_instructions}) 38 | 39 | # 数据准备 40 | flowers = ["玫瑰", "百合", "康乃馨"] 41 | prices = ["50", "30", "20"] 42 | 43 | # 创建一个空的DataFrame用于存储结果 44 | import pandas as pd 45 | df = pd.DataFrame(columns=["flower", "price", "description", "reason"]) # 先声明列名 46 | 47 | for flower, price in zip(flowers, prices): 48 | # 根据提示准备模型的输入 49 | input = prompt.format(flower_name=flower, price=price) 50 | 51 | # 获取模型的输出 52 | output = model.invoke(input) 53 | 54 | # 解析模型的输出(这是一个字典结构) 55 | parsed_output = output_parser.parse(output) 56 | 57 | # 在解析后的输出中添加“flower”和“price” 58 | parsed_output['flower'] = flower 59 | parsed_output['price'] = price 60 | 61 | # 将解析后的输出添加到DataFrame中 62 | df.loc[len(df)] = parsed_output 63 | 64 | # 打印字典 65 | print(df.to_dict(orient='records')) 66 | 67 | # 保存DataFrame到CSV文件 68 | df.to_csv("flowers_with_descriptions.csv", index=False) -------------------------------------------------------------------------------- /03_模型IO/flowers_with_descriptions.csv: -------------------------------------------------------------------------------- 1 | flower,price,description,reason 2 | 玫瑰,50,"This 50 yuan rose is the perfect gift to show your appreciation and love! With its gorgeous petals and sweet fragrance, it's sure to bring a smile to your special someone's face.","This description is short, sweet, and to the point, while also conveying the beauty and sentimentality of the flower. It should be a great way to convince customers to purchase this rose." 3 | 百合,30,"Indulge in the beauty of our 30-yuan lilies, a perfect combination of elegance and grace!","The description is concise and eye-catching, emphasizing the affordability and beauty of the lilies." 4 | 康乃馨,20,"Bring a smile to your loved ones with this 20 yuan Carnation bouquet! A perfect gift for any occasion, this bouquet will add a pop of color to any space.","This description is short and sweet, emphasizing the affordability and cheerful quality of the bouquet, making it a great gift for any occasion." 5 | -------------------------------------------------------------------------------- /04_提示模板上/00_ImportTemplates.py: -------------------------------------------------------------------------------- 1 | '''欢迎来到LangChain实战课 2 | https://time.geekbang.org/column/intro/100617601 3 | 作者 黄佳''' 4 | from langchain.prompts.prompt import PromptTemplate 5 | from langchain.prompts import FewShotPromptTemplate 6 | from langchain.prompts.pipeline import PipelinePromptTemplate 7 | from langchain.prompts import ChatPromptTemplate 8 | from langchain.prompts import ( 9 | ChatMessagePromptTemplate, 10 | SystemMessagePromptTemplate, 11 | AIMessagePromptTemplate, 12 | HumanMessagePromptTemplate, 13 | ) -------------------------------------------------------------------------------- /04_提示模板上/01_PromptTemplate.py: -------------------------------------------------------------------------------- 1 | '''欢迎来到LangChain实战课 2 | https://time.geekbang.org/column/intro/100617601 3 | 作者 黄佳''' 4 | from langchain import PromptTemplate 5 | 6 | template = """\ 7 | 你是业务咨询顾问。 8 | 你给一个销售{product}的电商公司,起一个好的名字? 9 | """ 10 | prompt = PromptTemplate.from_template(template) 11 | 12 | print(prompt.format(product="鲜花")) 13 | 14 | prompt = PromptTemplate( 15 | input_variables=["product", "market"], 16 | template="你是业务咨询顾问。对于一个面向{market}市场的,专注于销售{product}的公司,你会推荐哪个名字?" 17 | ) 18 | print(prompt.format(product="鲜花", market="高端")) -------------------------------------------------------------------------------- /04_提示模板上/02_ChatPromptTemplate.py: -------------------------------------------------------------------------------- 1 | '''欢迎来到LangChain实战课 2 | https://time.geekbang.org/column/intro/100617601 3 | 作者 黄佳''' 4 | # 导入聊天消息类模板 5 | from langchain.prompts import ( 6 | ChatPromptTemplate, 7 | SystemMessagePromptTemplate, 8 | HumanMessagePromptTemplate, 9 | ) 10 | # 模板的构建 11 | template="你是一位专业顾问,负责为专注于{product}的公司起名。" 12 | system_message_prompt = SystemMessagePromptTemplate.from_template(template) 13 | human_template="公司主打产品是{product_detail}。" 14 | human_message_prompt = HumanMessagePromptTemplate.from_template(human_template) 15 | prompt_template = ChatPromptTemplate.from_messages([system_message_prompt, human_message_prompt]) 16 | 17 | # 格式化提示消息生成提示 18 | prompt = prompt_template.format_prompt(product="鲜花装饰", product_detail="创新的鲜花设计。").to_messages() 19 | 20 | # 下面调用模型,把提示消息传入模型,生成结果 21 | import os 22 | os.environ["OPENAI_API_KEY"] = '你的OpenAI API Key' 23 | from langchain.chat_models import ChatOpenAI 24 | chat = ChatOpenAI() 25 | result = chat(prompt) 26 | print(result) -------------------------------------------------------------------------------- /04_提示模板上/03_FewShotPrompt.py: -------------------------------------------------------------------------------- 1 | '''欢迎来到LangChain实战课 2 | https://time.geekbang.org/column/intro/100617601 3 | 作者 黄佳''' 4 | # 1. 创建一些示例 5 | samples = [ 6 | 7 | { 8 | "flower_type": "玫瑰", 9 | "occasion": "爱情", 10 | "ad_copy": "玫瑰,浪漫的象征,是你向心爱的人表达爱意的最佳选择。" 11 | }, 12 | { 13 | "flower_type": "康乃馨", 14 | "occasion": "母亲节", 15 | "ad_copy": "康乃馨代表着母爱的纯洁与伟大,是母亲节赠送给母亲的完美礼物。" 16 | }, 17 | { 18 | "flower_type": "百合", 19 | "occasion": "庆祝", 20 | "ad_copy": "百合象征着纯洁与高雅,是你庆祝特殊时刻的理想选择。" 21 | }, 22 | { 23 | "flower_type": "向日葵", 24 | "occasion": "鼓励", 25 | "ad_copy": "向日葵象征着坚韧和乐观,是你鼓励亲朋好友的最好方式。" 26 | } 27 | ] 28 | 29 | # 2. 创建一个提示模板 30 | from langchain.prompts.prompt import PromptTemplate 31 | prompt_sample = PromptTemplate(input_variables=["flower_type", "occasion", "ad_copy"], 32 | template="鲜花类型: {flower_type}\n场合: {occasion}\n文案: {ad_copy}") 33 | print(prompt_sample.format(**samples[0])) 34 | 35 | # 3. 创建一个FewShotPromptTemplate对象 36 | from langchain.prompts.few_shot import FewShotPromptTemplate 37 | prompt = FewShotPromptTemplate( 38 | examples=samples, 39 | example_prompt=prompt_sample, 40 | suffix="鲜花类型: {flower_type}\n场合: {occasion}", 41 | input_variables=["flower_type", "occasion"] 42 | ) 43 | print(prompt.format(flower_type="野玫瑰", occasion="爱情")) 44 | 45 | # 4. 把提示传递给大模型 46 | import os 47 | os.environ["OPENAI_API_KEY"] = '你的OpenAI API Key' 48 | from langchain.llms import OpenAI 49 | model = OpenAI(model_name='text-davinci-003') 50 | result = model(prompt.format(flower_type="野玫瑰", occasion="爱情")) 51 | print(result) 52 | 53 | # 5. 使用示例选择器 54 | from langchain.prompts.example_selector import SemanticSimilarityExampleSelector 55 | from langchain.vectorstores import Qdrant 56 | from langchain.embeddings import OpenAIEmbeddings 57 | 58 | # 初始化示例选择器 59 | example_selector = SemanticSimilarityExampleSelector.from_examples( 60 | samples, 61 | OpenAIEmbeddings(), 62 | Qdrant, 63 | k=1 64 | ) 65 | 66 | # 创建一个使用示例选择器的FewShotPromptTemplate对象 67 | prompt = FewShotPromptTemplate( 68 | example_selector=example_selector, 69 | example_prompt=prompt_sample, 70 | suffix="鲜花类型: {flower_type}\n场合: {occasion}", 71 | input_variables=["flower_type", "occasion"] 72 | ) 73 | print(prompt.format(flower_type="红玫瑰", occasion="爱情")) 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /05_提示模板下/CoT.py: -------------------------------------------------------------------------------- 1 | '''欢迎来到LangChain实战课 2 | https://time.geekbang.org/column/intro/100617601 3 | 作者 黄佳''' 4 | # 设置环境变量和API密钥 5 | import os 6 | os.environ["OPENAI_API_KEY"] = '你的OpenAI API Key' 7 | 8 | # 创建聊天模型 9 | from langchain.chat_models import ChatOpenAI 10 | llm = ChatOpenAI(temperature=0) 11 | 12 | # 设定 AI 的角色和目标 13 | role_template = "你是一个为花店电商公司工作的AI助手, 你的目标是帮助客户根据他们的喜好做出明智的决定" 14 | 15 | # CoT 的关键部分,AI 解释推理过程,并加入一些先前的对话示例(Few-Shot Learning) 16 | cot_template = """ 17 | 作为一个为花店电商公司工作的AI助手,我的目标是帮助客户根据他们的喜好做出明智的决定。 18 | 19 | 我会按部就班的思考,先理解客户的需求,然后考虑各种鲜花的涵义,最后根据这个需求,给出我的推荐。 20 | 同时,我也会向客户解释我这样推荐的原因。 21 | 22 | 示例 1: 23 | 人类:我想找一种象征爱情的花。 24 | AI:首先,我理解你正在寻找一种可以象征爱情的花。在许多文化中,红玫瑰被视为爱情的象征,这是因为它们的红色通常与热情和浓烈的感情联系在一起。因此,考虑到这一点,我会推荐红玫瑰。红玫瑰不仅能够象征爱情,同时也可以传达出强烈的感情,这是你在寻找的。 25 | 26 | 示例 2: 27 | 人类:我想要一些独特和奇特的花。 28 | AI:从你的需求中,我理解你想要的是独一无二和引人注目的花朵。兰花是一种非常独特并且颜色鲜艳的花,它们在世界上的许多地方都被视为奢侈品和美的象征。因此,我建议你考虑兰花。选择兰花可以满足你对独特和奇特的要求,而且,兰花的美丽和它们所代表的力量和奢侈也可能会吸引你。 29 | """ 30 | from langchain.prompts import ChatPromptTemplate, HumanMessagePromptTemplate, SystemMessagePromptTemplate 31 | system_prompt_role = SystemMessagePromptTemplate.from_template(role_template) 32 | system_prompt_cot = SystemMessagePromptTemplate.from_template(cot_template) 33 | 34 | # 用户的询问 35 | human_template = "{human_input}" 36 | human_prompt = HumanMessagePromptTemplate.from_template(human_template) 37 | 38 | # 将以上所有信息结合为一个聊天提示 39 | chat_prompt = ChatPromptTemplate.from_messages([system_prompt_role, system_prompt_cot, human_prompt]) 40 | 41 | prompt = chat_prompt.format_prompt(human_input="我想为我的女朋友购买一些花。她喜欢粉色和紫色。你有什么建议吗?").to_messages() 42 | 43 | # 接收用户的询问,返回回答结果 44 | response = llm(prompt) 45 | print(response) -------------------------------------------------------------------------------- /06_调用模型/01_HugggingFace_Llama.py: -------------------------------------------------------------------------------- 1 | '''欢迎来到LangChain实战课 2 | https://time.geekbang.org/column/intro/100617601 3 | 作者 黄佳''' 4 | # 导入HuggingFace API Token 5 | import os 6 | os.environ['HUGGINGFACEHUB_API_TOKEN'] = 'Your HuggingFace API Token' 7 | 8 | # 导入必要的库 9 | from transformers import AutoTokenizer, AutoModelForCausalLM 10 | 11 | # 加载预训练模型的分词器 12 | tokenizer = AutoTokenizer.from_pretrained("meta-llama/Llama-2-7b-chat-hf") 13 | 14 | # 加载预训练的模型 15 | # 使用 device_map 参数将模型自动加载到可用的硬件设备上,例如GPU 16 | model = AutoModelForCausalLM.from_pretrained( 17 | "meta-llama/Llama-2-7b-chat-hf", 18 | device_map = 'auto') 19 | 20 | # 定义一个提示,希望模型基于此提示生成故事 21 | prompt = "请给我讲个玫瑰的爱情故事?" 22 | 23 | # 使用分词器将提示转化为模型可以理解的格式,并将其移动到GPU上 24 | inputs = tokenizer(prompt, return_tensors="pt").to("cuda") 25 | 26 | # 使用模型生成文本,设置最大生成令牌数为2000 27 | outputs = model.generate(inputs["input_ids"], max_new_tokens=2000) 28 | 29 | # 将生成的令牌解码成文本,并跳过任何特殊的令牌,例如[CLS], [SEP]等 30 | response = tokenizer.decode(outputs[0], skip_special_tokens=True) 31 | 32 | # 打印生成的响应 33 | print(response) -------------------------------------------------------------------------------- /06_调用模型/02_LangChain_HFHub.py: -------------------------------------------------------------------------------- 1 | '''欢迎来到LangChain实战课 2 | https://time.geekbang.org/column/intro/100617601 3 | 作者 黄佳''' 4 | # 导入HuggingFace API Token 5 | import os 6 | os.environ['HUGGINGFACEHUB_API_TOKEN'] = 'Your HuggingFace API Token' 7 | 8 | # 导入必要的库 9 | from langchain import PromptTemplate, HuggingFaceHub, LLMChain 10 | 11 | # 初始化HF LLM 12 | llm = HuggingFaceHub( 13 | repo_id="google/flan-t5-small", 14 | #repo_id="meta-llama/Llama-2-7b-chat-hf", 15 | ) 16 | 17 | # 创建简单的question-answering提示模板 18 | template = """Question: {question} 19 | Answer: """ 20 | 21 | # 创建Prompt 22 | prompt = PromptTemplate(template=template, input_variables=["question"]) 23 | 24 | # 调用LLM Chain --- 我们以后会详细讲LLM Chain 25 | llm_chain = LLMChain( 26 | prompt=prompt, 27 | llm=llm 28 | ) 29 | 30 | # 准备问题 31 | question = "Rose is which type of flower?" 32 | 33 | # 调用模型并返回结果 34 | print(llm_chain.run(question)) -------------------------------------------------------------------------------- /06_调用模型/03_LangChain_HFPipeline.py: -------------------------------------------------------------------------------- 1 | '''欢迎来到LangChain实战课 2 | https://time.geekbang.org/column/intro/100617601 3 | 作者 黄佳''' 4 | # 指定预训练模型的名称 5 | model = "meta-llama/Llama-2-7b-chat-hf" 6 | 7 | # 从预训练模型中加载词汇器 8 | from transformers import AutoTokenizer 9 | tokenizer = AutoTokenizer.from_pretrained(model) 10 | 11 | # 创建一个文本生成的管道 12 | import transformers 13 | import torch 14 | pipeline = transformers.pipeline( 15 | "text-generation", 16 | model=model, 17 | torch_dtype=torch.float16, 18 | device_map="auto", 19 | max_length = 1000 20 | ) 21 | 22 | # 创建HuggingFacePipeline实例 23 | from langchain import HuggingFacePipeline 24 | llm = HuggingFacePipeline(pipeline = pipeline, 25 | model_kwargs = {'temperature':0}) 26 | 27 | # 定义输入模板,该模板用于生成花束的描述 28 | template = """ 29 | 为以下的花束生成一个详细且吸引人的描述: 30 | 花束的详细信息: 31 | ```{flower_details}``` 32 | """ 33 | 34 | # 使用模板创建提示 35 | from langchain import PromptTemplate, LLMChain 36 | prompt = PromptTemplate(template=template, 37 | input_variables=["flower_details"]) 38 | 39 | # 创建LLMChain实例 40 | from langchain import PromptTemplate 41 | llm_chain = LLMChain(prompt=prompt, llm=llm) 42 | 43 | # 需要生成描述的花束的详细信息 44 | flower_details = "12支红玫瑰,搭配白色满天星和绿叶,包装在浪漫的红色纸中。" 45 | 46 | # 打印生成的花束描述 47 | print(llm_chain.run(flower_details)) -------------------------------------------------------------------------------- /06_调用模型/04_LangChain_CustomizeModel.py: -------------------------------------------------------------------------------- 1 | '''欢迎来到LangChain实战课 2 | https://time.geekbang.org/column/intro/100617601 3 | 作者 黄佳''' 4 | # 导入需要的库 5 | from llama_cpp import Llama 6 | from typing import Optional, List, Mapping, Any 7 | from langchain.llms.base import LLM 8 | 9 | # 模型的名称和路径常量 10 | MODEL_NAME = 'llama-2-7b-chat.ggmlv3.q4_K_S.bin' 11 | MODEL_PATH = '/home/huangj/03_Llama/' 12 | 13 | # 自定义的LLM类,继承自基础LLM类 14 | class CustomLLM(LLM): 15 | model_name = MODEL_NAME 16 | 17 | # 该方法使用Llama库调用模型生成回复 18 | def _call(self, prompt: str, stop: Optional[List[str]] = None) -> str: 19 | prompt_length = len(prompt) + 5 20 | # 初始化Llama模型,指定模型路径和线程数 21 | llm = Llama(model_path=MODEL_PATH+MODEL_NAME, n_threads=4) 22 | # 使用Llama模型生成回复 23 | response = llm(f"Q: {prompt} A: ", max_tokens=256) 24 | 25 | # 从返回的回复中提取文本部分 26 | output = response['choices'][0]['text'].replace('A: ', '').strip() 27 | 28 | # 返回生成的回复,同时剔除了问题部分和额外字符 29 | return output[prompt_length:] 30 | 31 | # 返回模型的标识参数,这里只是返回模型的名称 32 | @property 33 | def _identifying_params(self) -> Mapping[str, Any]: 34 | return {"name_of_model": self.model_name} 35 | 36 | # 返回模型的类型,这里是"custom" 37 | @property 38 | def _llm_type(self) -> str: 39 | return "custom" 40 | 41 | 42 | # 初始化自定义LLM类 43 | llm = CustomLLM() 44 | 45 | # 使用自定义LLM生成一个回复 46 | result = llm("昨天有一个客户抱怨他买了花给女朋友之后,两天花就枯了,你说作为客服我应该怎么解释?") 47 | 48 | # 打印生成的回复 49 | print(result) -------------------------------------------------------------------------------- /07_解析输出/01_Pydantic_Parser.py: -------------------------------------------------------------------------------- 1 | '''欢迎来到LangChain实战课 2 | https://time.geekbang.org/column/intro/100617601 3 | 作者 黄佳''' 4 | # ------Part 1 5 | from dotenv import load_dotenv # 用于加载环境变量 6 | load_dotenv() # 加载 .env 文件中的环境变量 7 | 8 | # 设置OpenAI API密钥 9 | import os 10 | # os.environ["OPENAI_API_KEY"] = 'Your OpenAI API Key' 11 | 12 | # 创建模型实例 13 | from langchain import OpenAI 14 | # from langchain.chat_models import ChatOpenAI 15 | model = OpenAI(model_name='gpt-3.5-turbo-instruct') 16 | # model = ChatOpenAI(model_name='gpt-4') 17 | 18 | # ------Part 2 19 | # 创建一个空的DataFrame用于存储结果 20 | import pandas as pd 21 | df = pd.DataFrame(columns=["flower_type", "price", "description", "reason"]) 22 | 23 | # 数据准备 24 | flowers = ["玫瑰", "百合", "康乃馨"] 25 | prices = ["50", "30", "20"] 26 | 27 | # 定义我们想要接收的数据格式 28 | from pydantic import BaseModel, Field 29 | class FlowerDescription(BaseModel): 30 | flower_type: str = Field(description="鲜花的种类") 31 | price: int = Field(description="鲜花的价格") 32 | description: str = Field(description="鲜花的描述文案") 33 | reason: str = Field(description="为什么要这样写这个文案") 34 | 35 | # ------Part 3 36 | # 创建输出解析器 37 | from langchain.output_parsers import PydanticOutputParser 38 | output_parser = PydanticOutputParser(pydantic_object=FlowerDescription) 39 | 40 | # 获取输出格式指示 41 | format_instructions = output_parser.get_format_instructions() 42 | # 打印提示 43 | print("输出格式:",format_instructions) 44 | 45 | 46 | # ------Part 4 47 | # 创建提示模板 48 | from langchain import PromptTemplate 49 | prompt_template = """您是一位专业的鲜花店文案撰写员。 50 | 对于售价为 {price} 元的 {flower} ,您能提供一个吸引人的简短中文描述吗? 51 | {format_instructions}""" 52 | 53 | # 根据模板创建提示,同时在提示中加入输出解析器的说明 54 | prompt = PromptTemplate.from_template(prompt_template, 55 | partial_variables={"format_instructions": format_instructions}) 56 | 57 | # 打印提示 58 | print("提示:", prompt) 59 | 60 | # ------Part 5 61 | for flower, price in zip(flowers, prices): 62 | # 根据提示准备模型的输入 63 | input = prompt.format(flower=flower, price=price) 64 | # 打印提示 65 | print("提示:", input) 66 | 67 | # 获取模型的输出 68 | output = model(input) 69 | 70 | # 解析模型的输出 71 | parsed_output = output_parser.parse(output) 72 | parsed_output_dict = parsed_output.dict() # 将Pydantic格式转换为字典 73 | 74 | # 将解析后的输出添加到DataFrame中 75 | df.loc[len(df)] = parsed_output.dict() 76 | 77 | # 打印字典 78 | print("输出的数据:", df.to_dict(orient='records')) 79 | 80 | -------------------------------------------------------------------------------- /07_解析输出/02_OutputFixParser.py: -------------------------------------------------------------------------------- 1 | '''欢迎来到LangChain实战课 2 | https://time.geekbang.org/column/intro/100617601 3 | 作者 黄佳''' 4 | # 导入所需要的库和模块 5 | from langchain.output_parsers import PydanticOutputParser 6 | from pydantic import BaseModel, Field 7 | from typing import List 8 | 9 | # 使用Pydantic创建一个数据格式,表示花 10 | class Flower(BaseModel): 11 | name: str = Field(description="name of a flower") 12 | colors: List[str] = Field(description="the colors of this flower") 13 | # 定义一个用于获取某种花的颜色列表的查询 14 | flower_query = "Generate the charaters for a random flower." 15 | 16 | # 定义一个格式不正确的输出 17 | misformatted = "{'name': '康乃馨', 'colors': ['粉红色','白色','红色','紫色','黄色']}" 18 | 19 | # 创建一个用于解析输出的Pydantic解析器,此处希望解析为Flower格式 20 | parser = PydanticOutputParser(pydantic_object=Flower) 21 | # 使用Pydantic解析器解析不正确的输出 22 | # parser.parse(misformatted) # 这行代码会出错 23 | 24 | # 从langchain库导入所需的模块 25 | from langchain.chat_models import ChatOpenAI 26 | from langchain.output_parsers import OutputFixingParser 27 | 28 | # 设置OpenAI API密钥 29 | import os 30 | os.environ["OPENAI_API_KEY"] = 'Your OpenAI API Key' 31 | 32 | # 使用OutputFixingParser创建一个新的解析器,该解析器能够纠正格式不正确的输出 33 | new_parser = OutputFixingParser.from_llm(parser=parser, llm=ChatOpenAI()) 34 | 35 | # 使用新的解析器解析不正确的输出 36 | result = new_parser.parse(misformatted) # 错误被自动修正 37 | print(result) # 打印解析后的输出结果 -------------------------------------------------------------------------------- /07_解析输出/03_RetryParser.py: -------------------------------------------------------------------------------- 1 | '''欢迎来到LangChain实战课 2 | https://time.geekbang.org/column/intro/100617601 3 | 作者 黄佳''' 4 | # 定义一个模板字符串,这个模板将用于生成提问 5 | template = """Based on the user question, provide an Action and Action Input for what step should be taken. 6 | {format_instructions} 7 | Question: {query} 8 | Response:""" 9 | 10 | # 定义一个Pydantic数据格式,这个格式描述了一个"行动"类及其属性 11 | from pydantic import BaseModel, Field 12 | class Action(BaseModel): 13 | action: str = Field(description="action to take") 14 | action_input: str = Field(description="input to the action") 15 | 16 | # 使用Pydantic格式Action来初始化一个输出解析器 17 | from langchain.output_parsers import PydanticOutputParser 18 | parser = PydanticOutputParser(pydantic_object=Action) 19 | 20 | # 定义一个提示模板,它将用于向模型提问 21 | from langchain.prompts import PromptTemplate 22 | prompt = PromptTemplate( 23 | template="Answer the user query.\n{format_instructions}\n{query}\n", 24 | input_variables=["query"], 25 | partial_variables={"format_instructions": parser.get_format_instructions()}, 26 | ) 27 | prompt_value = prompt.format_prompt(query="What are the colors of Orchid?") 28 | 29 | # 定义一个错误格式的字符串 30 | bad_response = '{"action": "search"}' 31 | # parser.parse(bad_response) # 如果直接解析,它会引发一个错误 32 | 33 | # 设置OpenAI API密钥 34 | import os 35 | os.environ["OPENAI_API_KEY"] = 'Your OpenAI API Key' 36 | 37 | # 尝试用OutputFixingParser来解决这个问题 38 | from langchain.output_parsers import OutputFixingParser 39 | from langchain.chat_models import ChatOpenAI 40 | 41 | fix_parser = OutputFixingParser.from_llm(parser=parser, llm=ChatOpenAI()) 42 | parse_result = fix_parser.parse(bad_response) 43 | print('OutputFixingParser的parse结果:',parse_result) 44 | 45 | # 初始化RetryWithErrorOutputParser,它会尝试再次提问来得到一个正确的输出 46 | from langchain.output_parsers import RetryWithErrorOutputParser 47 | from langchain.llms import OpenAI 48 | retry_parser = RetryWithErrorOutputParser.from_llm( 49 | parser=parser, llm=OpenAI(temperature=0) 50 | ) 51 | parse_result = retry_parser.parse_with_prompt(bad_response, prompt_value) 52 | print('RetryWithErrorOutputParser的parse结果:',parse_result) -------------------------------------------------------------------------------- /08_链上/01_Without_Chain.py: -------------------------------------------------------------------------------- 1 | '''欢迎来到LangChain实战课 2 | https://time.geekbang.org/column/intro/100617601 3 | 作者 黄佳''' 4 | # 设置OpenAI API密钥 5 | import os 6 | os.environ["OPENAI_API_KEY"] = 'Your Key' 7 | 8 | #----第一步 创建提示 9 | # 导入LangChain中的提示模板 10 | from langchain import PromptTemplate 11 | # 原始字符串模板 12 | template = "{flower}的花语是?" 13 | # 创建LangChain模板 14 | prompt_temp = PromptTemplate.from_template(template) 15 | # 根据模板创建提示 16 | prompt = prompt_temp.format(flower='玫瑰') 17 | # 打印提示的内容 18 | print(prompt) 19 | 20 | #----第二步 创建并调用模型 21 | # 导入LangChain中的OpenAI模型接口 22 | from langchain import OpenAI 23 | # 创建模型实例 24 | model = OpenAI(temperature=0) 25 | # 传入提示,调用模型,返回结果 26 | result = model(prompt) 27 | print(result) -------------------------------------------------------------------------------- /08_链上/02_With_LLMChain.py: -------------------------------------------------------------------------------- 1 | '''欢迎来到LangChain实战课 2 | https://time.geekbang.org/column/intro/100617601 3 | 作者 黄佳''' 4 | # 设置OpenAI API密钥 5 | import os 6 | os.environ["OPENAI_API_KEY"] = 'Your Key' 7 | 8 | # 导入所需的库 9 | from langchain import PromptTemplate, OpenAI, LLMChain 10 | # 原始字符串模板 11 | template = "{flower}的花语是?" 12 | # 创建模型实例 13 | llm = OpenAI(temperature=0) 14 | # 创建LLMChain 15 | llm_chain = LLMChain( 16 | llm=llm, 17 | prompt=PromptTemplate.from_template(template)) 18 | # 调用LLMChain,返回结果 19 | result = llm_chain("玫瑰") 20 | print(result) -------------------------------------------------------------------------------- /08_链上/03_Running_Chain.py: -------------------------------------------------------------------------------- 1 | '''欢迎来到LangChain实战课 2 | https://time.geekbang.org/column/intro/100617601 3 | 作者 黄佳''' 4 | # 设置OpenAI API密钥 5 | import os 6 | os.environ["OPENAI_API_KEY"] = 'Your Key' 7 | 8 | # 导入所需库 9 | from langchain import PromptTemplate, OpenAI, LLMChain 10 | 11 | # 设置提示模板 12 | prompt = PromptTemplate( 13 | input_variables=["flower", "season"], 14 | template="{flower}在{season}的花语是?" 15 | ) 16 | 17 | # 初始化大模型 18 | llm = OpenAI(temperature=0) 19 | 20 | # 初始化链 21 | llm_chain = LLMChain(llm=llm, prompt=prompt) 22 | 23 | # 调用链 24 | response = llm_chain({ 25 | 'flower': "玫瑰", 26 | 'season': "夏季" 27 | }) 28 | print(response) 29 | 30 | # run方法 31 | llm_chain.run({ 32 | 'flower': "玫瑰", 33 | 'season': "夏季" 34 | }) 35 | 36 | # predict方法 37 | result = llm_chain.predict(flower="玫瑰", season="夏季") 38 | print(result) 39 | 40 | # apply方法允许您针对输入列表运行链 41 | input_list = [ 42 | {"flower": "玫瑰", 'season': "夏季"}, 43 | {"flower": "百合", 'season': "春季"}, 44 | {"flower": "郁金香", 'season': "秋季"} 45 | ] 46 | result = llm_chain.apply(input_list) 47 | print(result) 48 | 49 | # generate方法 50 | result = llm_chain.generate(input_list) 51 | print(result) -------------------------------------------------------------------------------- /08_链上/04_SequentialChain.py: -------------------------------------------------------------------------------- 1 | '''欢迎来到LangChain实战课 2 | https://time.geekbang.org/column/intro/100617601 3 | 作者 黄佳''' 4 | # 设置OpenAI API密钥 5 | import os 6 | os.environ["OPENAI_API_KEY"] = 'Your Key' 7 | 8 | # 导入所需要的库 9 | from langchain.llms import OpenAI 10 | from langchain.chains import LLMChain, SequentialChain 11 | from langchain.prompts import PromptTemplate 12 | 13 | # 第一个LLMChain:生成鲜花的介绍 14 | llm = OpenAI(temperature=.7) 15 | template = """ 16 | 你是一个植物学家。给定花的名称和类型,你需要为这种花写一个200字左右的介绍。 17 | 花名: {name} 18 | 颜色: {color} 19 | 植物学家: 这是关于上述花的介绍:""" 20 | prompt_template = PromptTemplate( 21 | input_variables=["name", "color"], 22 | template=template 23 | ) 24 | introduction_chain = LLMChain( 25 | llm=llm, 26 | prompt=prompt_template, 27 | output_key="introduction" 28 | ) 29 | 30 | # 第二个LLMChain:根据鲜花的介绍写出鲜花的评论 31 | template = """ 32 | 你是一位鲜花评论家。给定一种花的介绍,你需要为这种花写一篇200字左右的评论。 33 | 鲜花介绍: 34 | {introduction} 35 | 花评人对上述花的评论:""" 36 | prompt_template = PromptTemplate( 37 | input_variables=["introduction"], 38 | template=template 39 | ) 40 | review_chain = LLMChain( 41 | llm=llm, 42 | prompt=prompt_template, 43 | output_key="review" 44 | ) 45 | 46 | # 第三个LLMChain:根据鲜花的介绍和评论写出一篇自媒体的文案 47 | template = """ 48 | 你是一家花店的社交媒体经理。给定一种花的介绍和评论,你需要为这种花写一篇社交媒体的帖子,300字左右。 49 | 鲜花介绍: 50 | {introduction} 51 | 花评人对上述花的评论: 52 | {review} 53 | 社交媒体帖子: 54 | """ 55 | prompt_template = PromptTemplate( 56 | input_variables=["introduction", "review"], 57 | template=template 58 | ) 59 | social_post_chain = LLMChain( 60 | llm=llm, 61 | prompt=prompt_template, 62 | output_key="social_post_text" 63 | ) 64 | 65 | # 总的链:按顺序运行三个链 66 | overall_chain = SequentialChain( 67 | chains=[introduction_chain, review_chain, social_post_chain], 68 | input_variables=["name", "color"], 69 | output_variables=["introduction", "review", "social_post_text"], 70 | verbose=True 71 | ) 72 | 73 | # 运行链并打印结果 74 | result = overall_chain({ 75 | "name": "玫瑰", 76 | "color": "黑色" 77 | }) 78 | print(result) 79 | -------------------------------------------------------------------------------- /09_链下/Rounter_Chain.py: -------------------------------------------------------------------------------- 1 | '''欢迎来到LangChain实战课 2 | https://time.geekbang.org/column/intro/100617601 3 | 作者 黄佳''' 4 | import warnings 5 | warnings.filterwarnings('ignore') 6 | 7 | # 设置OpenAI API密钥 8 | import os 9 | os.environ["OPENAI_API_KEY"] = 'Your Key' 10 | 11 | # 构建两个场景的模板 12 | flower_care_template = """ 13 | 你是一个经验丰富的园丁,擅长解答关于养花育花的问题。 14 | 下面是需要你来回答的问题: 15 | {input} 16 | """ 17 | 18 | flower_deco_template = """ 19 | 你是一位网红插花大师,擅长解答关于鲜花装饰的问题。 20 | 下面是需要你来回答的问题: 21 | {input} 22 | """ 23 | 24 | # 构建提示信息 25 | prompt_infos = [ 26 | { 27 | "key": "flower_care", 28 | "description": "适合回答关于鲜花护理的问题", 29 | "template": flower_care_template, 30 | }, 31 | { 32 | "key": "flower_decoration", 33 | "description": "适合回答关于鲜花装饰的问题", 34 | "template": flower_deco_template, 35 | } 36 | ] 37 | 38 | # 初始化语言模型 39 | from langchain.llms import OpenAI 40 | llm = OpenAI() 41 | 42 | # 构建目标链 43 | from langchain.chains.llm import LLMChain 44 | from langchain.prompts import PromptTemplate 45 | 46 | chain_map = {} 47 | 48 | for info in prompt_infos: 49 | prompt = PromptTemplate( 50 | template=info['template'], 51 | input_variables=["input"] 52 | ) 53 | print("目标提示:\n", prompt) 54 | 55 | chain = LLMChain( 56 | llm=llm, 57 | prompt=prompt, 58 | verbose=True 59 | ) 60 | chain_map[info["key"]] = chain 61 | 62 | # 构建路由链 63 | from langchain.chains.router.llm_router import LLMRouterChain, RouterOutputParser 64 | from langchain.chains.router.multi_prompt_prompt import MULTI_PROMPT_ROUTER_TEMPLATE as RounterTemplate 65 | 66 | destinations = [f"{p['key']}: {p['description']}" for p in prompt_infos] 67 | router_template = RounterTemplate.format(destinations="\n".join(destinations)) 68 | print("路由模板:\n", router_template) 69 | 70 | router_prompt = PromptTemplate( 71 | template=router_template, 72 | input_variables=["input"], 73 | output_parser=RouterOutputParser(), 74 | ) 75 | print("路由提示:\n", router_prompt) 76 | 77 | router_chain = LLMRouterChain.from_llm( 78 | llm, 79 | router_prompt, 80 | verbose=True 81 | ) 82 | 83 | # 构建默认链 84 | from langchain.chains import ConversationChain 85 | 86 | default_chain = ConversationChain( 87 | llm=llm, 88 | output_key="text", 89 | verbose=True 90 | ) 91 | 92 | # 构建多提示链 93 | from langchain.chains.router import MultiPromptChain 94 | 95 | chain = MultiPromptChain( 96 | router_chain=router_chain, 97 | destination_chains=chain_map, 98 | default_chain=default_chain, 99 | verbose=True 100 | ) 101 | 102 | # 测试1 103 | print(chain.run("如何为玫瑰浇水?")) 104 | # 测试2 105 | print(chain.run("如何为婚礼场地装饰花朵?")) 106 | # 测试3 107 | print(chain.run("如何区分阿豆和罗豆?")) -------------------------------------------------------------------------------- /10_记忆/01_ConversationChain.py: -------------------------------------------------------------------------------- 1 | '''欢迎来到LangChain实战课 2 | https://time.geekbang.org/column/intro/100617601 3 | 作者 黄佳''' 4 | # 设置OpenAI API密钥 5 | import os 6 | os.environ["OPENAI_API_KEY"] = 'Your Key' 7 | 8 | # 导入所需的库 9 | from langchain import OpenAI 10 | from langchain.chains import ConversationChain 11 | 12 | # 初始化大语言模型 13 | llm = OpenAI( 14 | temperature=0.5, 15 | model_name="text-davinci-003" 16 | ) 17 | 18 | # 初始化对话链 19 | conv_chain = ConversationChain(llm=llm) 20 | 21 | # 打印对话的模板 22 | print(conv_chain.prompt.template) -------------------------------------------------------------------------------- /10_记忆/02_ConversationBufferMemory.py: -------------------------------------------------------------------------------- 1 | '''欢迎来到LangChain实战课 2 | https://time.geekbang.org/column/intro/100617601 3 | 作者 黄佳''' 4 | # 设置OpenAI API密钥 5 | import os 6 | os.environ["OPENAI_API_KEY"] = 'Your Key' 7 | 8 | # 导入所需的库 9 | from langchain import OpenAI 10 | from langchain.chains import ConversationChain 11 | from langchain.chains.conversation.memory import ConversationBufferMemory 12 | 13 | # 初始化大语言模型 14 | llm = OpenAI( 15 | temperature=0.5, 16 | model_name="text-davinci-003" 17 | ) 18 | 19 | # 初始化对话链 20 | conversation = ConversationChain( 21 | llm=llm, 22 | memory=ConversationBufferMemory() 23 | ) 24 | 25 | # 第一天的对话 26 | # 回合1 27 | conversation("我姐姐明天要过生日,我需要一束生日花束。") 28 | print("第一次对话后的记忆:", conversation.memory.buffer) 29 | 30 | # 回合2 31 | conversation("她喜欢粉色玫瑰,颜色是粉色的。") 32 | print("第二次对话后的记忆:", conversation.memory.buffer) 33 | 34 | # 回合3 (第二天的对话) 35 | conversation("我又来了,还记得我昨天为什么要来买花吗?") 36 | print("/n第三次对话后时提示:/n",conversation.prompt.template) 37 | print("/n第三次对话后的记忆:/n", conversation.memory.buffer) 38 | 39 | -------------------------------------------------------------------------------- /10_记忆/03_ConversationBufferWindowMemory.py: -------------------------------------------------------------------------------- 1 | '''欢迎来到LangChain实战课 2 | https://time.geekbang.org/column/intro/100617601 3 | 作者 黄佳''' 4 | # 设置OpenAI API密钥 5 | import os 6 | os.environ["OPENAI_API_KEY"] = 'Your Key' 7 | 8 | # 导入所需的库 9 | from langchain import OpenAI 10 | from langchain.chains import ConversationChain 11 | from langchain.chains.conversation.memory import ConversationBufferWindowMemory 12 | 13 | # 初始化大语言模型 14 | llm = OpenAI( 15 | temperature=0.5, 16 | model_name="text-davinci-003" 17 | ) 18 | 19 | # 初始化对话链 20 | conversation = ConversationChain( 21 | llm=llm, 22 | memory=ConversationBufferWindowMemory(k=1) 23 | ) 24 | 25 | # 第一天的对话 26 | # 回合1 27 | result = conversation("我姐姐明天要过生日,我需要一束生日花束。") 28 | print(result) 29 | # 回合2 30 | result = conversation("她喜欢粉色玫瑰,颜色是粉色的。") 31 | # print("\n第二次对话后的记忆:\n", conversation.memory.buffer) 32 | print(result) 33 | 34 | # 第二天的对话 35 | # 回合3 36 | result = conversation("我又来了,还记得我昨天为什么要来买花吗?") 37 | print(result) 38 | -------------------------------------------------------------------------------- /10_记忆/04_ConversationSummaryMemory.py: -------------------------------------------------------------------------------- 1 | '''欢迎来到LangChain实战课 2 | https://time.geekbang.org/column/intro/100617601 3 | 作者 黄佳''' 4 | # 设置OpenAI API密钥 5 | import os 6 | os.environ["OPENAI_API_KEY"] = 'Your Key' 7 | 8 | # 导入所需的库 9 | from langchain import OpenAI 10 | from langchain.chains import ConversationChain 11 | from langchain.chains.conversation.memory import ConversationSummaryMemory 12 | 13 | # 初始化大语言模型 14 | llm = OpenAI( 15 | temperature=0.5, 16 | model_name="text-davinci-003" 17 | ) 18 | 19 | # 初始化对话链 20 | conversation = ConversationChain( 21 | llm=llm, 22 | memory=ConversationSummaryMemory(llm=llm) 23 | ) 24 | 25 | # 第一天的对话 26 | # 回合1 27 | result = conversation("我姐姐明天要过生日,我需要一束生日花束。") 28 | print(result) 29 | # 回合2 30 | result = conversation("她喜欢粉色玫瑰,颜色是粉色的。") 31 | # print("\n第二次对话后的记忆:\n", conversation.memory.buffer) 32 | print(result) 33 | 34 | # 第二天的对话 35 | # 回合3 36 | result = conversation("我又来了,还记得我昨天为什么要来买花吗?") 37 | print(result) -------------------------------------------------------------------------------- /10_记忆/05_ConversationSummaryBufferMemory.py: -------------------------------------------------------------------------------- 1 | '''欢迎来到LangChain实战课 2 | https://time.geekbang.org/column/intro/100617601 3 | 作者 黄佳''' 4 | # 设置OpenAI API密钥 5 | import os 6 | os.environ["OPENAI_API_KEY"] = 'Your Key' 7 | 8 | # 导入所需的库 9 | from langchain import OpenAI 10 | from langchain.chains import ConversationChain 11 | from langchain.chains.conversation.memory import ConversationSummaryBufferMemory 12 | 13 | # 初始化大语言模型 14 | llm = OpenAI( 15 | temperature=0.5, 16 | model_name="text-davinci-003" 17 | ) 18 | 19 | # 初始化对话链 20 | conversation = ConversationChain( 21 | llm=llm, 22 | memory=ConversationSummaryBufferMemory( 23 | llm=llm, 24 | max_token_limit=300 25 | ) 26 | ) 27 | 28 | # 第一天的对话 29 | # 回合1 30 | result = conversation("我姐姐明天要过生日,我需要一束生日花束。") 31 | print(result) 32 | # 回合2 33 | result = conversation("她喜欢粉色玫瑰,颜色是粉色的。") 34 | # print("\n第二次对话后的记忆:\n", conversation.memory.buffer) 35 | print(result) 36 | 37 | # 第二天的对话 38 | # 回合3 39 | result = conversation("我又来了,还记得我昨天为什么要来买花吗?") 40 | print(result) -------------------------------------------------------------------------------- /11_代理上/ReActAgent.py: -------------------------------------------------------------------------------- 1 | '''欢迎来到LangChain实战课 2 | https://time.geekbang.org/column/intro/100617601 3 | 作者 黄佳''' 4 | # 设置OpenAI和SERPAPI的API密钥 5 | import os 6 | os.environ["OPENAI_API_KEY"] = 'Your OpenAI API Key' 7 | os.environ["SERPAPI_API_KEY"] = 'Your SerpAPI API Key' 8 | 9 | # 加载所需的库 10 | from langchain.agents import load_tools 11 | from langchain.agents import initialize_agent 12 | from langchain.agents import AgentType 13 | from langchain.llms import OpenAI 14 | 15 | # 初始化大模型 16 | llm = OpenAI(temperature=0) 17 | 18 | # 设置工具 19 | tools = load_tools(["serpapi", "llm-math"], llm=llm) 20 | 21 | # 初始化Agent 22 | agent = initialize_agent(tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True) 23 | 24 | # 跑起来 25 | agent.run("目前市场上玫瑰花的平均价格是多少?如果我在此基础上加价15%卖出,应该如何定价?") -------------------------------------------------------------------------------- /12_代理中/ReActAgent_with_Debug.py: -------------------------------------------------------------------------------- 1 | '''欢迎来到LangChain实战课 2 | https://time.geekbang.org/column/intro/100617601 3 | 作者 黄佳''' 4 | # 设置OpenAI和SERPAPI的API密钥 5 | import os 6 | os.environ["OPENAI_API_KEY"] = 'Your OpenAI Key' 7 | os.environ["SERPAPI_API_KEY"] = 'Your SerpAPT Key' 8 | 9 | # 试一试LangChain的Debug和Verbose,看看有何区别 10 | import langchain 11 | # langchain.debug = True 12 | langchain.verbose = True 13 | 14 | # 配置日志输出 15 | import logging 16 | import sys 17 | logging.basicConfig(stream=sys.stdout, level=logging.DEBUG) 18 | logging.getLogger().addHandler(logging.StreamHandler(stream=sys.stdout)) 19 | 20 | # 跟踪与openai的通信 21 | import openai 22 | openai.api_key = os.environ["OPENAI_API_KEY"] 23 | # openai.log = "debug" 24 | 25 | # 加载所需的库 26 | from langchain.agents import load_tools 27 | from langchain.agents import initialize_agent 28 | from langchain.agents import AgentType 29 | from langchain.llms import OpenAI 30 | 31 | # 初始化大模型 32 | llm = OpenAI(temperature=0) 33 | 34 | # 设置工具 35 | tools = load_tools(["serpapi", "llm-math"], llm=llm) 36 | 37 | # 初始化Agent 38 | agent = initialize_agent(tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True) 39 | 40 | # 跑起来 41 | agent.run("目前市场上玫瑰花的平均价格是多少?如果我在此基础上加价15%卖出,应该如何定价?") -------------------------------------------------------------------------------- /13_代理下/Plan&Execute.py: -------------------------------------------------------------------------------- 1 | '''欢迎来到LangChain实战课 2 | https://time.geekbang.org/column/intro/100617601 3 | 作者 黄佳''' 4 | # 设置OpenAI和SERPAPI的API密钥 5 | import os 6 | os.environ["OPENAI_API_KEY"] = 'Your Key' 7 | os.environ["SERPAPI_API_KEY"] = 'Your Key' 8 | 9 | from langchain.chat_models import ChatOpenAI 10 | from langchain_experimental.plan_and_execute import PlanAndExecute, load_agent_executor, load_chat_planner 11 | from langchain.llms import OpenAI 12 | from langchain import SerpAPIWrapper 13 | from langchain.agents.tools import Tool 14 | from langchain import LLMMathChain 15 | 16 | search = SerpAPIWrapper() 17 | llm = OpenAI(temperature=0) 18 | llm_math_chain = LLMMathChain.from_llm(llm=llm, verbose=True) 19 | tools = [ 20 | Tool( 21 | name = "Search", 22 | func=search.run, 23 | description="useful for when you need to answer questions about current events" 24 | ), 25 | Tool( 26 | name="Calculator", 27 | func=llm_math_chain.run, 28 | description="useful for when you need to answer questions about math" 29 | ), 30 | ] 31 | model = ChatOpenAI(temperature=0) 32 | planner = load_chat_planner(model) 33 | executor = load_agent_executor(model, tools, verbose=True) 34 | agent = PlanAndExecute(planner=planner, executor=executor, verbose=True) 35 | 36 | agent.run("在纽约,100美元能买几束玫瑰?") -------------------------------------------------------------------------------- /13_代理下/SelfAskwithSearch.py: -------------------------------------------------------------------------------- 1 | '''欢迎来到LangChain实战课 2 | https://time.geekbang.org/column/intro/100617601 3 | 作者 黄佳''' 4 | # 设置OpenAI和SERPAPI的API密钥 5 | import os 6 | os.environ["OPENAI_API_KEY"] = 'Your Key' 7 | os.environ["SERPAPI_API_KEY"] = 'Your Key' 8 | 9 | from langchain import OpenAI, SerpAPIWrapper 10 | from langchain.agents import initialize_agent, Tool 11 | from langchain.agents import AgentType 12 | 13 | llm = OpenAI(temperature=0) 14 | search = SerpAPIWrapper() 15 | tools = [ 16 | Tool( 17 | name="Intermediate Answer", 18 | func=search.run, 19 | description="useful for when you need to ask with search", 20 | ) 21 | ] 22 | 23 | self_ask_with_search = initialize_agent( 24 | tools, llm, agent=AgentType.SELF_ASK_WITH_SEARCH, verbose=True 25 | ) 26 | self_ask_with_search.run( 27 | "使用玫瑰作为国花的国家的首都是哪里?" 28 | ) -------------------------------------------------------------------------------- /13_代理下/StructedToolChat.py: -------------------------------------------------------------------------------- 1 | '''欢迎来到LangChain实战课 2 | https://time.geekbang.org/column/intro/100617601 3 | 作者 黄佳''' 4 | # 设置OpenAIAPI密钥 5 | import os 6 | os.environ["OPENAI_API_KEY"] = 'Your Key' 7 | 8 | from langchain.agents.agent_toolkits import PlayWrightBrowserToolkit 9 | from langchain.tools.playwright.utils import create_async_playwright_browser 10 | 11 | async_browser = create_async_playwright_browser() 12 | toolkit = PlayWrightBrowserToolkit.from_browser(async_browser=async_browser) 13 | tools = toolkit.get_tools() 14 | print(tools) 15 | 16 | from langchain.agents import initialize_agent, AgentType 17 | from langchain.chat_models import ChatOpenAI 18 | 19 | # LLM不稳定,对于这个任务,可能要多跑几次才能得到正确结果 20 | llm = ChatOpenAI(temperature=0.5) 21 | 22 | agent_chain = initialize_agent( 23 | tools, 24 | llm, 25 | agent=AgentType.STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION, 26 | verbose=True, 27 | ) 28 | 29 | async def main(): 30 | response = await agent_chain.arun("What are the headers on python.langchain.com?") 31 | print(response) 32 | 33 | import asyncio 34 | loop = asyncio.get_event_loop() 35 | loop.run_until_complete(main()) -------------------------------------------------------------------------------- /14_工具/01_arxiv.py: -------------------------------------------------------------------------------- 1 | # 设置OpenAI API的密钥 2 | import os 3 | os.environ["OPENAI_API_KEY"] = 'Your key' 4 | 5 | # 导入库 6 | from langchain.chat_models import ChatOpenAI 7 | from langchain.agents import load_tools, initialize_agent, AgentType 8 | 9 | # 初始化模型和工具 10 | llm = ChatOpenAI(temperature=0.0) 11 | tools = load_tools( 12 | ["arxiv"], 13 | ) 14 | 15 | # 初始化链 16 | agent_chain = initialize_agent( 17 | tools, 18 | llm, 19 | agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, 20 | verbose=True, 21 | ) 22 | 23 | # 运行链 24 | agent_chain.run("介绍一下2005.14165这篇论文的创新点?") -------------------------------------------------------------------------------- /14_工具/02_GmailToken.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | 3 | import os.path 4 | 5 | from google.auth.transport.requests import Request 6 | from google.oauth2.credentials import Credentials 7 | from google_auth_oauthlib.flow import InstalledAppFlow 8 | from googleapiclient.discovery import build 9 | from googleapiclient.errors import HttpError 10 | 11 | # If modifying these scopes, delete the file token.json. 12 | SCOPES = ['https://www.googleapis.com/auth/gmail.readonly'] 13 | 14 | 15 | def main(): 16 | """Shows basic usage of the Gmail API. 17 | Lists the user's Gmail labels. 18 | """ 19 | creds = None 20 | # The file token.json stores the user's access and refresh tokens, and is 21 | # created automatically when the authorization flow completes for the first 22 | # time. 23 | if os.path.exists('token.json'): 24 | creds = Credentials.from_authorized_user_file('token.json', SCOPES) 25 | # If there are no (valid) credentials available, let the user log in. 26 | if not creds or not creds.valid: 27 | if creds and creds.expired and creds.refresh_token: 28 | creds.refresh(Request()) 29 | else: 30 | flow = InstalledAppFlow.from_client_secrets_file( 31 | 'credentials.json', SCOPES) 32 | creds = flow.run_local_server(port=8088) 33 | # Save the credentials for the next run 34 | with open('token.json', 'w') as token: 35 | token.write(creds.to_json()) 36 | 37 | try: 38 | # Call the Gmail API 39 | service = build('gmail', 'v1', credentials=creds) 40 | results = service.users().labels().list(userId='me').execute() 41 | labels = results.get('labels', []) 42 | 43 | if not labels: 44 | print('No labels found.') 45 | return 46 | print('Labels:') 47 | for label in labels: 48 | print(label['name']) 49 | 50 | except HttpError as error: 51 | # TODO(developer) - Handle errors from gmail API. 52 | print(f'An error occurred: {error}') 53 | 54 | 55 | if __name__ == '__main__': 56 | main() 57 | -------------------------------------------------------------------------------- /14_工具/03_GmailToolkit.py: -------------------------------------------------------------------------------- 1 | # 设置OpenAI API的密钥 2 | import os 3 | os.environ["OPENAI_API_KEY"] = 'Your Key' 4 | 5 | # 导入与Gmail交互所需的工具包 6 | from langchain.agents.agent_toolkits import GmailToolkit 7 | 8 | # 初始化Gmail工具包 9 | toolkit = GmailToolkit() 10 | 11 | # 从gmail工具中导入一些有用的功能 12 | from langchain.tools.gmail.utils import build_resource_service, get_gmail_credentials 13 | 14 | # 获取Gmail API的凭证,并指定相关的权限范围 15 | credentials = get_gmail_credentials( 16 | token_file="token.json", # Token文件路径 17 | scopes=["https://mail.google.com/"], # 具有完全的邮件访问权限 18 | client_secrets_file="credentials.json", # 客户端的秘密文件路径 19 | ) 20 | # 使用凭证构建API资源服务 21 | api_resource = build_resource_service(credentials=credentials) 22 | toolkit = GmailToolkit(api_resource=api_resource) 23 | 24 | # 获取工具 25 | tools = toolkit.get_tools() 26 | print(tools) 27 | 28 | # 导入与聊天模型相关的包 29 | from langchain.chat_models import ChatOpenAI 30 | from langchain.agents import initialize_agent, AgentType 31 | 32 | # 初始化聊天模型 33 | llm = ChatOpenAI(temperature=0, model='gpt-4') 34 | 35 | # 通过指定的工具和聊天模型初始化agent 36 | agent = initialize_agent( 37 | tools=toolkit.get_tools(), 38 | llm=llm, 39 | agent=AgentType.STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION, 40 | ) 41 | 42 | # 使用agent运行一些查询或指令 43 | result = agent.run( 44 | "今天易速鲜花客服给我发邮件了么?最新的邮件是谁发给我的?" 45 | ) 46 | 47 | # 打印结果 48 | print(result) -------------------------------------------------------------------------------- /15_RAG应用/01_Embedding.py: -------------------------------------------------------------------------------- 1 | # 设置OpenAI的API密钥 2 | import os 3 | os.environ["OPENAI_API_KEY"] = 'Your OpenAI Key' 4 | 5 | # 初始化Embedding类 6 | from langchain.embeddings import OpenAIEmbeddings 7 | embeddings_model = OpenAIEmbeddings() 8 | 9 | # Embed文本 10 | embeddings = embeddings_model.embed_documents( 11 | [ 12 | "您好,有什么需要帮忙的吗?", 13 | "哦,你好!昨天我订的花几天送达", 14 | "请您提供一些订单号?", 15 | "12345678", 16 | ] 17 | ) 18 | print(len(embeddings), len(embeddings[0])) 19 | 20 | # Embed查询 21 | embedded_query = embeddings_model.embed_query("刚才对话中的订单号是多少?") 22 | print(embedded_query[:3]) -------------------------------------------------------------------------------- /15_RAG应用/02_InMemoryStore.py: -------------------------------------------------------------------------------- 1 | # 设置OpenAI的API密钥 2 | import os 3 | os.environ["OPENAI_API_KEY"] = 'Your OpenAI Key' 4 | 5 | # 导入内存存储库,该库允许我们在RAM中临时存储数据 6 | from langchain.storage import InMemoryStore 7 | 8 | # 创建一个InMemoryStore的实例 9 | store = InMemoryStore() 10 | 11 | # 导入与嵌入相关的库。OpenAIEmbeddings是用于生成嵌入的工具,而CacheBackedEmbeddings允许我们缓存这些嵌入 12 | from langchain.embeddings import OpenAIEmbeddings, CacheBackedEmbeddings 13 | 14 | # 创建一个OpenAIEmbeddings的实例,这将用于实际计算文档的嵌入 15 | underlying_embeddings = OpenAIEmbeddings() 16 | 17 | # 创建一个CacheBackedEmbeddings的实例。 18 | # 这将为underlying_embeddings提供缓存功能,嵌入会被存储在上面创建的InMemoryStore中。 19 | # 我们还为缓存指定了一个命名空间,以确保不同的嵌入模型之间不会出现冲突。 20 | embedder = CacheBackedEmbeddings.from_bytes_store( 21 | underlying_embeddings, # 实际生成嵌入的工具 22 | store, # 嵌入的缓存位置 23 | namespace=underlying_embeddings.model # 嵌入缓存的命名空间 24 | ) 25 | 26 | # 使用embedder为两段文本生成嵌入。 27 | # 结果,即嵌入向量,将被存储在上面定义的内存存储中。 28 | embeddings = embedder.embed_documents(["你好", "智能鲜花客服"]) -------------------------------------------------------------------------------- /15_RAG应用/03_VectorstoreIndex.py: -------------------------------------------------------------------------------- 1 | # 设置OpenAI的API密钥 2 | import os 3 | os.environ["OPENAI_API_KEY"] = 'Your OpenAI Key' 4 | 5 | # 导入文档加载器模块,并使用TextLoader来加载文本文件 6 | from langchain.document_loaders import TextLoader 7 | loader = TextLoader('./OneFlower/易速鲜花花语大全.txt', encoding='utf8') 8 | 9 | # 使用VectorstoreIndexCreator来从加载器创建索引 10 | from langchain.indexes import VectorstoreIndexCreator 11 | index = VectorstoreIndexCreator().from_loaders([loader]) 12 | 13 | # 定义查询字符串, 使用创建的索引执行查询 14 | query = "玫瑰花的花语是什么?" 15 | result = index.query(query) 16 | print(result) # 打印查询结果 17 | 18 | 19 | # 替换成你所需要的工具 20 | from langchain.text_splitter import CharacterTextSplitter 21 | text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0) 22 | from langchain.vectorstores import Chroma 23 | from langchain.embeddings import OpenAIEmbeddings 24 | embeddings = OpenAIEmbeddings() 25 | index_creator = VectorstoreIndexCreator( 26 | vectorstore_cls=Chroma, 27 | embedding=OpenAIEmbeddings(), 28 | text_splitter=CharacterTextSplitter(chunk_size=1000, chunk_overlap=0) 29 | ) -------------------------------------------------------------------------------- /16_操作数据库/01_DBCreation.py: -------------------------------------------------------------------------------- 1 | # 导入sqlite3库,它是Python内置的轻量级数据库。 2 | import sqlite3 3 | 4 | # 连接到数据库 5 | conn = sqlite3.connect('FlowerShop.db') 6 | cursor = conn.cursor() 7 | 8 | # 执行SQL命令来创建Flowers表 9 | cursor.execute(''' 10 | CREATE TABLE Flowers ( 11 | ID INTEGER PRIMARY KEY, 12 | Name TEXT NOT NULL, 13 | Type TEXT NOT NULL, 14 | Source TEXT NOT NULL, 15 | PurchasePrice REAL, 16 | SalePrice REAL, 17 | StockQuantity INTEGER, 18 | SoldQuantity INTEGER, 19 | ExpiryDate DATE, 20 | Description TEXT, 21 | EntryDate DATE DEFAULT CURRENT_DATE 22 | ); 23 | ''') 24 | 25 | # 插入5种鲜花的数据 26 | flowers = [ 27 | ('Rose', 'Flower', 'France', 1.2, 2.5, 100, 10, '2023-12-31', 'A beautiful red rose'), 28 | ('Tulip', 'Flower', 'Netherlands', 0.8, 2.0, 150, 25, '2023-12-31', 'A colorful tulip'), 29 | ('Lily', 'Flower', 'China', 1.5, 3.0, 80, 5, '2023-12-31', 'An elegant white lily'), 30 | ('Daisy', 'Flower', 'USA', 0.7, 1.8, 120, 15, '2023-12-31', 'A cheerful daisy flower'), 31 | ('Orchid', 'Flower', 'Brazil', 2.0, 4.0, 50, 2, '2023-12-31', 'A delicate purple orchid') 32 | ] 33 | 34 | for flower in flowers: 35 | cursor.execute(''' 36 | INSERT INTO Flowers (Name, Type, Source, PurchasePrice, SalePrice, StockQuantity, SoldQuantity, ExpiryDate, Description) 37 | VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?); 38 | ''', flower) 39 | 40 | # 提交更改 41 | conn.commit() 42 | 43 | # 关闭数据库连接 44 | conn.close() 45 | -------------------------------------------------------------------------------- /16_操作数据库/02_SQL_LLM.py: -------------------------------------------------------------------------------- 1 | import os 2 | os.environ["OPENAI_API_KEY"] = 'Your OpenAI Key' 3 | 4 | # 导入langchain的实用工具和相关的模块 5 | from langchain.utilities import SQLDatabase 6 | from langchain.llms import OpenAI 7 | from langchain_experimental.sql import SQLDatabaseChain 8 | 9 | # 连接到FlowerShop数据库(之前我们使用的是Chinook.db) 10 | db = SQLDatabase.from_uri("sqlite:///FlowerShop.db") 11 | 12 | # 创建OpenAI的低级语言模型(LLM)实例,这里我们设置温度为0,意味着模型输出会更加确定性 13 | llm = OpenAI(temperature=0, verbose=True) 14 | 15 | # 创建SQL数据库链实例,它允许我们使用LLM来查询SQL数据库 16 | db_chain = SQLDatabaseChain.from_llm(llm, db, verbose=True) 17 | 18 | # 运行与鲜花运营相关的问题 19 | response = db_chain.run("有多少种不同的鲜花?") 20 | print(response) 21 | 22 | response = db_chain.run("哪种鲜花的存货数量最少?") 23 | print(response) 24 | 25 | response = db_chain.run("平均销售价格是多少?") 26 | print(response) 27 | 28 | response = db_chain.run("从法国进口的鲜花有多少种?") 29 | print(response) 30 | 31 | response = db_chain.run("哪种鲜花的销售量最高?") 32 | print(response) 33 | 34 | 35 | '''> Entering new SQLDatabaseChain chain... 36 | 有多少种不同的鲜花? 37 | SQLQuery:SELECT COUNT(DISTINCT "Name") FROM "Flowers"; 38 | SQLResult: [(5,)] 39 | Answer:有5种不同的鲜花。 40 | > Finished chain. 41 | 有5种不同的鲜花。 42 | 43 | 44 | > Entering new SQLDatabaseChain chain... 45 | 哪种鲜花的存货数量最少? 46 | SQLQuery:SELECT "Name", "StockQuantity" FROM "Flowers" ORDER BY "StockQuantity" ASC LIMIT 5; 47 | SQLResult: [('Orchid', 50), ('Lily', 80), ('Rose', 100), ('Daisy', 120), ('Tulip', 150)] 48 | Answer:Orchid的存货数量最少。 49 | > Finished chain. 50 | Orchid的存货数量最少。 51 | 52 | 53 | > Entering new SQLDatabaseChain chain... 54 | 平均销售价格是多少? 55 | SQLQuery:SELECT AVG("SalePrice") FROM "Flowers"; 56 | SQLResult: [(2.66,)] 57 | Answer:平均销售价格是2.66。 58 | > Finished chain. 59 | 平均销售价格是2.66。 60 | 61 | 62 | > Entering new SQLDatabaseChain chain... 63 | 从法国进口的鲜花有多少种? 64 | SQLQuery:SELECT COUNT(*) FROM "Flowers" WHERE "Source" = 'France'; 65 | SQLResult: [(1,)] 66 | Answer:从法国进口的鲜花有1种。 67 | > Finished chain. 68 | 从法国进口的鲜花有1种。 69 | 70 | 71 | > Entering new SQLDatabaseChain chain... 72 | 哪种鲜花的销售量最高? 73 | SQLQuery:SELECT "Name", "SoldQuantity" FROM "Flowers" ORDER BY "SoldQuantity" DESC LIMIT 5; 74 | SQLResult: [('Tulip', 25), ('Daisy', 15), ('Rose', 10), ('Lily', 5), ('Orchid', 2)] 75 | Answer:Tulip的销售量最高。 76 | > Finished chain. 77 | Tulip的销售量最高。''' 78 | -------------------------------------------------------------------------------- /16_操作数据库/03_SQL_Agent.py: -------------------------------------------------------------------------------- 1 | import os 2 | os.environ["OPENAI_API_KEY"] = 'Your OpenAI Key' 3 | 4 | from langchain.utilities import SQLDatabase 5 | from langchain.llms import OpenAI 6 | from langchain.agents import create_sql_agent 7 | from langchain.agents.agent_toolkits import SQLDatabaseToolkit 8 | from langchain.agents.agent_types import AgentType 9 | 10 | # 连接到FlowerShop数据库 11 | db = SQLDatabase.from_uri("sqlite:///FlowerShop.db") 12 | llm = OpenAI(temperature=0, verbose=True) 13 | 14 | # 创建SQL Agent 15 | agent_executor = create_sql_agent( 16 | llm=llm, 17 | toolkit=SQLDatabaseToolkit(db=db, llm=llm), 18 | verbose=True, 19 | agent_type=AgentType.ZERO_SHOT_REACT_DESCRIPTION, 20 | ) 21 | 22 | # 使用Agent执行SQL查询 23 | questions = [ 24 | "哪种鲜花的存货数量最少?", 25 | "平均销售价格是多少?", 26 | ] 27 | 28 | for question in questions: 29 | response = agent_executor.run(question) 30 | print(response) 31 | -------------------------------------------------------------------------------- /17_回调函数/01_Callback.py: -------------------------------------------------------------------------------- 1 | def compute(x, y, callback): 2 | result = x + y 3 | callback(result) 4 | 5 | def print_result(value): 6 | print(f"The result is: {value}") 7 | 8 | def square_result(value): 9 | print(f"The squared result is: {value**2}") 10 | 11 | # 使用print_result作为回调 12 | compute(3, 4, print_result) # 输出: The result is: 7 13 | 14 | # 使用square_result作为回调 15 | compute(3, 4, square_result) # 输出: The squared result is: 49 16 | -------------------------------------------------------------------------------- /17_回调函数/02_Async_Callback.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | 3 | async def compute(x, y, callback): 4 | print("Starting compute...") 5 | await asyncio.sleep(0.5) # 模拟异步操作 6 | result = x + y 7 | # callback(result) 8 | print("Finished compute...") 9 | 10 | def print_result(value): 11 | print(f"The result is: {value}") 12 | 13 | async def another_task(): 14 | print("Starting another task...") 15 | await asyncio.sleep(1) 16 | print("Finished another task...") 17 | 18 | async def main(): 19 | print("Main starts...") 20 | task1 = asyncio.create_task(compute(3, 4, print_result)) 21 | task2 = asyncio.create_task(another_task()) 22 | 23 | await task1 24 | await task2 25 | print("Main ends...") 26 | 27 | asyncio.run(main()) -------------------------------------------------------------------------------- /17_回调函数/03_LangChainOpenAICallback.py: -------------------------------------------------------------------------------- 1 | # 设置OpenAI API密钥 2 | import os 3 | os.environ["OPENAI_API_KEY"] = 'Your OpenAI Key' 4 | 5 | import asyncio 6 | from langchain import OpenAI 7 | from langchain.chains import ConversationChain 8 | from langchain.chains.conversation.memory import ConversationBufferMemory 9 | from langchain.callbacks import get_openai_callback 10 | 11 | # 初始化大语言模型 12 | llm = OpenAI(temperature=0.5, model_name="text-davinci-003") 13 | 14 | # 初始化对话链 15 | conversation = ConversationChain( 16 | llm=llm, 17 | memory=ConversationBufferMemory() 18 | ) 19 | 20 | # 使用context manager进行token counting 21 | with get_openai_callback() as cb: 22 | # 第一天的对话 23 | # 回合1 24 | conversation("我姐姐明天要过生日,我需要一束生日花束。") 25 | print("第一次对话后的记忆:", conversation.memory.buffer) 26 | 27 | # 回合2 28 | conversation("她喜欢粉色玫瑰,颜色是粉色的。") 29 | print("第二次对话后的记忆:", conversation.memory.buffer) 30 | 31 | # 回合3 (第二天的对话) 32 | conversation("我又来了,还记得我昨天为什么要来买花吗?") 33 | print("/n第三次对话后时提示:/n",conversation.prompt.template) 34 | print("/n第三次对话后的记忆:/n", conversation.memory.buffer) 35 | 36 | # 输出使用的tokens 37 | print("\n总计使用的tokens:", cb.total_tokens) 38 | 39 | # 进行更多的异步交互和token计数 40 | async def additional_interactions(): 41 | with get_openai_callback() as cb: 42 | await asyncio.gather( 43 | *[llm.agenerate(["我姐姐喜欢什么颜色的花?"]) for _ in range(3)] 44 | ) 45 | print("\n另外的交互中使用的tokens:", cb.total_tokens) 46 | 47 | # 运行异步函数 48 | asyncio.run(additional_interactions()) 49 | -------------------------------------------------------------------------------- /17_回调函数/04_LangChainCustomCallback.py: -------------------------------------------------------------------------------- 1 | # 设置OpenAI API密钥 2 | import os 3 | os.environ["OPENAI_API_KEY"] = 'Your OpenAI Key' 4 | 5 | import asyncio 6 | from typing import Any, Dict, List 7 | 8 | from langchain.chat_models import ChatOpenAI 9 | from langchain.schema import LLMResult, HumanMessage 10 | from langchain.callbacks.base import AsyncCallbackHandler, BaseCallbackHandler 11 | 12 | # 创建同步回调处理器 13 | class MyFlowerShopSyncHandler(BaseCallbackHandler): 14 | def on_llm_new_token(self, token: str, **kwargs) -> None: 15 | print(f"获取花卉数据: token: {token}") 16 | 17 | # 创建异步回调处理器 18 | class MyFlowerShopAsyncHandler(AsyncCallbackHandler): 19 | 20 | async def on_llm_start( 21 | self, serialized: Dict[str, Any], prompts: List[str], **kwargs: Any 22 | ) -> None: 23 | print("正在获取花卉数据...") 24 | await asyncio.sleep(0.5) # 模拟异步操作 25 | print("花卉数据获取完毕。提供建议...") 26 | 27 | async def on_llm_end(self, response: LLMResult, **kwargs: Any) -> None: 28 | print("整理花卉建议...") 29 | await asyncio.sleep(0.5) # 模拟异步操作 30 | print("祝你今天愉快!") 31 | 32 | # 主要的异步函数 33 | async def main(): 34 | flower_shop_chat = ChatOpenAI( 35 | max_tokens=100, 36 | streaming=True, 37 | callbacks=[MyFlowerShopSyncHandler(), MyFlowerShopAsyncHandler()], 38 | ) 39 | 40 | # 异步生成聊天回复 41 | await flower_shop_chat.agenerate([[HumanMessage(content="哪种花卉最适合生日?只简单说3种,不超过50字")]]) 42 | 43 | # 运行主异步函数 44 | asyncio.run(main()) 45 | -------------------------------------------------------------------------------- /18_CAMEL/CAMEL_CN.py: -------------------------------------------------------------------------------- 1 | # 设置OpenAI API密钥 2 | import os 3 | os.environ["OPENAI_API_KEY"] = 'Your OpenAI Key' 4 | 5 | # 导入所需的库 6 | from typing import List 7 | from langchain.chat_models import ChatOpenAI 8 | from langchain.prompts.chat import ( 9 | SystemMessagePromptTemplate, 10 | HumanMessagePromptTemplate, 11 | ) 12 | from langchain.schema import ( 13 | AIMessage, 14 | HumanMessage, 15 | SystemMessage, 16 | BaseMessage, 17 | ) 18 | 19 | # 定义CAMELAgent类,用于管理与语言模型的交互 20 | class CAMELAgent: 21 | def __init__( 22 | self, 23 | system_message: SystemMessage, 24 | model: ChatOpenAI, 25 | ) -> None: 26 | self.system_message = system_message 27 | self.model = model 28 | self.init_messages() 29 | 30 | def reset(self) -> None: 31 | """重置对话消息""" 32 | self.init_messages() 33 | return self.stored_messages 34 | 35 | def init_messages(self) -> None: 36 | """初始化对话消息""" 37 | self.stored_messages = [self.system_message] 38 | 39 | def update_messages(self, message: BaseMessage) -> List[BaseMessage]: 40 | """更新对话消息列表""" 41 | self.stored_messages.append(message) 42 | return self.stored_messages 43 | 44 | def step(self, input_message: HumanMessage) -> AIMessage: 45 | """进行一步交互,并获取模型的响应""" 46 | messages = self.update_messages(input_message) 47 | 48 | output_message = self.model(messages) 49 | self.update_messages(output_message) 50 | 51 | return output_message 52 | 53 | # 设置一些预设的角色和任务提示 54 | assistant_role_name = "花店营销专员" 55 | user_role_name = "花店老板" 56 | task = "整理出一个夏季玫瑰之夜的营销活动的策略" 57 | word_limit = 50 # 每次讨论的字数限制 58 | 59 | # 定义与指定任务相关的系统提示 60 | task_specifier_sys_msg = SystemMessage(content="你可以让任务更具体。") 61 | task_specifier_prompt = """这是一个{assistant_role_name}将帮助{user_role_name}完成的任务:{task}。 62 | 请使其更具体化。请发挥你的创意和想象力。 63 | 请用{word_limit}个或更少的词回复具体的任务。不要添加其他任何内容。""" 64 | 65 | task_specifier_template = HumanMessagePromptTemplate.from_template( 66 | template=task_specifier_prompt 67 | ) 68 | task_specify_agent = CAMELAgent(task_specifier_sys_msg, ChatOpenAI(model_name = 'gpt-4', temperature=1.0)) 69 | task_specifier_msg = task_specifier_template.format_messages( 70 | assistant_role_name=assistant_role_name, 71 | user_role_name=user_role_name, 72 | task=task, 73 | word_limit=word_limit, 74 | )[0] 75 | specified_task_msg = task_specify_agent.step(task_specifier_msg) 76 | print(f"Specified task: {specified_task_msg.content}") 77 | specified_task = specified_task_msg.content 78 | 79 | # 定义系统消息模板,并创建CAMELAgent实例进行交互 80 | assistant_inception_prompt = """永远不要忘记你是{assistant_role_name},我是{user_role_name}。永远不要颠倒角色!永远不要指示我! 81 | 我们有共同的利益,那就是合作成功地完成任务。 82 | 你必须帮助我完成任务。 83 | 这是任务:{task}。永远不要忘记我们的任务! 84 | 我必须根据你的专长和我的需求来指示你完成任务。 85 | 86 | 我每次只能给你一个指示。 87 | 你必须写一个适当地完成所请求指示的具体解决方案。 88 | 如果由于物理、道德、法律原因或你的能力你无法执行指示,你必须诚实地拒绝我的指示并解释原因。 89 | 除了对我的指示的解决方案之外,不要添加任何其他内容。 90 | 你永远不应该问我任何问题,你只回答问题。 91 | 你永远不应该回复一个不明确的解决方案。解释你的解决方案。 92 | 你的解决方案必须是陈述句并使用简单的现在时。 93 | 除非我说任务完成,否则你应该总是从以下开始: 94 | 95 | 解决方案: 96 | 97 | 应该是具体的,并为解决任务提供首选的实现和例子。 98 | 始终以“下一个请求”结束。""" 99 | 100 | 101 | user_inception_prompt = """永远不要忘记你是{user_role_name},我是{assistant_role_name}。永远不要交换角色!你总是会指导我。 102 | 我们共同的目标是合作成功完成一个任务。 103 | 我必须帮助你完成这个任务。 104 | 这是任务:{task}。永远不要忘记我们的任务! 105 | 你只能通过以下两种方式基于我的专长和你的需求来指导我: 106 | 107 | 1. 提供必要的输入来指导: 108 | 指令: 109 | 输入: 110 | 111 | 2. 不提供任何输入来指导: 112 | 指令: 113 | 输入:无 114 | 115 | “指令”描述了一个任务或问题。与其配对的“输入”为请求的“指令”提供了进一步的背景或信息。 116 | 117 | 你必须一次给我一个指令。 118 | 我必须写一个适当地完成请求指令的回复。 119 | 如果由于物理、道德、法律原因或我的能力而无法执行你的指令,我必须诚实地拒绝你的指令并解释原因。 120 | 你应该指导我,而不是问我问题。 121 | 现在你必须开始按照上述两种方式指导我。 122 | 除了你的指令和可选的相应输入之外,不要添加任何其他内容! 123 | 继续给我指令和必要的输入,直到你认为任务已经完成。 124 | 当任务完成时,你只需回复一个单词。 125 | 除非我的回答已经解决了你的任务,否则永远不要说。""" 126 | 127 | 128 | # 根据预设的角色和任务提示生成系统消息 129 | def get_sys_msgs(assistant_role_name: str, user_role_name: str, task: str): 130 | assistant_sys_template = SystemMessagePromptTemplate.from_template( 131 | template=assistant_inception_prompt 132 | ) 133 | assistant_sys_msg = assistant_sys_template.format_messages( 134 | assistant_role_name=assistant_role_name, 135 | user_role_name=user_role_name, 136 | task=task, 137 | )[0] 138 | 139 | user_sys_template = SystemMessagePromptTemplate.from_template( 140 | template=user_inception_prompt 141 | ) 142 | user_sys_msg = user_sys_template.format_messages( 143 | assistant_role_name=assistant_role_name, 144 | user_role_name=user_role_name, 145 | task=task, 146 | )[0] 147 | 148 | return assistant_sys_msg, user_sys_msg 149 | 150 | assistant_sys_msg, user_sys_msg = get_sys_msgs( 151 | assistant_role_name, user_role_name, specified_task 152 | ) 153 | 154 | # 创建助手和用户的CAMELAgent实例 155 | assistant_agent = CAMELAgent(assistant_sys_msg, ChatOpenAI(temperature=0.2)) 156 | user_agent = CAMELAgent(user_sys_msg, ChatOpenAI(temperature=0.2)) 157 | 158 | # 重置两个agent 159 | assistant_agent.reset() 160 | user_agent.reset() 161 | 162 | # 初始化对话互动 163 | assistant_msg = HumanMessage( 164 | content=( 165 | f"{user_sys_msg.content}。" 166 | "现在开始逐一给我介绍。" 167 | "只回复指令和输入。" 168 | ) 169 | ) 170 | 171 | user_msg = HumanMessage(content=f"{assistant_sys_msg.content}") 172 | user_msg = assistant_agent.step(user_msg) 173 | 174 | print(f"Original task prompt:\n{task}\n") 175 | print(f"Specified task prompt:\n{specified_task}\n") 176 | 177 | # 模拟对话交互,直到达到对话轮次上限或任务完成 178 | chat_turn_limit, n = 30, 0 179 | while n < chat_turn_limit: 180 | n += 1 181 | user_ai_msg = user_agent.step(assistant_msg) 182 | user_msg = HumanMessage(content=user_ai_msg.content) 183 | print(f"AI User ({user_role_name}):\n\n{user_msg.content}\n\n") 184 | 185 | assistant_ai_msg = assistant_agent.step(user_msg) 186 | assistant_msg = HumanMessage(content=assistant_ai_msg.content) 187 | print(f"AI Assistant ({assistant_role_name}):\n\n{assistant_msg.content}\n\n") 188 | if "" in user_msg.content: 189 | break -------------------------------------------------------------------------------- /19_BabyAGI/BabyAGI_CN.py: -------------------------------------------------------------------------------- 1 | # 设置API Key 2 | import os 3 | os.environ["OPENAI_API_KEY"] = 'Your OpenAI Key' 4 | 5 | # 导入所需的库和模块 6 | from collections import deque 7 | from typing import Dict, List, Optional, Any 8 | from langchain.chains import LLMChain 9 | from langchain.prompts import PromptTemplate 10 | from langchain.embeddings import OpenAIEmbeddings 11 | from langchain.llms import BaseLLM, OpenAI 12 | from langchain.vectorstores.base import VectorStore 13 | from pydantic import BaseModel, Field 14 | from langchain.chains.base import Chain 15 | from langchain.vectorstores import FAISS 16 | import faiss 17 | from langchain.docstore import InMemoryDocstore 18 | 19 | 20 | # 定义嵌入模型 21 | embeddings_model = OpenAIEmbeddings() 22 | # 初始化向量存储 23 | embedding_size = 1536 24 | index = faiss.IndexFlatL2(embedding_size) 25 | vectorstore = FAISS(embeddings_model.embed_query, index, InMemoryDocstore({}), {}) 26 | 27 | # 任务生成链 28 | class TaskCreationChain(LLMChain): 29 | """负责生成任务的链""" 30 | @classmethod 31 | def from_llm(cls, llm: BaseLLM, verbose: bool = True) -> LLMChain: 32 | """从LLM获取响应解析器""" 33 | task_creation_template = ( 34 | "You are a task creation AI that uses the result of an execution agent" 35 | " to create new tasks with the following objective: {objective}," 36 | " The last completed task has the result: {result}." 37 | " This result was based on this task description: {task_description}." 38 | " These are incomplete tasks: {incomplete_tasks}." 39 | " Based on the result, create new tasks to be completed" 40 | " by the AI system that do not overlap with incomplete tasks." 41 | " Return the tasks as an array." 42 | ) 43 | prompt = PromptTemplate( 44 | template=task_creation_template, 45 | input_variables=[ 46 | "result", 47 | "task_description", 48 | "incomplete_tasks", 49 | "objective", 50 | ], 51 | ) 52 | return cls(prompt=prompt, llm=llm, verbose=verbose) 53 | 54 | # 任务优先级链 55 | class TaskPrioritizationChain(LLMChain): 56 | """负责任务优先级排序的链""" 57 | @classmethod 58 | def from_llm(cls, llm: BaseLLM, verbose: bool = True) -> LLMChain: 59 | """从LLM获取响应解析器""" 60 | task_prioritization_template = ( 61 | "You are a task prioritization AI tasked with cleaning the formatting of and reprioritizing" 62 | " the following tasks: {task_names}." 63 | " Consider the ultimate objective of your team: {objective}." 64 | " Do not remove any tasks. Return the result as a numbered list, like:" 65 | " #. First task" 66 | " #. Second task" 67 | " Start the task list with number {next_task_id}." 68 | ) 69 | prompt = PromptTemplate( 70 | template=task_prioritization_template, 71 | input_variables=["task_names", "next_task_id", "objective"], 72 | ) 73 | return cls(prompt=prompt, llm=llm, verbose=verbose) 74 | 75 | # 任务执行链 76 | class ExecutionChain(LLMChain): 77 | """负责执行任务的链""" 78 | 79 | @classmethod 80 | def from_llm(cls, llm: BaseLLM, verbose: bool = True) -> LLMChain: 81 | """从LLM获取响应解析器""" 82 | execution_template = ( 83 | "You are an AI who performs one task based on the following objective: {objective}." 84 | " Take into account these previously completed tasks: {context}." 85 | " Your task: {task}." 86 | " Response:" 87 | ) 88 | prompt = PromptTemplate( 89 | template=execution_template, 90 | input_variables=["objective", "context", "task"], 91 | ) 92 | return cls(prompt=prompt, llm=llm, verbose=verbose) 93 | 94 | def get_next_task( 95 | task_creation_chain: LLMChain, 96 | result: Dict, 97 | task_description: str, 98 | task_list: List[str], 99 | objective: str, 100 | ) -> List[Dict]: 101 | """Get the next task.""" 102 | incomplete_tasks = ", ".join(task_list) 103 | response = task_creation_chain.run( 104 | result=result, 105 | task_description=task_description, 106 | incomplete_tasks=incomplete_tasks, 107 | objective=objective, 108 | ) 109 | new_tasks = response.split("\n") 110 | return [{"task_name": task_name} for task_name in new_tasks if task_name.strip()] 111 | 112 | 113 | def prioritize_tasks( 114 | task_prioritization_chain: LLMChain, 115 | this_task_id: int, 116 | task_list: List[Dict], 117 | objective: str, 118 | ) -> List[Dict]: 119 | """Prioritize tasks.""" 120 | task_names = [t["task_name"] for t in task_list] 121 | next_task_id = int(this_task_id) + 1 122 | response = task_prioritization_chain.run( 123 | task_names=task_names, next_task_id=next_task_id, objective=objective 124 | ) 125 | new_tasks = response.split("\n") 126 | prioritized_task_list = [] 127 | for task_string in new_tasks: 128 | if not task_string.strip(): 129 | continue 130 | task_parts = task_string.strip().split(".", 1) 131 | if len(task_parts) == 2: 132 | task_id = task_parts[0].strip() 133 | task_name = task_parts[1].strip() 134 | prioritized_task_list.append({"task_id": task_id, "task_name": task_name}) 135 | return prioritized_task_list 136 | 137 | 138 | def _get_top_tasks(vectorstore, query: str, k: int) -> List[str]: 139 | """Get the top k tasks based on the query.""" 140 | results = vectorstore.similarity_search_with_score(query, k=k) 141 | if not results: 142 | return [] 143 | sorted_results, _ = zip(*sorted(results, key=lambda x: x[1], reverse=True)) 144 | return [str(item.metadata["task"]) for item in sorted_results] 145 | 146 | 147 | def execute_task( 148 | vectorstore, execution_chain: LLMChain, objective: str, task: str, k: int = 5 149 | ) -> str: 150 | """Execute a task.""" 151 | context = _get_top_tasks(vectorstore, query=objective, k=k) 152 | return execution_chain.run(objective=objective, context=context, task=task) 153 | 154 | 155 | # BabyAGI 主类 156 | class BabyAGI(Chain, BaseModel): 157 | """BabyAGI代理的控制器模型""" 158 | 159 | task_list: deque = Field(default_factory=deque) 160 | task_creation_chain: TaskCreationChain = Field(...) 161 | task_prioritization_chain: TaskPrioritizationChain = Field(...) 162 | execution_chain: ExecutionChain = Field(...) 163 | task_id_counter: int = Field(1) 164 | vectorstore: VectorStore = Field(init=False) 165 | max_iterations: Optional[int] = None 166 | 167 | class Config: 168 | """Configuration for this pydantic object.""" 169 | 170 | arbitrary_types_allowed = True 171 | 172 | def add_task(self, task: Dict): 173 | self.task_list.append(task) 174 | 175 | def print_task_list(self): 176 | print("\033[95m\033[1m" + "\n*****TASK LIST*****\n" + "\033[0m\033[0m") 177 | for t in self.task_list: 178 | print(str(t["task_id"]) + ": " + t["task_name"]) 179 | 180 | def print_next_task(self, task: Dict): 181 | print("\033[92m\033[1m" + "\n*****NEXT TASK*****\n" + "\033[0m\033[0m") 182 | print(str(task["task_id"]) + ": " + task["task_name"]) 183 | 184 | def print_task_result(self, result: str): 185 | print("\033[93m\033[1m" + "\n*****TASK RESULT*****\n" + "\033[0m\033[0m") 186 | print(result) 187 | 188 | @property 189 | def input_keys(self) -> List[str]: 190 | return ["objective"] 191 | 192 | @property 193 | def output_keys(self) -> List[str]: 194 | return [] 195 | 196 | def _call(self, inputs: Dict[str, Any]) -> Dict[str, Any]: 197 | """Run the agent.""" 198 | objective = inputs["objective"] 199 | first_task = inputs.get("first_task", "Make a todo list") 200 | self.add_task({"task_id": 1, "task_name": first_task}) 201 | num_iters = 0 202 | while True: 203 | if self.task_list: 204 | self.print_task_list() 205 | 206 | # Step 1: Pull the first task 207 | task = self.task_list.popleft() 208 | self.print_next_task(task) 209 | 210 | # Step 2: Execute the task 211 | result = execute_task( 212 | self.vectorstore, self.execution_chain, objective, task["task_name"] 213 | ) 214 | this_task_id = int(task["task_id"]) 215 | self.print_task_result(result) 216 | 217 | # Step 3: Store the result in Pinecone 218 | result_id = f"result_{task['task_id']}_{num_iters}" 219 | self.vectorstore.add_texts( 220 | texts=[result], 221 | metadatas=[{"task": task["task_name"]}], 222 | ids=[result_id], 223 | ) 224 | 225 | # Step 4: Create new tasks and reprioritize task list 226 | new_tasks = get_next_task( 227 | self.task_creation_chain, 228 | result, 229 | task["task_name"], 230 | [t["task_name"] for t in self.task_list], 231 | objective, 232 | ) 233 | for new_task in new_tasks: 234 | self.task_id_counter += 1 235 | new_task.update({"task_id": self.task_id_counter}) 236 | self.add_task(new_task) 237 | self.task_list = deque( 238 | prioritize_tasks( 239 | self.task_prioritization_chain, 240 | this_task_id, 241 | list(self.task_list), 242 | objective, 243 | ) 244 | ) 245 | num_iters += 1 246 | if self.max_iterations is not None and num_iters == self.max_iterations: 247 | print( 248 | "\033[91m\033[1m" + "\n*****TASK ENDING*****\n" + "\033[0m\033[0m" 249 | ) 250 | break 251 | return {} 252 | 253 | @classmethod 254 | def from_llm( 255 | cls, llm: BaseLLM, vectorstore: VectorStore, verbose: bool = False, **kwargs 256 | ) -> "BabyAGI": 257 | """Initialize the BabyAGI Controller.""" 258 | task_creation_chain = TaskCreationChain.from_llm(llm, verbose=verbose) 259 | task_prioritization_chain = TaskPrioritizationChain.from_llm( 260 | llm, verbose=verbose 261 | ) 262 | execution_chain = ExecutionChain.from_llm(llm, verbose=verbose) 263 | return cls( 264 | task_creation_chain=task_creation_chain, 265 | task_prioritization_chain=task_prioritization_chain, 266 | execution_chain=execution_chain, 267 | vectorstore=vectorstore, 268 | **kwargs, 269 | ) 270 | 271 | 272 | # 主执行部分 273 | if __name__ == "__main__": 274 | OBJECTIVE = "分析一下北京市今天的气候情况,写出鲜花储存策略。" 275 | llm = OpenAI(temperature=0) 276 | verbose = False 277 | max_iterations: Optional[int] = 6 278 | baby_agi = BabyAGI.from_llm(llm=llm, vectorstore=vectorstore, 279 | verbose=verbose, 280 | max_iterations=max_iterations) 281 | baby_agi({"objective": OBJECTIVE}) 282 | 283 | -------------------------------------------------------------------------------- /20_人脉工具上/socializer_v1/agents/__pycache__/weibo_agent.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huangjia2019/langchain-in-action/6a899d656b6afa4497c53c7a535e83d98a3b63ad/20_人脉工具上/socializer_v1/agents/__pycache__/weibo_agent.cpython-311.pyc -------------------------------------------------------------------------------- /20_人脉工具上/socializer_v1/agents/weibo_agent.py: -------------------------------------------------------------------------------- 1 | # 导入一个搜索UID的工具 2 | from tools.search_tool import get_UID 3 | 4 | # 导入所需的库 5 | from langchain.prompts import PromptTemplate 6 | from langchain.chat_models import ChatOpenAI 7 | from langchain.agents import initialize_agent, Tool 8 | from langchain.agents import AgentType 9 | 10 | # 通过LangChain代理找到UID的函数 11 | def lookup_V(flower_type: str) : 12 | # 初始化大模型 13 | llm = ChatOpenAI(temperature=0, model_name="gpt-3.5-turbo") 14 | 15 | # 寻找UID的模板 16 | template = """given the {flower} I want you to get a related 微博 UID. 17 | Your answer should contain only a UID. 18 | The URL always starts with https://weibo.com/u/ 19 | for example, if https://weibo.com/u/1669879400 is her 微博, then 1669879400 is her UID 20 | This is only the example don't give me this, but the actual UID""" 21 | # 完整的提示模板 22 | prompt_template = PromptTemplate( 23 | input_variables=["flower"], template=template 24 | ) 25 | 26 | # 代理的工具 27 | tools = [ 28 | Tool( 29 | name="Crawl Google for 微博 page", 30 | func=get_UID, 31 | description="useful for when you need get the 微博 UID", 32 | ) 33 | ] 34 | 35 | # 初始化代理 36 | agent = initialize_agent( 37 | tools, 38 | llm, 39 | agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, 40 | verbose=True 41 | ) 42 | 43 | # 返回找到的UID 44 | ID = agent.run(prompt_template.format_prompt(flower=flower_type)) 45 | 46 | return ID -------------------------------------------------------------------------------- /20_人脉工具上/socializer_v1/findbigV.py: -------------------------------------------------------------------------------- 1 | # 设置OpenAI API密钥 2 | import os 3 | os.environ["OPENAI_API_KEY"] = 'Your Key' 4 | os.environ["SERPAPI_API_KEY"] = 'Your Key' 5 | 6 | # 导入所取的库 7 | import re 8 | from agents.weibo_agent import lookup_V 9 | 10 | if __name__ == "__main__": 11 | 12 | # 拿到UID 13 | response_UID = lookup_V(flower_type = "牡丹" ) 14 | 15 | # 抽取UID里面的数字 16 | UID = re.findall(r'\d+', response_UID)[0] 17 | print("这位鲜花大V的微博ID是", UID) 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /20_人脉工具上/socializer_v1/tools/__pycache__/general_tool.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huangjia2019/langchain-in-action/6a899d656b6afa4497c53c7a535e83d98a3b63ad/20_人脉工具上/socializer_v1/tools/__pycache__/general_tool.cpython-311.pyc -------------------------------------------------------------------------------- /20_人脉工具上/socializer_v1/tools/__pycache__/search_tool.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huangjia2019/langchain-in-action/6a899d656b6afa4497c53c7a535e83d98a3b63ad/20_人脉工具上/socializer_v1/tools/__pycache__/search_tool.cpython-311.pyc -------------------------------------------------------------------------------- /20_人脉工具上/socializer_v1/tools/general_tool.py: -------------------------------------------------------------------------------- 1 | import re 2 | 3 | def contains_chinese(s): 4 | return bool(re.search('[\u4e00-\u9fa5]', s)) 5 | 6 | def remove_non_chinese_fields(d): 7 | if isinstance(d, dict): 8 | to_remove = [key for key, value in d.items() if isinstance(value, (str, int, float, bool)) and (not contains_chinese(str(value)))] 9 | for key in to_remove: 10 | del d[key] 11 | 12 | for key, value in d.items(): 13 | if isinstance(value, (dict, list)): 14 | remove_non_chinese_fields(value) 15 | elif isinstance(d, list): 16 | to_remove_indices = [] 17 | for i, item in enumerate(d): 18 | if isinstance(item, (str, int, float, bool)) and (not contains_chinese(str(item))): 19 | to_remove_indices.append(i) 20 | else: 21 | remove_non_chinese_fields(item) 22 | 23 | for index in reversed(to_remove_indices): 24 | d.pop(index) -------------------------------------------------------------------------------- /20_人脉工具上/socializer_v1/tools/search_tool.py: -------------------------------------------------------------------------------- 1 | # 导入SerpAPIWrapper 2 | from langchain.utilities import SerpAPIWrapper 3 | 4 | # 重新定制SerpAPIWrapper,重构_process_response,返回URL 5 | class CustomSerpAPIWrapper(SerpAPIWrapper): 6 | def __init__(self): 7 | super(CustomSerpAPIWrapper, self).__init__() 8 | 9 | @staticmethod 10 | def _process_response(res: dict) -> str: 11 | """Process response from SerpAPI.""" 12 | if "error" in res.keys(): 13 | raise ValueError(f"Got error from SerpAPI: {res['error']}") 14 | if "answer_box_list" in res.keys(): 15 | res["answer_box"] = res["answer_box_list"] 16 | if "answer_box" in res.keys(): 17 | answer_box = res["answer_box"] 18 | if isinstance(answer_box, list): 19 | answer_box = answer_box[0] 20 | if "result" in answer_box.keys(): 21 | return answer_box["result"] 22 | elif "answer" in answer_box.keys(): 23 | return answer_box["answer"] 24 | elif "snippet" in answer_box.keys(): 25 | return answer_box["snippet"] 26 | elif "snippet_highlighted_words" in answer_box.keys(): 27 | return answer_box["snippet_highlighted_words"] 28 | else: 29 | answer = {} 30 | for key, value in answer_box.items(): 31 | if not isinstance(value, (list, dict)) and not ( 32 | isinstance(value, str) and value.startswith("http") 33 | ): 34 | answer[key] = value 35 | return str(answer) 36 | elif "events_results" in res.keys(): 37 | return res["events_results"][:10] 38 | elif "sports_results" in res.keys(): 39 | return res["sports_results"] 40 | elif "top_stories" in res.keys(): 41 | return res["top_stories"] 42 | elif "news_results" in res.keys(): 43 | return res["news_results"] 44 | elif "jobs_results" in res.keys() and "jobs" in res["jobs_results"].keys(): 45 | return res["jobs_results"]["jobs"] 46 | elif ( 47 | "shopping_results" in res.keys() 48 | and "title" in res["shopping_results"][0].keys() 49 | ): 50 | return res["shopping_results"][:3] 51 | elif "questions_and_answers" in res.keys(): 52 | return res["questions_and_answers"] 53 | elif ( 54 | "popular_destinations" in res.keys() 55 | and "destinations" in res["popular_destinations"].keys() 56 | ): 57 | return res["popular_destinations"]["destinations"] 58 | elif "top_sights" in res.keys() and "sights" in res["top_sights"].keys(): 59 | return res["top_sights"]["sights"] 60 | elif ( 61 | "images_results" in res.keys() 62 | and "thumbnail" in res["images_results"][0].keys() 63 | ): 64 | return str([item["thumbnail"] for item in res["images_results"][:10]]) 65 | 66 | snippets = [] 67 | if "knowledge_graph" in res.keys(): 68 | knowledge_graph = res["knowledge_graph"] 69 | title = knowledge_graph["title"] if "title" in knowledge_graph else "" 70 | if "description" in knowledge_graph.keys(): 71 | snippets.append(knowledge_graph["description"]) 72 | for key, value in knowledge_graph.items(): 73 | if ( 74 | isinstance(key, str) 75 | and isinstance(value, str) 76 | and key not in ["title", "description"] 77 | and not key.endswith("_stick") 78 | and not key.endswith("_link") 79 | and not value.startswith("http") 80 | ): 81 | snippets.append(f"{title} {key}: {value}.") 82 | if "organic_results" in res.keys(): 83 | first_organic_result = res["organic_results"][0] 84 | if "snippet" in first_organic_result.keys(): 85 | # snippets.append(first_organic_result["snippet"]) 86 | snippets.append(first_organic_result["link"]) 87 | elif "snippet_highlighted_words" in first_organic_result.keys(): 88 | snippets.append(first_organic_result["snippet_highlighted_words"]) 89 | elif "rich_snippet" in first_organic_result.keys(): 90 | snippets.append(first_organic_result["rich_snippet"]) 91 | elif "rich_snippet_table" in first_organic_result.keys(): 92 | snippets.append(first_organic_result["rich_snippet_table"]) 93 | elif "link" in first_organic_result.keys(): 94 | snippets.append(first_organic_result["link"]) 95 | if "buying_guide" in res.keys(): 96 | snippets.append(res["buying_guide"]) 97 | if "local_results" in res.keys() and "places" in res["local_results"].keys(): 98 | snippets.append(res["local_results"]["places"]) 99 | 100 | if len(snippets) > 0: 101 | return str(snippets) 102 | else: 103 | return "No good search result found" 104 | 105 | # 获取与某种鲜花相关的微博UID的函数 106 | def get_UID(flower: str): 107 | # search = SerpAPIWrapper() 108 | search = CustomSerpAPIWrapper() 109 | res = search.run(f"{flower}") 110 | return res -------------------------------------------------------------------------------- /20_人脉工具上/socializer_v2/agents/__pycache__/weibo_agent.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huangjia2019/langchain-in-action/6a899d656b6afa4497c53c7a535e83d98a3b63ad/20_人脉工具上/socializer_v2/agents/__pycache__/weibo_agent.cpython-311.pyc -------------------------------------------------------------------------------- /20_人脉工具上/socializer_v2/agents/weibo_agent.py: -------------------------------------------------------------------------------- 1 | # 导入一个搜索UID的工具 2 | from tools.search_tool import get_UID 3 | 4 | # 导入所需的库 5 | from langchain.prompts import PromptTemplate 6 | from langchain.chat_models import ChatOpenAI 7 | from langchain.agents import initialize_agent, Tool 8 | from langchain.agents import AgentType 9 | 10 | # 通过LangChain代理找到UID的函数 11 | def lookup_V(flower_type: str) : 12 | # 初始化大模型 13 | llm = ChatOpenAI(temperature=0, model_name="gpt-3.5-turbo") 14 | 15 | # 寻找UID的模板 16 | template = """given the {flower} I want you to get a related 微博 UID. 17 | Your answer should contain only a UID. 18 | The URL always starts with https://weibo.com/u/ 19 | for example, if https://weibo.com/u/1669879400 is her 微博, then 1669879400 is her UID 20 | This is only the example don't give me this, but the actual UID""" 21 | # 完整的提示模板 22 | prompt_template = PromptTemplate( 23 | input_variables=["flower"], template=template 24 | ) 25 | 26 | # 代理的工具 27 | tools = [ 28 | Tool( 29 | name="Crawl Google for 微博 page", 30 | func=get_UID, 31 | description="useful for when you need get the 微博 UID", 32 | ) 33 | ] 34 | 35 | # 初始化代理 36 | agent = initialize_agent( 37 | tools, 38 | llm, 39 | agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, 40 | verbose=True 41 | ) 42 | 43 | # 返回找到的UID 44 | ID = agent.run(prompt_template.format_prompt(flower=flower_type)) 45 | 46 | return ID -------------------------------------------------------------------------------- /20_人脉工具上/socializer_v2/findbigV.py: -------------------------------------------------------------------------------- 1 | # 设置OpenAI API密钥 2 | import os 3 | os.environ["OPENAI_API_KEY"] = 'your key' 4 | os.environ["SERPAPI_API_KEY"] = 'your key' 5 | 6 | # 导入所取的库 7 | import re 8 | from agents.weibo_agent import lookup_V 9 | from tools.general_tool import remove_non_chinese_fields 10 | from tools.scraping_tool import get_data 11 | 12 | if __name__ == "__main__": 13 | 14 | # 拿到UID 15 | response_UID = lookup_V(flower_type = "牡丹" ) 16 | 17 | # 抽取UID里面的数字 18 | UID = re.findall(r'\d+', response_UID)[0] 19 | print("这位鲜花大V的微博ID是", UID) 20 | 21 | # 根据UID爬取大V信息 22 | person_info = get_data(UID) 23 | print(person_info) 24 | 25 | # 移除无用的信息 26 | remove_non_chinese_fields(person_info) 27 | print(person_info) 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /20_人脉工具上/socializer_v2/tools/__pycache__/general_tool.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huangjia2019/langchain-in-action/6a899d656b6afa4497c53c7a535e83d98a3b63ad/20_人脉工具上/socializer_v2/tools/__pycache__/general_tool.cpython-311.pyc -------------------------------------------------------------------------------- /20_人脉工具上/socializer_v2/tools/__pycache__/scraping_tool.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huangjia2019/langchain-in-action/6a899d656b6afa4497c53c7a535e83d98a3b63ad/20_人脉工具上/socializer_v2/tools/__pycache__/scraping_tool.cpython-311.pyc -------------------------------------------------------------------------------- /20_人脉工具上/socializer_v2/tools/__pycache__/search_tool.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huangjia2019/langchain-in-action/6a899d656b6afa4497c53c7a535e83d98a3b63ad/20_人脉工具上/socializer_v2/tools/__pycache__/search_tool.cpython-311.pyc -------------------------------------------------------------------------------- /20_人脉工具上/socializer_v2/tools/general_tool.py: -------------------------------------------------------------------------------- 1 | import re 2 | 3 | def contains_chinese(s): 4 | return bool(re.search('[\u4e00-\u9fa5]', s)) 5 | 6 | def remove_non_chinese_fields(d): 7 | if isinstance(d, dict): 8 | to_remove = [key for key, value in d.items() if isinstance(value, (str, int, float, bool)) and (not contains_chinese(str(value)))] 9 | for key in to_remove: 10 | del d[key] 11 | 12 | for key, value in d.items(): 13 | if isinstance(value, (dict, list)): 14 | remove_non_chinese_fields(value) 15 | elif isinstance(d, list): 16 | to_remove_indices = [] 17 | for i, item in enumerate(d): 18 | if isinstance(item, (str, int, float, bool)) and (not contains_chinese(str(item))): 19 | to_remove_indices.append(i) 20 | else: 21 | remove_non_chinese_fields(item) 22 | 23 | for index in reversed(to_remove_indices): 24 | d.pop(index) -------------------------------------------------------------------------------- /20_人脉工具上/socializer_v2/tools/scraping_tool.py: -------------------------------------------------------------------------------- 1 | # 导入所需的库 2 | import json 3 | import requests 4 | import time 5 | 6 | # 定义爬取微博用户信息的函数 7 | def scrape_weibo(url: str): 8 | '''爬取相关鲜花服务商的资料''' 9 | headers = { 10 | "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36", 11 | "Referer": "https://weibo.com" 12 | } 13 | cookies = { 14 | "cookie": '''your cookie''' 15 | } 16 | response = requests.get(url, headers=headers, cookies=cookies) 17 | time.sleep(3) # 加上3s 的延时防止被反爬 18 | return response.text 19 | 20 | # 根据UID构建URL爬取信息 21 | def get_data(id): 22 | url = "https://weibo.com/ajax/profile/detail?uid={}".format(id) 23 | html = scrape_weibo(url) 24 | response = json.loads(html) 25 | 26 | return response -------------------------------------------------------------------------------- /20_人脉工具上/socializer_v2/tools/search_tool.py: -------------------------------------------------------------------------------- 1 | # 导入SerpAPIWrapper 2 | from langchain.utilities import SerpAPIWrapper 3 | 4 | # 重新定制SerpAPIWrapper,重构_process_response,返回URL 5 | class CustomSerpAPIWrapper(SerpAPIWrapper): 6 | def __init__(self): 7 | super(CustomSerpAPIWrapper, self).__init__() 8 | 9 | @staticmethod 10 | def _process_response(res: dict) -> str: 11 | """Process response from SerpAPI.""" 12 | if "error" in res.keys(): 13 | raise ValueError(f"Got error from SerpAPI: {res['error']}") 14 | if "answer_box_list" in res.keys(): 15 | res["answer_box"] = res["answer_box_list"] 16 | if "answer_box" in res.keys(): 17 | answer_box = res["answer_box"] 18 | if isinstance(answer_box, list): 19 | answer_box = answer_box[0] 20 | if "result" in answer_box.keys(): 21 | return answer_box["result"] 22 | elif "answer" in answer_box.keys(): 23 | return answer_box["answer"] 24 | elif "snippet" in answer_box.keys(): 25 | return answer_box["snippet"] 26 | elif "snippet_highlighted_words" in answer_box.keys(): 27 | return answer_box["snippet_highlighted_words"] 28 | else: 29 | answer = {} 30 | for key, value in answer_box.items(): 31 | if not isinstance(value, (list, dict)) and not ( 32 | isinstance(value, str) and value.startswith("http") 33 | ): 34 | answer[key] = value 35 | return str(answer) 36 | elif "events_results" in res.keys(): 37 | return res["events_results"][:10] 38 | elif "sports_results" in res.keys(): 39 | return res["sports_results"] 40 | elif "top_stories" in res.keys(): 41 | return res["top_stories"] 42 | elif "news_results" in res.keys(): 43 | return res["news_results"] 44 | elif "jobs_results" in res.keys() and "jobs" in res["jobs_results"].keys(): 45 | return res["jobs_results"]["jobs"] 46 | elif ( 47 | "shopping_results" in res.keys() 48 | and "title" in res["shopping_results"][0].keys() 49 | ): 50 | return res["shopping_results"][:3] 51 | elif "questions_and_answers" in res.keys(): 52 | return res["questions_and_answers"] 53 | elif ( 54 | "popular_destinations" in res.keys() 55 | and "destinations" in res["popular_destinations"].keys() 56 | ): 57 | return res["popular_destinations"]["destinations"] 58 | elif "top_sights" in res.keys() and "sights" in res["top_sights"].keys(): 59 | return res["top_sights"]["sights"] 60 | elif ( 61 | "images_results" in res.keys() 62 | and "thumbnail" in res["images_results"][0].keys() 63 | ): 64 | return str([item["thumbnail"] for item in res["images_results"][:10]]) 65 | 66 | snippets = [] 67 | if "knowledge_graph" in res.keys(): 68 | knowledge_graph = res["knowledge_graph"] 69 | title = knowledge_graph["title"] if "title" in knowledge_graph else "" 70 | if "description" in knowledge_graph.keys(): 71 | snippets.append(knowledge_graph["description"]) 72 | for key, value in knowledge_graph.items(): 73 | if ( 74 | isinstance(key, str) 75 | and isinstance(value, str) 76 | and key not in ["title", "description"] 77 | and not key.endswith("_stick") 78 | and not key.endswith("_link") 79 | and not value.startswith("http") 80 | ): 81 | snippets.append(f"{title} {key}: {value}.") 82 | if "organic_results" in res.keys(): 83 | first_organic_result = res["organic_results"][0] 84 | if "snippet" in first_organic_result.keys(): 85 | # snippets.append(first_organic_result["snippet"]) 86 | snippets.append(first_organic_result["link"]) 87 | elif "snippet_highlighted_words" in first_organic_result.keys(): 88 | snippets.append(first_organic_result["snippet_highlighted_words"]) 89 | elif "rich_snippet" in first_organic_result.keys(): 90 | snippets.append(first_organic_result["rich_snippet"]) 91 | elif "rich_snippet_table" in first_organic_result.keys(): 92 | snippets.append(first_organic_result["rich_snippet_table"]) 93 | elif "link" in first_organic_result.keys(): 94 | snippets.append(first_organic_result["link"]) 95 | if "buying_guide" in res.keys(): 96 | snippets.append(res["buying_guide"]) 97 | if "local_results" in res.keys() and "places" in res["local_results"].keys(): 98 | snippets.append(res["local_results"]["places"]) 99 | 100 | if len(snippets) > 0: 101 | return str(snippets) 102 | else: 103 | return "No good search result found" 104 | 105 | # 获取与某种鲜花相关的微博UID的函数 106 | def get_UID(flower: str): 107 | # search = SerpAPIWrapper() 108 | search = CustomSerpAPIWrapper() 109 | res = search.run(f"{flower}") 110 | return res -------------------------------------------------------------------------------- /21_人脉工具下/socializer_v3/agents/__pycache__/weibo_agent.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huangjia2019/langchain-in-action/6a899d656b6afa4497c53c7a535e83d98a3b63ad/21_人脉工具下/socializer_v3/agents/__pycache__/weibo_agent.cpython-311.pyc -------------------------------------------------------------------------------- /21_人脉工具下/socializer_v3/agents/weibo_agent.py: -------------------------------------------------------------------------------- 1 | # 导入一个搜索UID的工具 2 | from tools.search_tool import get_UID 3 | 4 | # 导入所需的库 5 | from langchain.prompts import PromptTemplate 6 | from langchain.chat_models import ChatOpenAI 7 | from langchain.agents import initialize_agent, Tool 8 | from langchain.agents import AgentType 9 | 10 | # 通过LangChain代理找到UID的函数 11 | def lookup_V(flower_type: str) : 12 | # 初始化大模型 13 | llm = ChatOpenAI(temperature=0, model_name="gpt-3.5-turbo") 14 | 15 | # 寻找UID的模板 16 | template = """given the {flower} I want you to get a related 微博 UID. 17 | Your answer should contain only a UID. 18 | The URL always starts with https://weibo.com/u/ 19 | for example, if https://weibo.com/u/1669879400 is her 微博, then 1669879400 is her UID 20 | This is only the example don't give me this, but the actual UID""" 21 | # 完整的提示模板 22 | prompt_template = PromptTemplate( 23 | input_variables=["flower"], template=template 24 | ) 25 | 26 | # 代理的工具 27 | tools = [ 28 | Tool( 29 | name="Crawl Google for 微博 page", 30 | func=get_UID, 31 | description="useful for when you need get the 微博 UID", 32 | ) 33 | ] 34 | 35 | # 初始化代理 36 | agent = initialize_agent( 37 | tools, 38 | llm, 39 | agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, 40 | verbose=True 41 | ) 42 | 43 | # 返回找到的UID 44 | ID = agent.run(prompt_template.format_prompt(flower=flower_type)) 45 | 46 | return ID -------------------------------------------------------------------------------- /21_人脉工具下/socializer_v3/findbigV.py: -------------------------------------------------------------------------------- 1 | # 设置OpenAI API密钥 2 | import os 3 | os.environ["OPENAI_API_KEY"] = 'your key' 4 | os.environ["SERPAPI_API_KEY"] = 'your key' 5 | 6 | # 导入所取的库 7 | import re 8 | from agents.weibo_agent import lookup_V 9 | from tools.general_tool import remove_non_chinese_fields 10 | from tools.scraping_tool import get_data 11 | from tools.textgen_tool import generate_letter 12 | 13 | 14 | if __name__ == "__main__": 15 | 16 | # 拿到UID 17 | response_UID = lookup_V(flower_type = "牡丹" ) 18 | 19 | # 抽取UID里面的数字 20 | UID = re.findall(r'\d+', response_UID)[0] 21 | print("这位鲜花大V的微博ID是", UID) 22 | 23 | # 根据UID爬取大V信息 24 | person_info = get_data(UID) 25 | print(person_info) 26 | 27 | # 移除无用的信息 28 | remove_non_chinese_fields(person_info) 29 | print(person_info) 30 | 31 | # 调用函数根据大V信息生成文本 32 | result = generate_letter(information = person_info) 33 | print(result) 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /21_人脉工具下/socializer_v3/tools/__pycache__/general_tool.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huangjia2019/langchain-in-action/6a899d656b6afa4497c53c7a535e83d98a3b63ad/21_人脉工具下/socializer_v3/tools/__pycache__/general_tool.cpython-311.pyc -------------------------------------------------------------------------------- /21_人脉工具下/socializer_v3/tools/__pycache__/scraping_tool.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huangjia2019/langchain-in-action/6a899d656b6afa4497c53c7a535e83d98a3b63ad/21_人脉工具下/socializer_v3/tools/__pycache__/scraping_tool.cpython-311.pyc -------------------------------------------------------------------------------- /21_人脉工具下/socializer_v3/tools/__pycache__/search_tool.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huangjia2019/langchain-in-action/6a899d656b6afa4497c53c7a535e83d98a3b63ad/21_人脉工具下/socializer_v3/tools/__pycache__/search_tool.cpython-311.pyc -------------------------------------------------------------------------------- /21_人脉工具下/socializer_v3/tools/__pycache__/textgen_tool.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huangjia2019/langchain-in-action/6a899d656b6afa4497c53c7a535e83d98a3b63ad/21_人脉工具下/socializer_v3/tools/__pycache__/textgen_tool.cpython-311.pyc -------------------------------------------------------------------------------- /21_人脉工具下/socializer_v3/tools/general_tool.py: -------------------------------------------------------------------------------- 1 | import re 2 | 3 | def contains_chinese(s): 4 | return bool(re.search('[\u4e00-\u9fa5]', s)) 5 | 6 | def remove_non_chinese_fields(d): 7 | if isinstance(d, dict): 8 | to_remove = [key for key, value in d.items() if isinstance(value, (str, int, float, bool)) and (not contains_chinese(str(value)))] 9 | for key in to_remove: 10 | del d[key] 11 | 12 | for key, value in d.items(): 13 | if isinstance(value, (dict, list)): 14 | remove_non_chinese_fields(value) 15 | elif isinstance(d, list): 16 | to_remove_indices = [] 17 | for i, item in enumerate(d): 18 | if isinstance(item, (str, int, float, bool)) and (not contains_chinese(str(item))): 19 | to_remove_indices.append(i) 20 | else: 21 | remove_non_chinese_fields(item) 22 | 23 | for index in reversed(to_remove_indices): 24 | d.pop(index) -------------------------------------------------------------------------------- /21_人脉工具下/socializer_v3/tools/scraping_tool.py: -------------------------------------------------------------------------------- 1 | # 导入所需的库 2 | import json 3 | import requests 4 | import time 5 | 6 | # 定义爬取微博用户信息的函数 7 | def scrape_weibo(url: str): 8 | '''爬取相关鲜花服务商的资料''' 9 | headers = { 10 | "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36", 11 | "Referer": "https://weibo.com" 12 | } 13 | cookies = { 14 | "cookie": '''your cookie''' 15 | } 16 | response = requests.get(url, headers=headers, cookies=cookies) 17 | time.sleep(3) # 加上3s 的延时防止被反爬 18 | return response.text 19 | 20 | # 根据UID构建URL爬取信息 21 | def get_data(id): 22 | url = "https://weibo.com/ajax/profile/detail?uid={}".format(id) 23 | html = scrape_weibo(url) 24 | response = json.loads(html) 25 | 26 | return response -------------------------------------------------------------------------------- /21_人脉工具下/socializer_v3/tools/search_tool.py: -------------------------------------------------------------------------------- 1 | # 导入SerpAPIWrapper 2 | from langchain.utilities import SerpAPIWrapper 3 | 4 | # 重新定制SerpAPIWrapper,重构_process_response,返回URL 5 | class CustomSerpAPIWrapper(SerpAPIWrapper): 6 | def __init__(self): 7 | super(CustomSerpAPIWrapper, self).__init__() 8 | 9 | @staticmethod 10 | def _process_response(res: dict) -> str: 11 | """Process response from SerpAPI.""" 12 | if "error" in res.keys(): 13 | raise ValueError(f"Got error from SerpAPI: {res['error']}") 14 | if "answer_box_list" in res.keys(): 15 | res["answer_box"] = res["answer_box_list"] 16 | if "answer_box" in res.keys(): 17 | answer_box = res["answer_box"] 18 | if isinstance(answer_box, list): 19 | answer_box = answer_box[0] 20 | if "result" in answer_box.keys(): 21 | return answer_box["result"] 22 | elif "answer" in answer_box.keys(): 23 | return answer_box["answer"] 24 | elif "snippet" in answer_box.keys(): 25 | return answer_box["snippet"] 26 | elif "snippet_highlighted_words" in answer_box.keys(): 27 | return answer_box["snippet_highlighted_words"] 28 | else: 29 | answer = {} 30 | for key, value in answer_box.items(): 31 | if not isinstance(value, (list, dict)) and not ( 32 | isinstance(value, str) and value.startswith("http") 33 | ): 34 | answer[key] = value 35 | return str(answer) 36 | elif "events_results" in res.keys(): 37 | return res["events_results"][:10] 38 | elif "sports_results" in res.keys(): 39 | return res["sports_results"] 40 | elif "top_stories" in res.keys(): 41 | return res["top_stories"] 42 | elif "news_results" in res.keys(): 43 | return res["news_results"] 44 | elif "jobs_results" in res.keys() and "jobs" in res["jobs_results"].keys(): 45 | return res["jobs_results"]["jobs"] 46 | elif ( 47 | "shopping_results" in res.keys() 48 | and "title" in res["shopping_results"][0].keys() 49 | ): 50 | return res["shopping_results"][:3] 51 | elif "questions_and_answers" in res.keys(): 52 | return res["questions_and_answers"] 53 | elif ( 54 | "popular_destinations" in res.keys() 55 | and "destinations" in res["popular_destinations"].keys() 56 | ): 57 | return res["popular_destinations"]["destinations"] 58 | elif "top_sights" in res.keys() and "sights" in res["top_sights"].keys(): 59 | return res["top_sights"]["sights"] 60 | elif ( 61 | "images_results" in res.keys() 62 | and "thumbnail" in res["images_results"][0].keys() 63 | ): 64 | return str([item["thumbnail"] for item in res["images_results"][:10]]) 65 | 66 | snippets = [] 67 | if "knowledge_graph" in res.keys(): 68 | knowledge_graph = res["knowledge_graph"] 69 | title = knowledge_graph["title"] if "title" in knowledge_graph else "" 70 | if "description" in knowledge_graph.keys(): 71 | snippets.append(knowledge_graph["description"]) 72 | for key, value in knowledge_graph.items(): 73 | if ( 74 | isinstance(key, str) 75 | and isinstance(value, str) 76 | and key not in ["title", "description"] 77 | and not key.endswith("_stick") 78 | and not key.endswith("_link") 79 | and not value.startswith("http") 80 | ): 81 | snippets.append(f"{title} {key}: {value}.") 82 | if "organic_results" in res.keys(): 83 | first_organic_result = res["organic_results"][0] 84 | if "snippet" in first_organic_result.keys(): 85 | # snippets.append(first_organic_result["snippet"]) 86 | snippets.append(first_organic_result["link"]) 87 | elif "snippet_highlighted_words" in first_organic_result.keys(): 88 | snippets.append(first_organic_result["snippet_highlighted_words"]) 89 | elif "rich_snippet" in first_organic_result.keys(): 90 | snippets.append(first_organic_result["rich_snippet"]) 91 | elif "rich_snippet_table" in first_organic_result.keys(): 92 | snippets.append(first_organic_result["rich_snippet_table"]) 93 | elif "link" in first_organic_result.keys(): 94 | snippets.append(first_organic_result["link"]) 95 | if "buying_guide" in res.keys(): 96 | snippets.append(res["buying_guide"]) 97 | if "local_results" in res.keys() and "places" in res["local_results"].keys(): 98 | snippets.append(res["local_results"]["places"]) 99 | 100 | if len(snippets) > 0: 101 | return str(snippets) 102 | else: 103 | return "No good search result found" 104 | 105 | # 获取与某种鲜花相关的微博UID的函数 106 | def get_UID(flower: str): 107 | # search = SerpAPIWrapper() 108 | search = CustomSerpAPIWrapper() 109 | res = search.run(f"{flower}") 110 | return res -------------------------------------------------------------------------------- /21_人脉工具下/socializer_v3/tools/textgen_tool.py: -------------------------------------------------------------------------------- 1 | # 导入所需要的库 2 | from langchain.prompts import PromptTemplate 3 | from langchain.chat_models import ChatOpenAI 4 | from langchain.chains import LLMChain 5 | 6 | 7 | # 生成文案的函数 8 | def generate_letter(information): 9 | 10 | # 设计提示模板 11 | ice_breaker_template = """ 12 | 下面是这个人的微博信息 {information} 13 | 请你帮我: 14 | 1. 写一个简单的总结 15 | 2. 挑两件有趣的事情说一说 16 | 3. 找一些他比较感兴趣的事情 17 | 4. 写一篇热情洋溢的介绍信 18 | """ 19 | summary_prompt_template = PromptTemplate( 20 | input_variables=["information"], 21 | template=ice_breaker_template 22 | ) 23 | 24 | # 初始化大模型 25 | llm = ChatOpenAI(model_name="gpt-3.5-turbo") 26 | 27 | # 初始化链 28 | chain = LLMChain(llm=llm, prompt=summary_prompt_template) 29 | 30 | # 生成文案 31 | result = chain.run(information = information) 32 | return result -------------------------------------------------------------------------------- /21_人脉工具下/socializer_v4/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huangjia2019/langchain-in-action/6a899d656b6afa4497c53c7a535e83d98a3b63ad/21_人脉工具下/socializer_v4/__init__.py -------------------------------------------------------------------------------- /21_人脉工具下/socializer_v4/agents/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huangjia2019/langchain-in-action/6a899d656b6afa4497c53c7a535e83d98a3b63ad/21_人脉工具下/socializer_v4/agents/__init__.py -------------------------------------------------------------------------------- /21_人脉工具下/socializer_v4/agents/__pycache__/__init__.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huangjia2019/langchain-in-action/6a899d656b6afa4497c53c7a535e83d98a3b63ad/21_人脉工具下/socializer_v4/agents/__pycache__/__init__.cpython-311.pyc -------------------------------------------------------------------------------- /21_人脉工具下/socializer_v4/agents/__pycache__/weibo_agent.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huangjia2019/langchain-in-action/6a899d656b6afa4497c53c7a535e83d98a3b63ad/21_人脉工具下/socializer_v4/agents/__pycache__/weibo_agent.cpython-311.pyc -------------------------------------------------------------------------------- /21_人脉工具下/socializer_v4/agents/weibo_agent.py: -------------------------------------------------------------------------------- 1 | # 导入一个搜索UID的工具 2 | from tools.search_tool import get_UID 3 | 4 | # 导入所需的库 5 | from langchain.prompts import PromptTemplate 6 | from langchain.chat_models import ChatOpenAI 7 | from langchain.agents import initialize_agent, Tool 8 | from langchain.agents import AgentType 9 | 10 | # 通过LangChain代理找到UID的函数 11 | def lookup_V(flower_type: str) : 12 | # 初始化大模型 13 | llm = ChatOpenAI(temperature=0, model_name="gpt-3.5-turbo") 14 | 15 | # 寻找UID的模板 16 | template = """given the {flower} I want you to get a related 微博 UID. 17 | Your answer should contain only a UID. 18 | The URL always starts with https://weibo.com/u/ 19 | for example, if https://weibo.com/u/1669879400 is her 微博, then 1669879400 is her UID 20 | This is only the example don't give me this, but the actual UID""" 21 | # 完整的提示模板 22 | prompt_template = PromptTemplate( 23 | input_variables=["flower"], template=template 24 | ) 25 | 26 | # 代理的工具 27 | tools = [ 28 | Tool( 29 | name="Crawl Google for 微博 page", 30 | func=get_UID, 31 | description="useful for when you need get the 微博 UID", 32 | ) 33 | ] 34 | 35 | # 初始化代理 36 | agent = initialize_agent( 37 | tools, 38 | llm, 39 | agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, 40 | verbose=True 41 | ) 42 | 43 | # 返回找到的UID 44 | ID = agent.run(prompt_template.format_prompt(flower=flower_type)) 45 | 46 | return ID -------------------------------------------------------------------------------- /21_人脉工具下/socializer_v4/findbigV.py: -------------------------------------------------------------------------------- 1 | # 设置OpenAI API密钥 2 | import os 3 | os.environ["OPENAI_API_KEY"] = 'your key' 4 | os.environ["SERPAPI_API_KEY"] = 'your key' 5 | 6 | # 导入所取的库 7 | import re 8 | from agents.weibo_agent import lookup_V 9 | from tools.general_tool import remove_non_chinese_fields 10 | from tools.scraping_tool import get_data 11 | from tools.textgen_tool import generate_letter 12 | 13 | 14 | if __name__ == "__main__": 15 | 16 | # 拿到UID 17 | response_UID = lookup_V(flower_type = "牡丹" ) 18 | 19 | # 抽取UID里面的数字 20 | UID = re.findall(r'\d+', response_UID)[0] 21 | print("这位鲜花大V的微博ID是", UID) 22 | 23 | # 根据UID爬取大V信息 24 | person_info = get_data(UID) 25 | print(person_info) 26 | 27 | # 移除无用的信息 28 | remove_non_chinese_fields(person_info) 29 | print(person_info) 30 | 31 | # 调用函数根据大V信息生成文本 32 | result = generate_letter(information = person_info) 33 | print(result) 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /21_人脉工具下/socializer_v4/tools/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huangjia2019/langchain-in-action/6a899d656b6afa4497c53c7a535e83d98a3b63ad/21_人脉工具下/socializer_v4/tools/__init__.py -------------------------------------------------------------------------------- /21_人脉工具下/socializer_v4/tools/__pycache__/__init__.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huangjia2019/langchain-in-action/6a899d656b6afa4497c53c7a535e83d98a3b63ad/21_人脉工具下/socializer_v4/tools/__pycache__/__init__.cpython-311.pyc -------------------------------------------------------------------------------- /21_人脉工具下/socializer_v4/tools/__pycache__/general_tool.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huangjia2019/langchain-in-action/6a899d656b6afa4497c53c7a535e83d98a3b63ad/21_人脉工具下/socializer_v4/tools/__pycache__/general_tool.cpython-311.pyc -------------------------------------------------------------------------------- /21_人脉工具下/socializer_v4/tools/__pycache__/parsing_tool.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huangjia2019/langchain-in-action/6a899d656b6afa4497c53c7a535e83d98a3b63ad/21_人脉工具下/socializer_v4/tools/__pycache__/parsing_tool.cpython-311.pyc -------------------------------------------------------------------------------- /21_人脉工具下/socializer_v4/tools/__pycache__/scraping_tool.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huangjia2019/langchain-in-action/6a899d656b6afa4497c53c7a535e83d98a3b63ad/21_人脉工具下/socializer_v4/tools/__pycache__/scraping_tool.cpython-311.pyc -------------------------------------------------------------------------------- /21_人脉工具下/socializer_v4/tools/__pycache__/search_tool.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huangjia2019/langchain-in-action/6a899d656b6afa4497c53c7a535e83d98a3b63ad/21_人脉工具下/socializer_v4/tools/__pycache__/search_tool.cpython-311.pyc -------------------------------------------------------------------------------- /21_人脉工具下/socializer_v4/tools/__pycache__/textgen_tool.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huangjia2019/langchain-in-action/6a899d656b6afa4497c53c7a535e83d98a3b63ad/21_人脉工具下/socializer_v4/tools/__pycache__/textgen_tool.cpython-311.pyc -------------------------------------------------------------------------------- /21_人脉工具下/socializer_v4/tools/general_tool.py: -------------------------------------------------------------------------------- 1 | import re 2 | 3 | def contains_chinese(s): 4 | return bool(re.search('[\u4e00-\u9fa5]', s)) 5 | 6 | def remove_non_chinese_fields(d): 7 | if isinstance(d, dict): 8 | to_remove = [key for key, value in d.items() if isinstance(value, (str, int, float, bool)) and (not contains_chinese(str(value)))] 9 | for key in to_remove: 10 | del d[key] 11 | 12 | for key, value in d.items(): 13 | if isinstance(value, (dict, list)): 14 | remove_non_chinese_fields(value) 15 | elif isinstance(d, list): 16 | to_remove_indices = [] 17 | for i, item in enumerate(d): 18 | if isinstance(item, (str, int, float, bool)) and (not contains_chinese(str(item))): 19 | to_remove_indices.append(i) 20 | else: 21 | remove_non_chinese_fields(item) 22 | 23 | for index in reversed(to_remove_indices): 24 | d.pop(index) -------------------------------------------------------------------------------- /21_人脉工具下/socializer_v4/tools/parsing_tool.py: -------------------------------------------------------------------------------- 1 | # 导入所需的类 2 | from langchain.output_parsers import PydanticOutputParser 3 | from pydantic import BaseModel, Field 4 | from typing import List 5 | 6 | # 定义一个名为TextParsing的模型,描述了如何解析大V信息 7 | class TextParsing(BaseModel): 8 | summary: str = Field(description="大V个人简介") # 大V的简介或背景信息 9 | facts: List[str] = Field(description="大V的特点") # 大V的一些显著特点或者事实 10 | interest: List[str] = Field(description="这个大V可能感兴趣的事情") # 大V可能感兴趣的主题或活动 11 | letter: List[str] = Field(description="一篇联络这个大V的邮件") # 联络大V的建议邮件内容 12 | 13 | # 将模型对象转换为字典 14 | def to_dict(self): 15 | return { 16 | "summary": self.summary, 17 | "facts": self.facts, 18 | "interest": self.interest, 19 | "letter": self.letter, 20 | } 21 | 22 | # 创建一个基于Pydantic模型的解析器,用于将文本输出解析为特定的结构 23 | letter_parser: PydanticOutputParser = PydanticOutputParser( 24 | pydantic_object=TextParsing 25 | ) -------------------------------------------------------------------------------- /21_人脉工具下/socializer_v4/tools/scraping_tool.py: -------------------------------------------------------------------------------- 1 | # 导入所需的库 2 | import json 3 | import requests 4 | import time 5 | 6 | # 定义爬取微博用户信息的函数 7 | def scrape_weibo(url: str): 8 | '''爬取相关鲜花服务商的资料''' 9 | headers = { 10 | "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36", 11 | "Referer": "https://weibo.com" 12 | } 13 | cookies = { 14 | "cookie": '''your cookie''' 15 | } 16 | response = requests.get(url, headers=headers, cookies=cookies) 17 | time.sleep(3) # 加上3s 的延时防止被反爬 18 | return response.text 19 | 20 | # 根据UID构建URL爬取信息 21 | def get_data(id): 22 | url = "https://weibo.com/ajax/profile/detail?uid={}".format(id) 23 | html = scrape_weibo(url) 24 | response = json.loads(html) 25 | 26 | return response -------------------------------------------------------------------------------- /21_人脉工具下/socializer_v4/tools/search_tool.py: -------------------------------------------------------------------------------- 1 | # 导入SerpAPIWrapper 2 | from langchain.utilities import SerpAPIWrapper 3 | 4 | # 重新定制SerpAPIWrapper,重构_process_response,返回URL 5 | class CustomSerpAPIWrapper(SerpAPIWrapper): 6 | def __init__(self): 7 | super(CustomSerpAPIWrapper, self).__init__() 8 | 9 | @staticmethod 10 | def _process_response(res: dict) -> str: 11 | """Process response from SerpAPI.""" 12 | if "error" in res.keys(): 13 | raise ValueError(f"Got error from SerpAPI: {res['error']}") 14 | if "answer_box_list" in res.keys(): 15 | res["answer_box"] = res["answer_box_list"] 16 | if "answer_box" in res.keys(): 17 | answer_box = res["answer_box"] 18 | if isinstance(answer_box, list): 19 | answer_box = answer_box[0] 20 | if "result" in answer_box.keys(): 21 | return answer_box["result"] 22 | elif "answer" in answer_box.keys(): 23 | return answer_box["answer"] 24 | elif "snippet" in answer_box.keys(): 25 | return answer_box["snippet"] 26 | elif "snippet_highlighted_words" in answer_box.keys(): 27 | return answer_box["snippet_highlighted_words"] 28 | else: 29 | answer = {} 30 | for key, value in answer_box.items(): 31 | if not isinstance(value, (list, dict)) and not ( 32 | isinstance(value, str) and value.startswith("http") 33 | ): 34 | answer[key] = value 35 | return str(answer) 36 | elif "events_results" in res.keys(): 37 | return res["events_results"][:10] 38 | elif "sports_results" in res.keys(): 39 | return res["sports_results"] 40 | elif "top_stories" in res.keys(): 41 | return res["top_stories"] 42 | elif "news_results" in res.keys(): 43 | return res["news_results"] 44 | elif "jobs_results" in res.keys() and "jobs" in res["jobs_results"].keys(): 45 | return res["jobs_results"]["jobs"] 46 | elif ( 47 | "shopping_results" in res.keys() 48 | and "title" in res["shopping_results"][0].keys() 49 | ): 50 | return res["shopping_results"][:3] 51 | elif "questions_and_answers" in res.keys(): 52 | return res["questions_and_answers"] 53 | elif ( 54 | "popular_destinations" in res.keys() 55 | and "destinations" in res["popular_destinations"].keys() 56 | ): 57 | return res["popular_destinations"]["destinations"] 58 | elif "top_sights" in res.keys() and "sights" in res["top_sights"].keys(): 59 | return res["top_sights"]["sights"] 60 | elif ( 61 | "images_results" in res.keys() 62 | and "thumbnail" in res["images_results"][0].keys() 63 | ): 64 | return str([item["thumbnail"] for item in res["images_results"][:10]]) 65 | 66 | snippets = [] 67 | if "knowledge_graph" in res.keys(): 68 | knowledge_graph = res["knowledge_graph"] 69 | title = knowledge_graph["title"] if "title" in knowledge_graph else "" 70 | if "description" in knowledge_graph.keys(): 71 | snippets.append(knowledge_graph["description"]) 72 | for key, value in knowledge_graph.items(): 73 | if ( 74 | isinstance(key, str) 75 | and isinstance(value, str) 76 | and key not in ["title", "description"] 77 | and not key.endswith("_stick") 78 | and not key.endswith("_link") 79 | and not value.startswith("http") 80 | ): 81 | snippets.append(f"{title} {key}: {value}.") 82 | if "organic_results" in res.keys(): 83 | first_organic_result = res["organic_results"][0] 84 | if "snippet" in first_organic_result.keys(): 85 | # snippets.append(first_organic_result["snippet"]) 86 | snippets.append(first_organic_result["link"]) 87 | elif "snippet_highlighted_words" in first_organic_result.keys(): 88 | snippets.append(first_organic_result["snippet_highlighted_words"]) 89 | elif "rich_snippet" in first_organic_result.keys(): 90 | snippets.append(first_organic_result["rich_snippet"]) 91 | elif "rich_snippet_table" in first_organic_result.keys(): 92 | snippets.append(first_organic_result["rich_snippet_table"]) 93 | elif "link" in first_organic_result.keys(): 94 | snippets.append(first_organic_result["link"]) 95 | if "buying_guide" in res.keys(): 96 | snippets.append(res["buying_guide"]) 97 | if "local_results" in res.keys() and "places" in res["local_results"].keys(): 98 | snippets.append(res["local_results"]["places"]) 99 | 100 | if len(snippets) > 0: 101 | return str(snippets) 102 | else: 103 | return "No good search result found" 104 | 105 | # 获取与某种鲜花相关的微博UID的函数 106 | def get_UID(flower: str): 107 | # search = SerpAPIWrapper() 108 | search = CustomSerpAPIWrapper() 109 | res = search.run(f"{flower}") 110 | return res -------------------------------------------------------------------------------- /21_人脉工具下/socializer_v4/tools/textgen_tool.py: -------------------------------------------------------------------------------- 1 | # 导入所需要的库 2 | from langchain.prompts import PromptTemplate 3 | from langchain.chat_models import ChatOpenAI 4 | from langchain.chains import LLMChain 5 | from tools.parsing_tool import letter_parser 6 | 7 | 8 | # 生成文案的函数 9 | def generate_letter(information): 10 | 11 | # 设计提示模板 12 | letter_template = """ 13 | 下面是这个人的微博信息 {information} 14 | 请你帮我: 15 | 1. 写一个简单的总结 16 | 2. 挑两件有趣的特点说一说 17 | 3. 找一些他比较感兴趣的事情 18 | 4. 写一篇热情洋溢的介绍信 19 | \n{format_instructions}""" 20 | 21 | prompt_template = PromptTemplate( 22 | input_variables=["information"], 23 | template=letter_template, 24 | partial_variables={ 25 | "format_instructions": letter_parser.get_format_instructions() 26 | }, 27 | ) 28 | 29 | # 初始化大模型 30 | llm = ChatOpenAI(model_name="gpt-3.5-turbo") 31 | 32 | # 初始化链 33 | chain = LLMChain(llm=llm, prompt=prompt_template) 34 | 35 | # 生成文案 36 | result = chain.run(information = information) 37 | return result -------------------------------------------------------------------------------- /21_人脉工具下/socializer_v5/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huangjia2019/langchain-in-action/6a899d656b6afa4497c53c7a535e83d98a3b63ad/21_人脉工具下/socializer_v5/__init__.py -------------------------------------------------------------------------------- /21_人脉工具下/socializer_v5/__pycache__/findbigV.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huangjia2019/langchain-in-action/6a899d656b6afa4497c53c7a535e83d98a3b63ad/21_人脉工具下/socializer_v5/__pycache__/findbigV.cpython-311.pyc -------------------------------------------------------------------------------- /21_人脉工具下/socializer_v5/agents/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huangjia2019/langchain-in-action/6a899d656b6afa4497c53c7a535e83d98a3b63ad/21_人脉工具下/socializer_v5/agents/__init__.py -------------------------------------------------------------------------------- /21_人脉工具下/socializer_v5/agents/__pycache__/__init__.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huangjia2019/langchain-in-action/6a899d656b6afa4497c53c7a535e83d98a3b63ad/21_人脉工具下/socializer_v5/agents/__pycache__/__init__.cpython-311.pyc -------------------------------------------------------------------------------- /21_人脉工具下/socializer_v5/agents/__pycache__/weibo_agent.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huangjia2019/langchain-in-action/6a899d656b6afa4497c53c7a535e83d98a3b63ad/21_人脉工具下/socializer_v5/agents/__pycache__/weibo_agent.cpython-311.pyc -------------------------------------------------------------------------------- /21_人脉工具下/socializer_v5/agents/weibo_agent.py: -------------------------------------------------------------------------------- 1 | # 导入一个搜索UID的工具 2 | from tools.search_tool import get_UID 3 | 4 | # 导入所需的库 5 | from langchain.prompts import PromptTemplate 6 | from langchain.chat_models import ChatOpenAI 7 | from langchain.agents import initialize_agent, Tool 8 | from langchain.agents import AgentType 9 | 10 | # 通过LangChain代理找到UID的函数 11 | def lookup_V(flower_type: str) : 12 | # 初始化大模型 13 | llm = ChatOpenAI(temperature=0, model_name="gpt-3.5-turbo") 14 | 15 | # 寻找UID的模板 16 | template = """given the {flower} I want you to get a related 微博 UID. 17 | Your answer should contain only a UID. 18 | The URL always starts with https://weibo.com/u/ 19 | for example, if https://weibo.com/u/1669879400 is her 微博, then 1669879400 is her UID 20 | This is only the example don't give me this, but the actual UID""" 21 | # 完整的提示模板 22 | prompt_template = PromptTemplate( 23 | input_variables=["flower"], template=template 24 | ) 25 | 26 | # 代理的工具 27 | tools = [ 28 | Tool( 29 | name="Crawl Google for 微博 page", 30 | func=get_UID, 31 | description="useful for when you need get the 微博 UID", 32 | ) 33 | ] 34 | 35 | # 初始化代理 36 | agent = initialize_agent( 37 | tools, 38 | llm, 39 | agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, 40 | verbose=True 41 | ) 42 | 43 | # 返回找到的UID 44 | ID = agent.run(prompt_template.format_prompt(flower=flower_type)) 45 | 46 | return ID -------------------------------------------------------------------------------- /21_人脉工具下/socializer_v5/app.py: -------------------------------------------------------------------------------- 1 | # 导入所需的库和模块 2 | from flask import Flask, render_template, request, jsonify 3 | from findbigV import find_bigV 4 | import json 5 | 6 | # 实例化Flask应用 7 | app = Flask(__name__) 8 | 9 | # 主页路由,返回index.html模板 10 | @app.route("/") 11 | def index(): 12 | return render_template("index.html") 13 | 14 | # 处理请求的路由,仅允许POST请求 15 | @app.route("/process", methods=["POST"]) 16 | def process(): 17 | # 获取提交的花的名称 18 | flower = request.form["flower"] 19 | # 使用find_bigV函数获取相关数据 20 | response_str = find_bigV(flower=flower) 21 | # 使用json.loads将字符串解析为字典 22 | response = json.loads(response_str) 23 | 24 | # 返回数据的json响应 25 | return jsonify( 26 | { 27 | "summary": response["summary"], 28 | "facts": response["facts"], 29 | "interest": response["interest"], 30 | "letter": response["letter"], 31 | } 32 | ) 33 | 34 | # 判断是否是主程序运行,并设置Flask应用的host和debug模式 35 | if __name__ == "__main__": 36 | app.run(host="0.0.0.0", debug=True) 37 | -------------------------------------------------------------------------------- /21_人脉工具下/socializer_v5/findbigV.py: -------------------------------------------------------------------------------- 1 | # 设置OpenAI API密钥 2 | import os 3 | os.environ["OPENAI_API_KEY"] = 'your key' 4 | os.environ["SERPAPI_API_KEY"] = 'your key' 5 | 6 | # 导入所取的库 7 | import re 8 | from agents.weibo_agent import lookup_V 9 | from tools.general_tool import remove_non_chinese_fields 10 | from tools.scraping_tool import get_data 11 | from tools.textgen_tool import generate_letter 12 | 13 | 14 | def find_bigV(flower: str) : 15 | # 拿到UID 16 | response_UID = lookup_V(flower_type = flower ) 17 | 18 | # 抽取UID里面的数字 19 | UID = re.findall(r'\d+', response_UID)[0] 20 | print("这位鲜花大V的微博ID是", UID) 21 | 22 | # 根据UID爬取大V信息 23 | person_info = get_data(UID) 24 | print(person_info) 25 | 26 | # 移除无用的信息 27 | remove_non_chinese_fields(person_info) 28 | print(person_info) 29 | 30 | # 调用函数根据大V信息生成文本 31 | result = generate_letter(information = person_info) 32 | print(result) 33 | 34 | return result 35 | 36 | 37 | if __name__ == "__main__": 38 | 39 | # 拿到UID 40 | response_UID = lookup_V(flower_type = "牡丹" ) 41 | 42 | # 抽取UID里面的数字 43 | UID = re.findall(r'\d+', response_UID)[0] 44 | print("这位鲜花大V的微博ID是", UID) 45 | 46 | # 根据UID爬取大V信息 47 | person_info = get_data(UID) 48 | print(person_info) 49 | 50 | # 移除无用的信息 51 | remove_non_chinese_fields(person_info) 52 | print(person_info) 53 | 54 | result = generate_letter(information = person_info) 55 | print(result) 56 | 57 | from flask import jsonify 58 | import json 59 | # 使用json.loads将字符串解析为字典 60 | result = json.loads(result) 61 | abc = jsonify( 62 | { 63 | "summary": result["summary"], 64 | "facts": result["facts"], 65 | "interest": result["interest"], 66 | "letter": result["letter"], 67 | } 68 | ) 69 | 70 | 71 | -------------------------------------------------------------------------------- /21_人脉工具下/socializer_v5/static/css/style.css: -------------------------------------------------------------------------------- 1 | /* static/css/style.css */ 2 | 3 | * { 4 | box-sizing: border-box; 5 | margin: 0; 6 | padding: 0; 7 | } 8 | 9 | body { 10 | font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; 11 | background-color: #f5f5f5; 12 | color: #333; 13 | line-height: 1.6; 14 | } 15 | 16 | .container { 17 | width: 80%; 18 | margin: 0 auto; 19 | padding: 30px; 20 | background-color: #ffffff; 21 | box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); 22 | border-radius: 5px; 23 | display: flex; 24 | flex-direction: column; 25 | align-items: center; 26 | } 27 | 28 | h1 { 29 | font-size: 32px; 30 | margin-bottom: 20px; 31 | } 32 | 33 | input[type="text"] { 34 | width: 100%; 35 | padding: 12px 20px; 36 | margin: 8px 0; 37 | box-sizing: border-box; 38 | border: 2px solid #ccc; 39 | border-radius: 4px; 40 | background-color: #f8f8f8; 41 | font-size: 14px; 42 | } 43 | 44 | button { 45 | background-color: #4caf50; 46 | border: none; 47 | color: white; 48 | padding: 15px 32px; 49 | text-align: center; 50 | text-decoration: none; 51 | display: inline-block; 52 | font-size: 16px; 53 | margin: 4px 2px; 54 | cursor: pointer; 55 | border-radius: 4px; 56 | transition: 0.3s; 57 | } 58 | 59 | button:hover { 60 | background-color: #45a049; 61 | } 62 | 63 | #result { 64 | margin-top: 30px; 65 | width: 100%; 66 | text-align: center; 67 | } 68 | 69 | 70 | #loading { 71 | display: none; 72 | position: fixed; 73 | top: 0; 74 | right: 0; 75 | bottom: 0; 76 | left: 0; 77 | z-index: 999; 78 | background-color: rgba(255, 255, 255, 0.8); 79 | } 80 | 81 | .loader { 82 | position: absolute; 83 | top: 50%; 84 | left: 50%; 85 | transform: translate(-50%, -50%); 86 | border: 8px solid #f3f3f3; 87 | border-top: 8px solid #3498db; 88 | border-radius: 50%; 89 | width: 50px; 90 | height: 50px; 91 | animation: spin 2s linear infinite; 92 | } 93 | 94 | p { 95 | font-size: 18px; 96 | margin-bottom: 10px; 97 | } 98 | 99 | h2 { 100 | font-size: 24px; 101 | margin-bottom: 10px; 102 | margin-top: 20px; 103 | } 104 | 105 | 106 | /* style.css */ 107 | 108 | /* Add or update this in your style.css file */ 109 | 110 | body { 111 | font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; 112 | background-color: #f5f5f5; 113 | color: #333; 114 | line-height: 1.6; 115 | background-image: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%); 116 | } 117 | 118 | .spinner-container { 119 | position: fixed; 120 | display: flex; 121 | align-items: center; 122 | justify-content: center; 123 | top: 0; 124 | right: 0; 125 | bottom: 0; 126 | left: 0; 127 | z-index: 999; 128 | } 129 | 130 | #loading-spinner { 131 | font-size: 48px; 132 | } 133 | 134 | button { 135 | background-color: #4caf50; 136 | background-image: linear-gradient(135deg, #43c6ac 0%, #191654 100%); 137 | border: none; 138 | color: white; 139 | padding: 15px 32px; 140 | text-align: center; 141 | text-decoration: none; 142 | display: inline-block; 143 | font-size: 16px; 144 | margin: 4px 2px; 145 | cursor: pointer; 146 | border-radius: 4px; 147 | transition: 0.3s; 148 | } 149 | 150 | ul { 151 | list-style-type: none; 152 | } -------------------------------------------------------------------------------- /21_人脉工具下/socializer_v5/templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 人脉工具 11 | 12 | 15 | 16 | 17 |
18 |

易速鲜花人脉工具

19 |
20 | 21 | 22 |
23 |
24 | 25 |

基本情况

26 |

27 |

特色内容

28 |
29 |

可能感兴趣的事儿

30 |
31 |

联络邮件

32 |
33 |
34 |
35 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /21_人脉工具下/socializer_v5/tools/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huangjia2019/langchain-in-action/6a899d656b6afa4497c53c7a535e83d98a3b63ad/21_人脉工具下/socializer_v5/tools/__init__.py -------------------------------------------------------------------------------- /21_人脉工具下/socializer_v5/tools/__pycache__/__init__.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huangjia2019/langchain-in-action/6a899d656b6afa4497c53c7a535e83d98a3b63ad/21_人脉工具下/socializer_v5/tools/__pycache__/__init__.cpython-311.pyc -------------------------------------------------------------------------------- /21_人脉工具下/socializer_v5/tools/__pycache__/general_tool.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huangjia2019/langchain-in-action/6a899d656b6afa4497c53c7a535e83d98a3b63ad/21_人脉工具下/socializer_v5/tools/__pycache__/general_tool.cpython-311.pyc -------------------------------------------------------------------------------- /21_人脉工具下/socializer_v5/tools/__pycache__/parsing_tool.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huangjia2019/langchain-in-action/6a899d656b6afa4497c53c7a535e83d98a3b63ad/21_人脉工具下/socializer_v5/tools/__pycache__/parsing_tool.cpython-311.pyc -------------------------------------------------------------------------------- /21_人脉工具下/socializer_v5/tools/__pycache__/scraping_tool.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huangjia2019/langchain-in-action/6a899d656b6afa4497c53c7a535e83d98a3b63ad/21_人脉工具下/socializer_v5/tools/__pycache__/scraping_tool.cpython-311.pyc -------------------------------------------------------------------------------- /21_人脉工具下/socializer_v5/tools/__pycache__/search_tool.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huangjia2019/langchain-in-action/6a899d656b6afa4497c53c7a535e83d98a3b63ad/21_人脉工具下/socializer_v5/tools/__pycache__/search_tool.cpython-311.pyc -------------------------------------------------------------------------------- /21_人脉工具下/socializer_v5/tools/__pycache__/textgen_tool.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huangjia2019/langchain-in-action/6a899d656b6afa4497c53c7a535e83d98a3b63ad/21_人脉工具下/socializer_v5/tools/__pycache__/textgen_tool.cpython-311.pyc -------------------------------------------------------------------------------- /21_人脉工具下/socializer_v5/tools/general_tool.py: -------------------------------------------------------------------------------- 1 | import re 2 | 3 | def contains_chinese(s): 4 | return bool(re.search('[\u4e00-\u9fa5]', s)) 5 | 6 | def remove_non_chinese_fields(d): 7 | if isinstance(d, dict): 8 | to_remove = [key for key, value in d.items() if isinstance(value, (str, int, float, bool)) and (not contains_chinese(str(value)))] 9 | for key in to_remove: 10 | del d[key] 11 | 12 | for key, value in d.items(): 13 | if isinstance(value, (dict, list)): 14 | remove_non_chinese_fields(value) 15 | elif isinstance(d, list): 16 | to_remove_indices = [] 17 | for i, item in enumerate(d): 18 | if isinstance(item, (str, int, float, bool)) and (not contains_chinese(str(item))): 19 | to_remove_indices.append(i) 20 | else: 21 | remove_non_chinese_fields(item) 22 | 23 | for index in reversed(to_remove_indices): 24 | d.pop(index) -------------------------------------------------------------------------------- /21_人脉工具下/socializer_v5/tools/parsing_tool.py: -------------------------------------------------------------------------------- 1 | # 导入所需的类 2 | from langchain.output_parsers import PydanticOutputParser 3 | from pydantic import BaseModel, Field 4 | from typing import List 5 | 6 | # 定义一个名为TextParsing的模型,描述了如何解析大V信息 7 | class TextParsing(BaseModel): 8 | summary: str = Field(description="大V个人简介") # 大V的简介或背景信息 9 | facts: List[str] = Field(description="大V的特点") # 大V的一些显著特点或者事实 10 | interest: List[str] = Field(description="这个大V可能感兴趣的事情") # 大V可能感兴趣的主题或活动 11 | letter: List[str] = Field(description="一篇联络这个大V的邮件") # 联络大V的建议邮件内容 12 | 13 | # 将模型对象转换为字典 14 | def to_dict(self): 15 | return { 16 | "summary": self.summary, 17 | "facts": self.facts, 18 | "interest": self.interest, 19 | "letter": self.letter, 20 | } 21 | 22 | # 创建一个基于Pydantic模型的解析器,用于将文本输出解析为特定的结构 23 | letter_parser: PydanticOutputParser = PydanticOutputParser( 24 | pydantic_object=TextParsing 25 | ) -------------------------------------------------------------------------------- /21_人脉工具下/socializer_v5/tools/scraping_tool.py: -------------------------------------------------------------------------------- 1 | # 导入所需的库 2 | import json 3 | import requests 4 | import time 5 | 6 | # 定义爬取微博用户信息的函数 7 | def scrape_weibo(url: str): 8 | '''爬取相关鲜花服务商的资料''' 9 | headers = { 10 | "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36", 11 | "Referer": "https://weibo.com" 12 | } 13 | cookies = { 14 | "cookie": '''your cookie''' 15 | } 16 | response = requests.get(url, headers=headers, cookies=cookies) 17 | time.sleep(3) # 加上3s 的延时防止被反爬 18 | return response.text 19 | 20 | # 根据UID构建URL爬取信息 21 | def get_data(id): 22 | url = "https://weibo.com/ajax/profile/detail?uid={}".format(id) 23 | html = scrape_weibo(url) 24 | response = json.loads(html) 25 | 26 | return response -------------------------------------------------------------------------------- /21_人脉工具下/socializer_v5/tools/search_tool.py: -------------------------------------------------------------------------------- 1 | # 导入SerpAPIWrapper 2 | from langchain.utilities import SerpAPIWrapper 3 | 4 | # 重新定制SerpAPIWrapper,重构_process_response,返回URL 5 | class CustomSerpAPIWrapper(SerpAPIWrapper): 6 | def __init__(self): 7 | super(CustomSerpAPIWrapper, self).__init__() 8 | 9 | @staticmethod 10 | def _process_response(res: dict) -> str: 11 | """Process response from SerpAPI.""" 12 | if "error" in res.keys(): 13 | raise ValueError(f"Got error from SerpAPI: {res['error']}") 14 | if "answer_box_list" in res.keys(): 15 | res["answer_box"] = res["answer_box_list"] 16 | if "answer_box" in res.keys(): 17 | answer_box = res["answer_box"] 18 | if isinstance(answer_box, list): 19 | answer_box = answer_box[0] 20 | if "result" in answer_box.keys(): 21 | return answer_box["result"] 22 | elif "answer" in answer_box.keys(): 23 | return answer_box["answer"] 24 | elif "snippet" in answer_box.keys(): 25 | return answer_box["snippet"] 26 | elif "snippet_highlighted_words" in answer_box.keys(): 27 | return answer_box["snippet_highlighted_words"] 28 | else: 29 | answer = {} 30 | for key, value in answer_box.items(): 31 | if not isinstance(value, (list, dict)) and not ( 32 | isinstance(value, str) and value.startswith("http") 33 | ): 34 | answer[key] = value 35 | return str(answer) 36 | elif "events_results" in res.keys(): 37 | return res["events_results"][:10] 38 | elif "sports_results" in res.keys(): 39 | return res["sports_results"] 40 | elif "top_stories" in res.keys(): 41 | return res["top_stories"] 42 | elif "news_results" in res.keys(): 43 | return res["news_results"] 44 | elif "jobs_results" in res.keys() and "jobs" in res["jobs_results"].keys(): 45 | return res["jobs_results"]["jobs"] 46 | elif ( 47 | "shopping_results" in res.keys() 48 | and "title" in res["shopping_results"][0].keys() 49 | ): 50 | return res["shopping_results"][:3] 51 | elif "questions_and_answers" in res.keys(): 52 | return res["questions_and_answers"] 53 | elif ( 54 | "popular_destinations" in res.keys() 55 | and "destinations" in res["popular_destinations"].keys() 56 | ): 57 | return res["popular_destinations"]["destinations"] 58 | elif "top_sights" in res.keys() and "sights" in res["top_sights"].keys(): 59 | return res["top_sights"]["sights"] 60 | elif ( 61 | "images_results" in res.keys() 62 | and "thumbnail" in res["images_results"][0].keys() 63 | ): 64 | return str([item["thumbnail"] for item in res["images_results"][:10]]) 65 | 66 | snippets = [] 67 | if "knowledge_graph" in res.keys(): 68 | knowledge_graph = res["knowledge_graph"] 69 | title = knowledge_graph["title"] if "title" in knowledge_graph else "" 70 | if "description" in knowledge_graph.keys(): 71 | snippets.append(knowledge_graph["description"]) 72 | for key, value in knowledge_graph.items(): 73 | if ( 74 | isinstance(key, str) 75 | and isinstance(value, str) 76 | and key not in ["title", "description"] 77 | and not key.endswith("_stick") 78 | and not key.endswith("_link") 79 | and not value.startswith("http") 80 | ): 81 | snippets.append(f"{title} {key}: {value}.") 82 | if "organic_results" in res.keys(): 83 | first_organic_result = res["organic_results"][0] 84 | if "snippet" in first_organic_result.keys(): 85 | # snippets.append(first_organic_result["snippet"]) 86 | snippets.append(first_organic_result["link"]) 87 | elif "snippet_highlighted_words" in first_organic_result.keys(): 88 | snippets.append(first_organic_result["snippet_highlighted_words"]) 89 | elif "rich_snippet" in first_organic_result.keys(): 90 | snippets.append(first_organic_result["rich_snippet"]) 91 | elif "rich_snippet_table" in first_organic_result.keys(): 92 | snippets.append(first_organic_result["rich_snippet_table"]) 93 | elif "link" in first_organic_result.keys(): 94 | snippets.append(first_organic_result["link"]) 95 | if "buying_guide" in res.keys(): 96 | snippets.append(res["buying_guide"]) 97 | if "local_results" in res.keys() and "places" in res["local_results"].keys(): 98 | snippets.append(res["local_results"]["places"]) 99 | 100 | if len(snippets) > 0: 101 | return str(snippets) 102 | else: 103 | return "No good search result found" 104 | 105 | # 获取与某种鲜花相关的微博UID的函数 106 | def get_UID(flower: str): 107 | # search = SerpAPIWrapper() 108 | search = CustomSerpAPIWrapper() 109 | res = search.run(f"{flower}") 110 | return res -------------------------------------------------------------------------------- /21_人脉工具下/socializer_v5/tools/textgen_tool.py: -------------------------------------------------------------------------------- 1 | # 导入所需要的库 2 | from langchain.prompts import PromptTemplate 3 | from langchain.chat_models import ChatOpenAI 4 | from langchain.chains import LLMChain 5 | from tools.parsing_tool import letter_parser 6 | 7 | 8 | # 生成文案的函数 9 | def generate_letter(information): 10 | 11 | # 设计提示模板 12 | letter_template = """ 13 | 下面是这个人的微博信息 {information} 14 | 请你帮我: 15 | 1. 写一个简单的总结 16 | 2. 挑两件有趣的特点说一说 17 | 3. 找一些他比较感兴趣的事情 18 | 4. 写一篇热情洋溢的介绍信 19 | \n{format_instructions}""" 20 | 21 | prompt_template = PromptTemplate( 22 | input_variables=["information"], 23 | template=letter_template, 24 | partial_variables={ 25 | "format_instructions": letter_parser.get_format_instructions() 26 | }, 27 | ) 28 | 29 | # 初始化大模型 30 | llm = ChatOpenAI(model_name="gpt-3.5-turbo") 31 | 32 | # 初始化链 33 | chain = LLMChain(llm=llm, prompt=prompt_template) 34 | 35 | # 生成文案 36 | result = chain.run(information = information) 37 | return result -------------------------------------------------------------------------------- /22_Chatbot上/Chatbot_v1.0.py: -------------------------------------------------------------------------------- 1 | # 设置OpenAI API密钥 2 | import os 3 | os.environ["OPENAI_API_KEY"] = 'Your Key' 4 | 5 | # 导入所需的库和模块 6 | from langchain.schema import ( 7 | HumanMessage, 8 | SystemMessage 9 | ) 10 | from langchain.chat_models import ChatOpenAI 11 | 12 | # 创建一个聊天模型的实例 13 | chat = ChatOpenAI() 14 | 15 | # 创建一个消息列表 16 | messages = [ 17 | SystemMessage(content="你是一个花卉行家。"), 18 | HumanMessage(content="朋友喜欢淡雅的颜色,她的婚礼我选择什么花?") 19 | ] 20 | 21 | # 使用聊天模型获取响应 22 | response = chat(messages) 23 | print(response) 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /22_Chatbot上/Chatbot_v1.1.py: -------------------------------------------------------------------------------- 1 | # 设置OpenAI API密钥 2 | import os 3 | os.environ["OPENAI_API_KEY"] = 'Your Key' 4 | 5 | # 导入所需的库和模块 6 | from langchain.schema import HumanMessage, SystemMessage 7 | from langchain.chat_models import ChatOpenAI 8 | 9 | # 定义一个命令行聊天机器人的类 10 | class CommandlineChatbot: 11 | # 在初始化时,设置花卉行家的角色并初始化聊天模型 12 | def __init__(self): 13 | self.chat = ChatOpenAI() 14 | self.messages = [SystemMessage(content="你是一个花卉行家。")] 15 | 16 | # 定义一个循环来持续与用户交互 17 | def chat_loop(self): 18 | print("Chatbot 已启动! 输入'exit'来退出程序。") 19 | while True: 20 | user_input = input("你: ") 21 | # 如果用户输入“exit”,则退出循环 22 | if user_input.lower() == 'exit': 23 | print("再见!") 24 | break 25 | # 将用户的输入添加到消息列表中,并获取机器人的响应 26 | self.messages.append(HumanMessage(content=user_input)) 27 | response = self.chat(self.messages) 28 | print(f"Chatbot: {response.content}") 29 | 30 | # 如果直接运行这个脚本,启动聊天机器人 31 | if __name__ == "__main__": 32 | bot = CommandlineChatbot() 33 | bot.chat_loop() -------------------------------------------------------------------------------- /22_Chatbot上/Chatbot_v2.0.py: -------------------------------------------------------------------------------- 1 | # 设置OpenAI API密钥 2 | import os 3 | os.environ["OPENAI_API_KEY"] = 'Your Key' 4 | 5 | # 导入所需的库和模块 6 | from langchain.schema import HumanMessage, SystemMessage 7 | from langchain.memory import ConversationBufferMemory 8 | from langchain.prompts import ( 9 | ChatPromptTemplate, 10 | MessagesPlaceholder, 11 | SystemMessagePromptTemplate, 12 | HumanMessagePromptTemplate, 13 | ) 14 | from langchain.chains import LLMChain 15 | from langchain.chat_models import ChatOpenAI 16 | 17 | # 设置OpenAI API密钥 18 | os.environ["OPENAI_API_KEY"] = 'Your Key' 19 | 20 | # 带记忆的聊天机器人类 21 | class ChatbotWithMemory: 22 | def __init__(self): 23 | 24 | # 初始化LLM 25 | self.llm = ChatOpenAI() 26 | 27 | # 初始化Prompt 28 | self.prompt = ChatPromptTemplate( 29 | messages=[ 30 | SystemMessagePromptTemplate.from_template( 31 | "你是一个花卉行家。你通常的回答不超过30字。" 32 | ), 33 | MessagesPlaceholder(variable_name="chat_history"), 34 | HumanMessagePromptTemplate.from_template("{question}") 35 | ] 36 | ) 37 | 38 | # 初始化Memory 39 | self.memory = ConversationBufferMemory(memory_key="chat_history", return_messages=True) 40 | 41 | # 初始化LLMChain with LLM, prompt and memory 42 | self.conversation = LLMChain( 43 | llm=self.llm, 44 | prompt=self.prompt, 45 | verbose=True, 46 | memory=self.memory 47 | ) 48 | 49 | # 与机器人交互的函数 50 | def chat_loop(self): 51 | print("Chatbot 已启动! 输入'exit'来退出程序。") 52 | while True: 53 | user_input = input("你: ") 54 | if user_input.lower() == 'exit': 55 | print("再见!") 56 | break 57 | 58 | response = self.conversation({"question": user_input}) 59 | print(f"Chatbot: {response['text']}") 60 | 61 | if __name__ == "__main__": 62 | # 启动Chatbot 63 | bot = ChatbotWithMemory() 64 | bot.chat_loop() 65 | -------------------------------------------------------------------------------- /22_Chatbot上/Chatbot_v3.0.py: -------------------------------------------------------------------------------- 1 | # 导入所需的库 2 | import os 3 | from langchain.text_splitter import RecursiveCharacterTextSplitter 4 | from langchain.embeddings import OpenAIEmbeddings 5 | from langchain.vectorstores import Qdrant 6 | from langchain.memory import ConversationSummaryMemory 7 | from langchain.chat_models import ChatOpenAI 8 | from langchain.chains import ConversationalRetrievalChain 9 | from langchain.document_loaders import PyPDFLoader 10 | from langchain.document_loaders import Docx2txtLoader 11 | from langchain.document_loaders import TextLoader 12 | 13 | # 设置OpenAI API密钥 14 | os.environ["OPENAI_API_KEY"] = 'Your Key' 15 | 16 | # ChatBot类的实现-带检索功能 17 | class ChatbotWithRetrieval: 18 | 19 | def __init__(self, dir): 20 | 21 | # 加载Documents 22 | base_dir = dir # 文档的存放目录 23 | documents = [] 24 | for file in os.listdir(base_dir): 25 | file_path = os.path.join(base_dir, file) 26 | if file.endswith('.pdf'): 27 | loader = PyPDFLoader(file_path) 28 | documents.extend(loader.load()) 29 | elif file.endswith('.docx') or file.endswith('.doc'): 30 | loader = Docx2txtLoader(file_path) 31 | documents.extend(loader.load()) 32 | elif file.endswith('.txt'): 33 | loader = TextLoader(file_path) 34 | documents.extend(loader.load()) 35 | 36 | # 文本的分割 37 | text_splitter = RecursiveCharacterTextSplitter(chunk_size=200, chunk_overlap=0) 38 | all_splits = text_splitter.split_documents(documents) 39 | 40 | # 向量数据库 41 | self.vectorstore = Qdrant.from_documents( 42 | documents=all_splits, # 以分块的文档 43 | embedding=OpenAIEmbeddings(), # 用OpenAI的Embedding Model做嵌入 44 | location=":memory:", # in-memory 存储 45 | collection_name="my_documents",) # 指定collection_name 46 | 47 | # 初始化LLM 48 | self.llm = ChatOpenAI() 49 | 50 | # 初始化Memory 51 | self.memory = ConversationSummaryMemory( 52 | llm=self.llm, 53 | memory_key="chat_history", 54 | return_messages=True 55 | ) 56 | 57 | # 设置Retrieval Chain 58 | retriever = self.vectorstore.as_retriever() 59 | self.qa = ConversationalRetrievalChain.from_llm( 60 | self.llm, 61 | retriever=retriever, 62 | memory=self.memory 63 | ) 64 | 65 | # 交互对话的函数 66 | def chat_loop(self): 67 | print("Chatbot 已启动! 输入'exit'来退出程序。") 68 | while True: 69 | user_input = input("你: ") 70 | if user_input.lower() == 'exit': 71 | print("再见!") 72 | break 73 | # 调用 Retrieval Chain 74 | response = self.qa(user_input) 75 | print(f"Chatbot: {response['answer']}") 76 | 77 | if __name__ == "__main__": 78 | # 启动Chatbot 79 | folder = "OneFlower" 80 | bot = ChatbotWithRetrieval(folder) 81 | bot.chat_loop() 82 | -------------------------------------------------------------------------------- /23_Chatbot下/Chatbot_v4.0.py: -------------------------------------------------------------------------------- 1 | # 导入所需的库 2 | import os 3 | import streamlit as st 4 | from langchain.text_splitter import RecursiveCharacterTextSplitter 5 | from langchain.embeddings import OpenAIEmbeddings 6 | from langchain.vectorstores import Qdrant 7 | from langchain.memory import ConversationSummaryMemory 8 | from langchain.chat_models import ChatOpenAI 9 | from langchain.chains import ConversationalRetrievalChain 10 | from langchain.document_loaders import PyPDFLoader 11 | from langchain.document_loaders import Docx2txtLoader 12 | from langchain.document_loaders import TextLoader 13 | 14 | # 设置OpenAI API密钥 15 | os.environ["OPENAI_API_KEY"] = 'Your Key' 16 | 17 | # ChatBot类的实现 18 | class ChatbotWithRetrieval: 19 | 20 | def __init__(self, dir): 21 | 22 | # 加载Documents 23 | base_dir = dir # 文档的存放目录 24 | documents = [] 25 | for file in os.listdir(base_dir): 26 | file_path = os.path.join(base_dir, file) 27 | if file.endswith('.pdf'): 28 | loader = PyPDFLoader(file_path) 29 | documents.extend(loader.load()) 30 | elif file.endswith('.docx') or file.endswith('.doc'): 31 | loader = Docx2txtLoader(file_path) 32 | documents.extend(loader.load()) 33 | elif file.endswith('.txt'): 34 | loader = TextLoader(file_path) 35 | documents.extend(loader.load()) 36 | 37 | # 文本的分割 38 | text_splitter = RecursiveCharacterTextSplitter(chunk_size=200, chunk_overlap=0) 39 | all_splits = text_splitter.split_documents(documents) 40 | 41 | # 向量数据库 42 | self.vectorstore = Qdrant.from_documents( 43 | documents=all_splits, # 以分块的文档 44 | embedding=OpenAIEmbeddings(), # 用OpenAI的Embedding Model做嵌入 45 | location=":memory:", # in-memory 存储 46 | collection_name="my_documents",) # 指定collection_name 47 | 48 | # 初始化LLM 49 | self.llm = ChatOpenAI() 50 | 51 | # 初始化Memory 52 | self.memory = ConversationSummaryMemory( 53 | llm=self.llm, 54 | memory_key="chat_history", 55 | return_messages=True 56 | ) 57 | 58 | # 设置Retrieval Chain 59 | retriever = self.vectorstore.as_retriever() 60 | self.qa = ConversationalRetrievalChain.from_llm( 61 | self.llm, 62 | retriever=retriever, 63 | memory=self.memory 64 | ) 65 | 66 | def chat_loop(self): 67 | print("Chatbot 已启动! 输入'exit'来退出程序。") 68 | while True: 69 | user_input = input("你: ") 70 | if user_input.lower() == 'exit': 71 | print("再见!") 72 | break 73 | # 调用 Retrieval Chain 74 | response = self.qa(user_input) 75 | print(f"Chatbot: {response['answer']}") 76 | 77 | # Streamlit界面的创建 78 | def main(): 79 | st.title("易速鲜花聊天客服") 80 | 81 | # Check if the 'bot' attribute exists in the session state 82 | if "bot" not in st.session_state: 83 | st.session_state.bot = ChatbotWithRetrieval("OneFlower") 84 | 85 | user_input = st.text_input("请输入你的问题:") 86 | 87 | if user_input: 88 | response = st.session_state.bot.qa(user_input) 89 | st.write(f"Chatbot: {response['answer']}") 90 | 91 | if __name__ == "__main__": 92 | main() 93 | 94 | -------------------------------------------------------------------------------- /23_Chatbot下/Chatbot_v5.2.py: -------------------------------------------------------------------------------- 1 | # 导入所需的库 2 | import os 3 | import gradio as gr 4 | from langchain.text_splitter import RecursiveCharacterTextSplitter 5 | from langchain.embeddings import OpenAIEmbeddings 6 | from langchain.vectorstores import Qdrant 7 | from langchain.memory import ConversationSummaryMemory 8 | from langchain.chat_models import ChatOpenAI 9 | from langchain.chains import ConversationalRetrievalChain 10 | from langchain.document_loaders import PyPDFLoader 11 | from langchain.document_loaders import Docx2txtLoader 12 | from langchain.document_loaders import TextLoader 13 | 14 | # 设置OpenAI API密钥 15 | os.environ["OPENAI_API_KEY"] = 'Your Key' 16 | 17 | class ChatbotWithRetrieval: 18 | def __init__(self, dir): 19 | 20 | # 加载Documents 21 | base_dir = dir # 文档的存放目录 22 | documents = [] 23 | for file in os.listdir(base_dir): 24 | file_path = os.path.join(base_dir, file) 25 | if file.endswith('.pdf'): 26 | loader = PyPDFLoader(file_path) 27 | documents.extend(loader.load()) 28 | elif file.endswith('.docx') or file.endswith('.doc'): 29 | loader = Docx2txtLoader(file_path) 30 | documents.extend(loader.load()) 31 | elif file.endswith('.txt'): 32 | loader = TextLoader(file_path) 33 | documents.extend(loader.load()) 34 | 35 | # 文本的分割 36 | text_splitter = RecursiveCharacterTextSplitter(chunk_size=200, chunk_overlap=0) 37 | all_splits = text_splitter.split_documents(documents) 38 | 39 | # 向量数据库 40 | self.vectorstore = Qdrant.from_documents( 41 | documents=all_splits, # 以分块的文档 42 | embedding=OpenAIEmbeddings(), # 用OpenAI的Embedding Model做嵌入 43 | location=":memory:", # in-memory 存储 44 | collection_name="my_documents",) # 指定collection_name 45 | 46 | # 初始化LLM 47 | self.llm = ChatOpenAI() 48 | 49 | # 初始化Memory 50 | self.memory = ConversationSummaryMemory( 51 | llm=self.llm, 52 | memory_key="chat_history", 53 | return_messages=True 54 | ) 55 | # 初始化对话历史 56 | self.conversation_history = "" 57 | 58 | # 设置Retrieval Chain 59 | retriever = self.vectorstore.as_retriever() 60 | self.qa = ConversationalRetrievalChain.from_llm( 61 | self.llm, 62 | retriever=retriever, 63 | memory=self.memory 64 | ) 65 | 66 | def get_response(self, user_input): # 这是为 Gradio 创建的新函数 67 | response = self.qa(user_input) 68 | # 更新对话历史 69 | self.conversation_history += f"你: {user_input}\nChatbot: {response['answer']}\n" 70 | return self.conversation_history 71 | 72 | if __name__ == "__main__": 73 | folder = "OneFlower" 74 | bot = ChatbotWithRetrieval(folder) 75 | 76 | # 定义 Gradio 界面 77 | interface = gr.Interface( 78 | fn=bot.get_response, # 使用我们刚刚创建的函数 79 | inputs="text", # 输入是文本 80 | outputs="text", # 输出也是文本 81 | live=False, # 实时更新,这样用户可以连续与模型交互 82 | title="易速鲜花智能客服", # 界面标题 83 | description="请输入问题,然后点击提交。" # 描述 84 | ) 85 | interface.launch() # 启动 Gradio 界面 -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LangChain实战课 2 | 3 | 4 | 喜欢这个Repo,就要[到这里](https://time.geekbang.org/column/intro/100617601)购买此课,支持佳哥 5 | 6 | 还有,佳哥的新书GPT图解,重磅问世。当然你也要支持一下。[此处](https://u.jd.com/EzPlXWB)购买5折。 7 | 8 | ![Alt text](img/book.png) 9 | 10 | https://time.geekbang.org/column/intro/100617601 11 | ![image](https://github.com/huangjia2019/langchain/assets/48795276/03c72bf0-918c-4428-8b8c-b77152cac985) 12 | ![image](https://github.com/huangjia2019/langchain/assets/48795276/791eecc3-f8fb-4e8f-b22a-6d626492b987) 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /img/book.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huangjia2019/langchain-in-action/6a899d656b6afa4497c53c7a535e83d98a3b63ad/img/book.png -------------------------------------------------------------------------------- /requirements_v0.1.txt: -------------------------------------------------------------------------------- 1 | aiofiles==23.2.1 2 | aiohttp==3.8.5 3 | aiosignal==1.3.1 4 | altair==5.1.2 5 | anyio==3.7.1 6 | argon2-cffi==23.1.0 7 | argon2-cffi-bindings==21.2.0 8 | arrow==1.2.3 9 | asttokens==2.4.0 10 | async-lru==2.0.4 11 | async-timeout==4.0.3 12 | attrs==23.1.0 13 | Babel==2.12.1 14 | backcall==0.2.0 15 | backoff==2.2.1 16 | beautifulsoup4==4.12.2 17 | bleach==6.0.0 18 | blinker==1.6.2 19 | blis==0.7.10 20 | cachetools==5.3.1 21 | catalogue==2.0.9 22 | certifi==2023.7.22 23 | cffi==1.15.1 24 | chardet==5.2.0 25 | charset-normalizer==3.2.0 26 | click==8.1.7 27 | colorama==0.4.6 28 | comm==0.1.4 29 | confection==0.1.2 30 | contourpy==1.1.0 31 | cryptography==41.0.3 32 | cycler==0.11.0 33 | cymem==2.0.7 34 | dataclasses-json==0.5.14 35 | debugpy==1.8.0 36 | decorator==5.1.1 37 | defusedxml==0.7.1 38 | Deprecated==1.2.14 39 | dill==0.3.7 40 | distro==1.8.0 41 | docx2txt==0.8 42 | elastic-transport==8.4.0 43 | elasticsearch==8.9.0 44 | emoji==2.8.0 45 | executing==1.2.0 46 | faiss-cpu==1.7.4 47 | fastapi==0.103.2 48 | fastjsonschema==2.18.0 49 | ffmpy==0.3.1 50 | filelock==3.12.3 51 | filetype==1.2.0 52 | Flask==2.3.3 53 | fonttools==4.42.1 54 | fqdn==1.5.1 55 | frozenlist==1.4.0 56 | fsspec==2023.9.0 57 | gitdb==4.0.10 58 | GitPython==3.1.37 59 | google-api-core==2.11.1 60 | google-api-python-client==2.98.0 61 | google-auth==2.23.0 62 | google-auth-httplib2==0.1.1 63 | google-auth-oauthlib==1.1.0 64 | google-search-results==2.4.2 65 | googleapis-common-protos==1.60.0 66 | gradio==3.47.1 67 | gradio_client==0.6.0 68 | greenlet==2.0.2 69 | grpcio==1.58.0 70 | grpcio-tools==1.58.0 71 | h11==0.14.0 72 | h2==4.1.0 73 | hpack==4.0.0 74 | httpcore==0.17.3 75 | httplib2==0.22.0 76 | httpx==0.24.1 77 | huggingface-hub==0.16.4 78 | hyperframe==6.0.1 79 | idna==3.4 80 | importlib-metadata==6.8.0 81 | importlib-resources==6.1.0 82 | ipykernel==6.25.2 83 | ipython==8.15.0 84 | ipython-genutils==0.2.0 85 | ipywidgets==8.1.1 86 | isoduration==20.11.0 87 | itsdangerous==2.1.2 88 | jedi==0.19.0 89 | Jinja2==3.1.2 90 | joblib==1.3.2 91 | json5==0.9.14 92 | jsonpatch==1.33 93 | jsonpointer==2.4 94 | jsonschema==4.19.0 95 | jsonschema-specifications==2023.7.1 96 | jupyter==1.0.0 97 | jupyter-console==6.6.3 98 | jupyter-events==0.7.0 99 | jupyter-lsp==2.2.0 100 | jupyter_client==8.3.1 101 | jupyter_core==5.3.1 102 | jupyter_server==2.7.3 103 | jupyter_server_terminals==0.4.4 104 | jupyterlab==4.0.5 105 | jupyterlab-pygments==0.2.2 106 | jupyterlab-widgets==3.0.9 107 | jupyterlab_server==2.25.0 108 | kiwisolver==1.4.5 109 | langchain==0.1.0 110 | langchain-community==0.0.9 111 | langchain-core==0.1.7 112 | langchain-experimental==0.0.23 113 | langchain-openai==0.0.2 114 | langchainhub==0.1.14 115 | langcodes==3.3.0 116 | langdetect==1.0.9 117 | langsmith==0.0.77 118 | lxml==4.9.3 119 | manifest-ml==0.0.1 120 | markdown-it-py==3.0.0 121 | MarkupSafe==2.1.3 122 | marshmallow==3.20.1 123 | matplotlib==3.7.3 124 | matplotlib-inline==0.1.6 125 | mdurl==0.1.2 126 | mistune==3.0.1 127 | mpmath==1.3.0 128 | multidict==6.0.4 129 | murmurhash==1.0.9 130 | mypy-extensions==1.0.0 131 | nbclient==0.8.0 132 | nbconvert==7.8.0 133 | nbformat==5.9.2 134 | nest-asyncio==1.5.7 135 | networkx==3.1 136 | nltk==3.8.1 137 | notebook==7.0.3 138 | notebook_shim==0.2.3 139 | numexpr==2.8.5 140 | numpy==1.25.2 141 | oauthlib==3.2.2 142 | openai==1.6.1 143 | orjson==3.9.8 144 | outcome==1.2.0 145 | overrides==7.4.0 146 | packaging==23.2 147 | pandas==2.1.0 148 | pandocfilters==1.5.0 149 | parso==0.8.3 150 | pathy==0.10.2 151 | pickleshare==0.7.5 152 | Pillow==10.0.0 153 | platformdirs==3.10.0 154 | playwright==1.38.0 155 | portalocker==2.7.0 156 | preshed==3.0.8 157 | prometheus-client==0.17.1 158 | prompt-toolkit==3.0.39 159 | protobuf==4.24.3 160 | psutil==5.9.5 161 | pure-eval==0.2.2 162 | pyarrow==13.0.0 163 | pyasn1==0.5.0 164 | pyasn1-modules==0.3.0 165 | pycparser==2.21 166 | pydantic==1.10.12 167 | pydeck==0.8.1b0 168 | pydub==0.25.1 169 | pyee==9.0.4 170 | PyGithub==1.59.1 171 | Pygments==2.16.1 172 | PyJWT==2.8.0 173 | PyNaCl==1.5.0 174 | pyparsing==3.1.1 175 | pypdf==3.15.5 176 | PySocks==1.7.1 177 | python-dateutil==2.8.2 178 | python-dotenv==1.0.0 179 | python-iso639==2023.6.15 180 | python-json-logger==2.0.7 181 | python-magic==0.4.27 182 | python-multipart==0.0.6 183 | pytz==2023.3.post1 184 | pywin32==306 185 | pywinpty==2.0.11 186 | PyYAML==6.0.1 187 | pyzmq==25.1.1 188 | qdrant-client==1.7.0 189 | qtconsole==5.4.4 190 | QtPy==2.4.0 191 | rapidfuzz==3.4.0 192 | redis==5.0.0 193 | referencing==0.30.2 194 | regex==2023.8.8 195 | requests==2.31.0 196 | requests-oauthlib==1.3.1 197 | rfc3339-validator==0.1.4 198 | rfc3986-validator==0.1.1 199 | rich==13.6.0 200 | rpds-py==0.10.3 201 | rsa==4.9 202 | safetensors==0.3.3 203 | scikit-learn==1.3.0 204 | scipy==1.11.2 205 | selenium==4.13.0 206 | semantic-version==2.10.0 207 | Send2Trash==1.8.2 208 | six==1.16.0 209 | smart-open==6.4.0 210 | smmap==5.0.1 211 | sniffio==1.3.0 212 | sortedcontainers==2.4.0 213 | soupsieve==2.5 214 | spacy==3.6.1 215 | spacy-legacy==3.0.12 216 | spacy-loggers==1.0.4 217 | SQLAlchemy==1.4.49 218 | sqlitedict==2.1.0 219 | srsly==2.4.7 220 | stack-data==0.6.2 221 | starlette==0.27.0 222 | streamlit==1.27.2 223 | sympy==1.12 224 | tabulate==0.9.0 225 | tenacity==8.2.3 226 | terminado==0.17.1 227 | thinc==8.1.12 228 | threadpoolctl==3.2.0 229 | tiktoken==0.5.2 230 | tinycss2==1.2.1 231 | tokenizers==0.13.3 232 | toml==0.10.2 233 | toolz==0.12.0 234 | torch==2.0.1 235 | torchaudio==2.0.2 236 | torchvision==0.15.2 237 | tornado==6.3.3 238 | tqdm==4.66.1 239 | traitlets==5.9.0 240 | transformers==4.33.1 241 | trio==0.22.2 242 | trio-websocket==0.11.1 243 | typer==0.9.0 244 | types-requests==2.31.0.20240106 245 | typing-inspect==0.9.0 246 | typing_extensions==4.7.1 247 | tzdata==2023.3 248 | tzlocal==5.1 249 | unstructured==0.10.22 250 | uri-template==1.3.0 251 | uritemplate==4.1.1 252 | urllib3==1.26.18 253 | uvicorn==0.23.2 254 | validators==0.22.0 255 | wasabi==1.1.2 256 | watchdog==3.0.0 257 | wcwidth==0.2.6 258 | webcolors==1.13 259 | webencodings==0.5.1 260 | websocket-client==1.6.3 261 | websockets==11.0.3 262 | Werkzeug==2.3.7 263 | widgetsnbextension==4.0.9 264 | wikipedia==1.4.0 265 | wrapt==1.15.0 266 | wsproto==1.2.0 267 | yarl==1.9.2 268 | zipp==3.17.0 269 | -------------------------------------------------------------------------------- /requirements_v0.2.txt: -------------------------------------------------------------------------------- 1 | aiohttp==3.9.5 2 | aiosignal==1.3.1 3 | annotated-types==0.7.0 4 | anyio==4.4.0 5 | attrs==23.2.0 6 | blinker==1.8.2 7 | certifi==2024.6.2 8 | charset-normalizer==3.3.2 9 | click==8.1.7 10 | colorama==0.4.6 11 | dataclasses-json==0.6.6 12 | distro==1.9.0 13 | docx2txt==0.8 14 | fastapi==0.110.3 15 | filelock==3.14.0 16 | Flask==3.0.3 17 | frozenlist==1.4.1 18 | fsspec==2024.6.0 19 | gitdb==4.0.11 20 | GitPython==3.1.43 21 | greenlet==3.0.3 22 | grpcio==1.64.1 23 | grpcio-tools==1.64.1 24 | h11==0.14.0 25 | h2==4.1.0 26 | hpack==4.0.0 27 | httpcore==1.0.5 28 | httpx==0.27.0 29 | huggingface-hub==0.23.3 30 | hyperframe==6.0.1 31 | idna==3.7 32 | itsdangerous==2.2.0 33 | Jinja2==3.1.4 34 | jsonpatch==1.33 35 | jsonpointer==2.4 36 | jsonschema==4.22.0 37 | jsonschema-specifications==2023.12.1 38 | langchain==0.2.2 39 | langchain-cli==0.0.24 40 | langchain-community==0.2.3 41 | langchain-core==0.2.4 42 | langchain-experimental==0.0.60 43 | langchain-openai==0.1.8 44 | langchain-text-splitters==0.2.1 45 | langserve==0.2.1 46 | langsmith==0.1.73 47 | libcst==1.4.0 48 | markdown-it-py==3.0.0 49 | MarkupSafe==2.1.5 50 | marshmallow==3.21.2 51 | mdurl==0.1.2 52 | multidict==6.0.5 53 | mypy-extensions==1.0.0 54 | numpy==1.26.4 55 | openai==1.31.1 56 | orjson==3.10.3 57 | packaging==23.2 58 | pillow==10.3.0 59 | portalocker==2.8.2 60 | protobuf==5.27.0 61 | pydantic==2.7.3 62 | pydantic_core==2.18.4 63 | Pygments==2.18.0 64 | pypdf==4.2.0 65 | pyproject-toml==0.0.10 66 | python-dotenv==1.0.1 67 | pywin32==306 68 | PyYAML==6.0.1 69 | qdrant-client==1.9.1 70 | referencing==0.35.1 71 | regex==2024.5.15 72 | requests==2.32.3 73 | rich==13.7.1 74 | rpds-py==0.18.1 75 | safetensors==0.4.3 76 | setuptools==70.0.0 77 | shellingham==1.5.4 78 | smmap==5.0.1 79 | sniffio==1.3.1 80 | SQLAlchemy==2.0.30 81 | sse-starlette==1.8.2 82 | starlette==0.37.2 83 | tenacity==8.3.0 84 | tiktoken==0.7.0 85 | tokenizers==0.19.1 86 | toml==0.10.2 87 | tomlkit==0.12.5 88 | tqdm==4.66.4 89 | transformers==4.41.2 90 | typer==0.9.4 91 | typing-inspect==0.9.0 92 | typing_extensions==4.12.1 93 | urllib3==2.2.1 94 | uvicorn==0.23.2 95 | Werkzeug==3.0.3 96 | wheel==0.43.0 97 | yarl==1.9.4 98 | --------------------------------------------------------------------------------