Skip to main content

直接从向量存储中检索

本笔记本介绍了如何使用LangChain在向量索引上进行文本生成。如果我们想要生成能够从大量自定义文本中获取信息的文本,例如生成具有对先前写过的博客文章的理解的博客文章,或者可以参考产品文档的产品教程,那么这将非常有用。

准备数据

首先,我们准备数据。对于这个示例,我们从托管在Github上的markdown文件中获取一个文档站点,并将其拆分成足够小的文档。

from langchain.llms import OpenAI
from langchain.docstore.document import Document
import requests
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.vectorstores import Chroma
from langchain.text_splitter import CharacterTextSplitter
from langchain.prompts import PromptTemplate
import pathlib
import subprocess
import tempfile
def get_github_docs(repo_owner, repo_name):
with tempfile.TemporaryDirectory() as d:
subprocess.check_call(
f"git clone --depth 1 https://github.com/{repo_owner}/{repo_name}.git .",
cwd=d,
shell=True,
)
git_sha = (
subprocess.check_output("git rev-parse HEAD", shell=True, cwd=d)
.decode("utf-8")
.strip()
)
repo_path = pathlib.Path(d)
markdown_files = list(repo_path.glob("*/*.md")) + list(
repo_path.glob("*/*.mdx")
)
for markdown_file in markdown_files:
with open(markdown_file, "r") as f:
relative_path = markdown_file.relative_to(repo_path)
github_url = f"https://github.com/{repo_owner}/{repo_name}/blob/{git_sha}/{relative_path}"
yield Document(page_content=f.read(), metadata={"source": github_url})


sources = get_github_docs("yirenlu92", "deno-manual-forked")

source_chunks = []
splitter = CharacterTextSplitter(separator=" ", chunk_size=1024, chunk_overlap=0)
for source in sources:
for chunk in splitter.split_text(source.page_content):
source_chunks.append(Document(page_content=chunk, metadata=source.metadata))
    Cloning into '.'...

设置向量数据库

现在我们已经将文档内容拆分成块,让我们将所有这些信息放入向量索引中以便于检索。

search_index = Chroma.from_documents(source_chunks, OpenAIEmbeddings())

使用自定义提示设置LLM链

接下来,让我们设置一个简单的LLM链,但为其提供一个用于生成博客文章的自定义提示。请注意,自定义提示是参数化的,并且接受两个输入:context,它将是从向量搜索中获取的文档,以及topic,它由用户提供。

from langchain.chains import LLMChain

prompt_template = """使用下面的上下文来撰写一个关于以下主题的400字博客文章:
上下文:{context}
主题:{topic}
博客文章:"""

PROMPT = PromptTemplate(template=prompt_template, input_variables=["context", "topic"])

llm = OpenAI(temperature=0)

chain = LLMChain(llm=llm, prompt=PROMPT)

生成文本

最后,我们编写一个函数来将我们的输入应用于链条。该函数接受一个输入参数topic。我们找到与该topic对应的向量索引中的文档,并将它们作为我们简单的LLM链中的附加上下文。

def generate_blog_post(topic):
docs = search_index.similarity_search(topic, k=4)
inputs = [{"context": doc.page_content, "topic": topic} for doc in docs]
print(chain.apply(inputs))
generate_blog_post("环境变量")
    [{'text': '\n\n环境变量是在Deno应用程序中存储和访问敏感信息的好方法。Deno提供了对环境变量的内置支持,使用`Deno.env`,您还可以使用`.env`文件来存储和访问环境变量。\n\n使用`Deno.env`很简单。它有getter和setter方法,因此您可以轻松设置和检索环境变量。例如,您可以像这样设置`FIREBASE_API_KEY`和`FIREBASE_AUTH_DOMAIN`环境变量:\n\n```ts\nDeno.env.set("FIREBASE_API_KEY", "examplekey123");\nDeno.env.set("FIREBASE_AUTH_DOMAIN", "firebasedomain.com");\n\nconsole.log(Deno.env.get("FIREBASE_API_KEY")); // examplekey123\nconsole.log(Deno.env.get("FIREBASE_AUTH_DOMAIN")); // firebasedomain.com\n```\n\n您还可以将环境变量存储在`.env`文件中。这是一个很好的'}, {'text': '\n\n环境变量是管理程序配置设置的强大工具。它们允许我们设置可以被程序使用的值,而无需将它们硬编码到代码中。这使得更容易在不修改代码的情况下更改设置。\n\n在Deno中,可以通过使用`VAR=value`语法来设置环境变量。这将把环境变量`VAR`设置为值`value`。这可以用于在运行命令之前设置任意数量的环境变量。例如,如果我们想要在运行Deno命令之前将环境变量`VAR`设置为`hello`,我们可以这样做:\n\n```\nVAR=hello deno run main.ts\n```\n\n这将在运行命令之前将环境变量`VAR`设置为`hello`。然后,我们可以使用`Deno.env.get()`函数在我们的代码中访问此变量。例如,如果我们运行以下命令:\n\n```\nVAR=hello && deno eval "console.log(\'Deno: \' + Deno.env.get(\'VAR'}, {'text': '\n\n环境变量是开发人员的重要工具,可以让他们在不将数据硬编码到应用程序中的情况下存储和访问数据。在Deno中,您可以使用`Deno.env.get()`函数访问环境变量。\n\n例如,如果您想要访问`HOME`环境变量,可以这样做:\n\n```js\n// env.js\nDeno.env.get("HOME");\n```\n\n在运行此代码时,您需要授予Deno进程对环境变量的访问权限。这可以通过向`deno run`命令传递`--allow-env`标志来完成。您还可以指定要授予访问权限的环境变量,例如:\n\n```shell\n# 仅允许访问HOME环境变量\ndeno run --allow-env=HOME env.js\n```\n\n需要注意的是,在Windows上,环境变量不区分大小写,因此Deno也会在Windows上不区分大小写地匹配它们。\n\n在使用环境变量时还需要注意的一件事是子进程权限。子进程功能强大,可以访问系统资源,而不管您授予Deno的权限'}, {'text': '\n\n环境变量是任何编程语言的重要组成部分,Deno也不例外。Deno是一个基于V8 JavaScript引擎构建的安全JavaScript和TypeScript运行时,最近添加了对环境变量的支持。此功能在Deno版本1.6.0中添加,现在可以在Deno应用程序中使用。\n\n环境变量用于存储可以被程序使用的信息。它们通常用于存储配置信息,例如数据库的位置或用户的名称。在Deno中,环境变量存储在`Deno.env`对象中。该对象类似于Node.js中的`process.env`对象,它允许您访问和设置环境变量。\n\n`Deno.env`对象是一个只读对象,这意味着您不能直接修改环境变量。相反,您必须使用`Deno.env.set()`函数来设置环境变量。此函数接受两个参数:环境变量的名称和要设置的值。例如,如果您想要将`FOO`环境变量设置为`bar`,您可以使用以下代码:\n\n```'}]