├── 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 |
7 |
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 |
13 |
14 |
15 |
16 |
17 |
18 |
易速鲜花人脉工具
19 |
23 |
24 |
![Profile Picture]()
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 | 
9 |
10 | https://time.geekbang.org/column/intro/100617601
11 | 
12 | 
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 |
--------------------------------------------------------------------------------