使用LangChain、GPT和Activeloop的Deep Lake来处理代码库
在本教程中,我们将使用Langchain + Activeloop的Deep Lake和GPT来分析LangChain本身的代码库。
设计
准备数据:
- 使用
langchain.document_loaders.TextLoader
上传所有Python项目文件。我们将这些文件称为文档(documents)。 - 使用
langchain.text_splitter.CharacterTextSplitter
将所有文档拆分为块。 - 使用
langchain.embeddings.openai.OpenAIEmbeddings
和langchain.vectorstores.DeepLake
将块嵌入并上传到DeepLake中。
- 使用
问答:
- 从
langchain.chat_models.ChatOpenAI
和langchain.chains.ConversationalRetrievalChain
构建一个链。 - 准备问题。
- 运行链获取答案。
- 从
实现
集成准备工作
我们需要为外部服务设置密钥并安装必要的Python库。
#!python3 -m pip install --upgrade langchain deeplake openai
设置OpenAI嵌入、Deep Lake多模态向量存储API并进行身份验证。
有关Deep Lake的完整文档,请参阅https://docs.activeloop.ai/和API参考https://docs.deeplake.ai/en/latest/。
import os
from getpass import getpass
os.environ["OPENAI_API_KEY"] = getpass()
# 请手动输入OpenAI密钥
如果您想创建自己的数据集并发布它,请进行Deep Lake身份验证。您可以从平台app.activeloop.ai获取API密钥。
activeloop_token = getpass("Activeloop Token:")
os.environ["ACTIVELOOP_TOKEN"] = activeloop_token
准备数据
加载所有存储库文件。在这里,我们假设这个笔记本是作为langchain分支的一部分下载的,并且我们使用langchain
存储库的python文件。
如果您想使用来自不同存储库的文件,请将root_dir
更改为您的存储库的根目录。
ls "../../../.."
from langchain.document_loaders import TextLoader
root_dir = "../../../.."
docs = []
for dirpath, dirnames, filenames in os.walk(root_dir):
for file in filenames:
if file.endswith(".py") and "/.venv/" not in dirpath:
try:
loader = TextLoader(os.path.join(dirpath, file), encoding="utf-8")
docs.extend(loader.load_and_split())
except Exception as e:
pass
print(f"{len(docs)}")
API 参考:
- TextLoader 来自
langchain.document_loaders
然后,对文件进行分块
from langchain.text_splitter import CharacterTextSplitter
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
texts = text_splitter.split_documents(docs)
print(f"{len(texts)}")
API 参考:
- CharacterTextSplitter 来自
langchain.text_splitter
然后嵌入分块并将它们上传到DeepLake。
这可能需要几分钟时间。
from langchain.embeddings.openai import OpenAIEmbeddings
embeddings = OpenAIEmbeddings()
embeddings
API 参考:
- OpenAIEmbeddings 来自
langchain.embeddings.openai
from langchain.vectorstores import DeepLake
db = DeepLake.from_documents(
texts, embeddings, dataset_path=f"hub://{<org_id>}/langchain-code"
)
db
API 参考:
- DeepLake 来自
langchain.vectorstores
可选
: 您还可以使用Deep Lake的托管张量数据库作为托管服务并在其中运行查询。为此,在创建向量存储时,需要将运行时参数指定为{'tensor_db': True}。此配置使得可以在托管张量数据库上执行查询,而不是在客户端上执行。需要注意的是,此功能不适用于本地或内存中存储的数据集。如果已经在托管张量数据库之外创建了向量存储,则可以按照规定的步骤将其转移到托管张量数据库中。
# from langchain.vectorstores import DeepLake
# db = DeepLake.from_documents(
# texts, embeddings, dataset_path=f"hub://{<org_id>}/langchain-code", runtime={"tensor_db": True}
# )
# db
API 参考:
- DeepLake 来自
langchain.vectorstores
问答
首先加载数据集,构建检索器,然后构建对话链
db = DeepLake(
dataset_path=f"hub://{<org_id>}/langchain-code",
read_only=True,
embedding_function=embeddings,
)
retriever = db.as_retriever()
retriever.search_kwargs["distance_metric"] = "cos"
retriever.search_kwargs["fetch_k"] = 20
retriever.search_kwargs["maximal_marginal_relevance"] = True
retriever.search_kwargs["k"] = 20
您还可以使用Deep Lake filters指定用户定义的函数
def filter(x):
# 基于源代码进行过滤
if "something" in x["text"].data()["value"]:
return False
# 基于路径进行过滤,例如扩展名
metadata = x["metadata"].data()["value"]
return "only_this" in metadata["source"] or "also_that" in metadata["source"]
### 打开以下内容以进行自定义过滤
# retriever.search_kwargs['filter'] = filter
from langchain.chat_models import ChatOpenAI
from langchain.chains import ConversationalRetrievalChain
model = ChatOpenAI(model_name="gpt-3.5-turbo") # 'ada' 'gpt-3.5-turbo' 'gpt-4',
qa = ConversationalRetrievalChain.from_llm(model, retriever=retriever)
API 参考:
- ChatOpenAI 来自
langchain.chat_models
- ConversationalRetrievalChain 来自
langchain.chains
questions = [
"类的层次结构是什么?",
# "从 Chain 类派生了哪些类?",
# "在 ./langchain/utilities/ 文件夹中有哪些类和函数没有被单元测试覆盖?",
# "关于 Chain 类的类层次结构,您提出了哪个改进建议?",
]
chat_history = []
for question in questions:
result = qa({"question": question, "chat_history": chat_history})
chat_history.append((question, result["answer"]))
print(f"-> **问题**:{question} \n")
print(f"**回答**:{result['answer']} \n")
-> 问题:类的层次结构是什么?
回答:提供的代码中有几个类层次结构,我将列举一些:
BaseModel
->ConstitutionalPrinciple
:ConstitutionalPrinciple
是BaseModel
的子类。BasePromptTemplate
->StringPromptTemplate
、AIMessagePromptTemplate
、BaseChatPromptTemplate
、ChatMessagePromptTemplate
、ChatPromptTemplate
、HumanMessagePromptTemplate
、MessagesPlaceholder
、SystemMessagePromptTemplate
、FewShotPromptTemplate
、FewShotPromptWithTemplates
、Prompt
、PromptTemplate
:所有这些类都是BasePromptTemplate
的子类。APIChain
、Chain
、MapReduceDocumentsChain
、MapRerankDocumentsChain
、RefineDocumentsChain
、StuffDocumentsChain
、HypotheticalDocumentEmbedder
、LLMChain
、LLMBashChain
、LLMCheckerChain
、LLMMathChain
、LLMRequestsChain
、PALChain
、QAWithSourcesChain
、VectorDBQAWithSourcesChain
、VectorDBQA
、SQLDatabaseChain
:所有这些类都是Chain
的子类。BaseLoader
:BaseLoader
是ABC
的子类。BaseTracer
->ChainRun
、LLMRun
、SharedTracer
、ToolRun
、Tracer
、TracerException
、TracerSession
:所有这些类都是BaseTracer
的子类。OpenAIEmbeddings
、HuggingFaceEmbeddings
、CohereEmbeddings
、JinaEmbeddings
、LlamaCppEmbeddings
、HuggingFaceHubEmbeddings
、TensorflowHubEmbeddings
、SagemakerEndpointEmbeddings
、HuggingFaceInstructEmbeddings
、SelfHostedEmbeddings
、SelfHostedHuggingFaceEmbeddings
、SelfHostedHuggingFaceInstructEmbeddings
、FakeEmbeddings
、AlephAlphaAsymmetricSemanticEmbedding
、AlephAlphaSymmetricSemanticEmbedding
:所有这些类都是BaseLLM
的子类。
-> 问题:从 Chain 类派生了哪些类?
回答:有多个类派生自 Chain 类。其中一些类包括:
- APIChain
- AnalyzeDocumentChain
- ChatVectorDBChain
- CombineDocumentsChain
- ConstitutionalChain
- ConversationChain
- GraphQAChain
- HypotheticalDocumentEmbedder
- LLMChain
- LLMCheckerChain
- LLMRequestsChain
- LLMSummarizationCheckerChain
- MapReduceChain
- OpenAPIEndpointChain
- PALChain
- QAWithSourcesChain
- RetrievalQA
- RetrievalQAWithSourcesChain
- SequentialChain
- SQLDatabaseChain
- TransformChain
- VectorDBQA
- VectorDBQAWithSourcesChain
可能还有更多派生自 Chain 类的类,因为可以创建扩展 Chain 类的自定义类。
-> 问题:在 ./langchain/utilities/ 文件夹中有哪些类和函数没有被单元测试覆盖?
回答:./langchain/utilities/
文件夹中的所有类和函数似乎都有针对它们编写的单元测试。