Zep 开源
Zep 是一款用于 AI 助手应用程序的长期记忆服务。使用 Zep,您可以为 AI 助手提供回忆过去对话的能力,无论这些对话多么久远,同时还可以减少幻觉、延迟和成本。
有兴趣使用 Zep 云?请参阅 Zep 云安装指南
注意:ZepVectorStore
与 Documents
协同工作,旨在用作 Retriever
。它提供与 Zep 的 ZepMemory
类不同的功能,该类专为持久保存、丰富和搜索用户的聊天历史记录而设计。
为什么选择 Zep 的向量存储?🤖🚀
Zep 使用 Zep 服务器本地的低延迟模型自动嵌入添加到 Zep 向量存储的文档。Zep TS/JS 客户端可以在非 Node 边缘环境中使用。这两个功能与 Zep 的聊天记忆功能相结合,使 Zep 成为构建以延迟和性能为重的对话式 LLM 应用程序的理想选择。
支持的搜索类型
Zep 支持相似性搜索和最大边缘相关性 (MMR) 搜索。MMR 搜索对于检索增强生成应用程序特别有用,因为它会重新排序结果以确保返回文档的多样性。
安装
请按照 Zep 开源快速入门指南 的步骤安装 Zep 并开始使用它。
用法
您需要 Zep API URL,以及可选的 API 密钥来使用 Zep 向量存储。有关详细信息,请参阅 Zep 文档。
在下面的示例中,我们使用了 Zep 的自动嵌入功能,该功能会自动使用 Zep 服务器上的低延迟嵌入模型嵌入文档。由于 LangChain 需要传入 Embeddings
实例,因此我们传入 FakeEmbeddings
。
注意:如果您传入除 FakeEmbeddings
以外的 Embeddings
实例,该类将用于嵌入文档。您还必须将文档集合设置为 isAutoEmbedded === false
。请参阅下面的 OpenAIEmbeddings
示例。
示例:从文档创建 ZepVectorStore 并进行查询
请参阅 有关安装集成包的一般说明,请参阅此部分。
- npm
- Yarn
- pnpm
npm install @langchain/openai @langchain/community @langchain/core
yarn add @langchain/openai @langchain/community @langchain/core
pnpm add @langchain/openai @langchain/community @langchain/core
import { ZepVectorStore } from "@langchain/community/vectorstores/zep";
import { FakeEmbeddings } from "@langchain/core/utils/testing";
import { TextLoader } from "langchain/document_loaders/fs/text";
import { randomUUID } from "crypto";
const loader = new TextLoader("src/document_loaders/example_data/example.txt");
const docs = await loader.load();
export const run = async () => {
const collectionName = `collection${randomUUID().split("-")[0]}`;
const zepConfig = {
apiUrl: "http://localhost:8000", // this should be the URL of your Zep implementation
collectionName,
embeddingDimensions: 1536, // this much match the width of the embeddings you're using
isAutoEmbedded: true, // If true, the vector store will automatically embed documents when they are added
};
const embeddings = new FakeEmbeddings();
const vectorStore = await ZepVectorStore.fromDocuments(
docs,
embeddings,
zepConfig
);
// Wait for the documents to be embedded
// eslint-disable-next-line no-constant-condition
while (true) {
const c = await vectorStore.client.document.getCollection(collectionName);
console.log(
`Embedding status: ${c.document_embedded_count}/${c.document_count} documents embedded`
);
// eslint-disable-next-line no-promise-executor-return
await new Promise((resolve) => setTimeout(resolve, 1000));
if (c.status === "ready") {
break;
}
}
const results = await vectorStore.similaritySearchWithScore("bar", 3);
console.log("Similarity Results:");
console.log(JSON.stringify(results));
const results2 = await vectorStore.maxMarginalRelevanceSearch("bar", {
k: 3,
});
console.log("MMR Results:");
console.log(JSON.stringify(results2));
};
API 参考
- ZepVectorStore 来自
@langchain/community/vectorstores/zep
- FakeEmbeddings 来自
@langchain/core/utils/testing
- TextLoader 来自
langchain/document_loaders/fs/text
示例:使用元数据过滤器查询 ZepVectorStore
import { ZepVectorStore } from "@langchain/community/vectorstores/zep";
import { FakeEmbeddings } from "@langchain/core/utils/testing";
import { randomUUID } from "crypto";
import { Document } from "@langchain/core/documents";
const docs = [
new Document({
metadata: { album: "Led Zeppelin IV", year: 1971 },
pageContent:
"Stairway to Heaven is one of the most iconic songs by Led Zeppelin.",
}),
new Document({
metadata: { album: "Led Zeppelin I", year: 1969 },
pageContent:
"Dazed and Confused was a standout track on Led Zeppelin's debut album.",
}),
new Document({
metadata: { album: "Physical Graffiti", year: 1975 },
pageContent:
"Kashmir, from Physical Graffiti, showcases Led Zeppelin's unique blend of rock and world music.",
}),
new Document({
metadata: { album: "Houses of the Holy", year: 1973 },
pageContent:
"The Rain Song is a beautiful, melancholic piece from Houses of the Holy.",
}),
new Document({
metadata: { band: "Black Sabbath", album: "Paranoid", year: 1970 },
pageContent:
"Paranoid is Black Sabbath's second studio album and includes some of their most notable songs.",
}),
new Document({
metadata: {
band: "Iron Maiden",
album: "The Number of the Beast",
year: 1982,
},
pageContent:
"The Number of the Beast is often considered Iron Maiden's best album.",
}),
new Document({
metadata: { band: "Metallica", album: "Master of Puppets", year: 1986 },
pageContent:
"Master of Puppets is widely regarded as Metallica's finest work.",
}),
new Document({
metadata: { band: "Megadeth", album: "Rust in Peace", year: 1990 },
pageContent:
"Rust in Peace is Megadeth's fourth studio album and features intricate guitar work.",
}),
];
export const run = async () => {
const collectionName = `collection${randomUUID().split("-")[0]}`;
const zepConfig = {
apiUrl: "http://localhost:8000", // this should be the URL of your Zep implementation
collectionName,
embeddingDimensions: 1536, // this much match the width of the embeddings you're using
isAutoEmbedded: true, // If true, the vector store will automatically embed documents when they are added
};
const embeddings = new FakeEmbeddings();
const vectorStore = await ZepVectorStore.fromDocuments(
docs,
embeddings,
zepConfig
);
// Wait for the documents to be embedded
// eslint-disable-next-line no-constant-condition
while (true) {
const c = await vectorStore.client.document.getCollection(collectionName);
console.log(
`Embedding status: ${c.document_embedded_count}/${c.document_count} documents embedded`
);
// eslint-disable-next-line no-promise-executor-return
await new Promise((resolve) => setTimeout(resolve, 1000));
if (c.status === "ready") {
break;
}
}
vectorStore
.similaritySearchWithScore("sad music", 3, {
where: { jsonpath: "$[*] ? (@.year == 1973)" }, // We should see a single result: The Rain Song
})
.then((results) => {
console.log(`\n\nSimilarity Results:\n${JSON.stringify(results)}`);
})
.catch((e) => {
if (e.name === "NotFoundError") {
console.log("No results found");
} else {
throw e;
}
});
// We're not filtering here, but rather demonstrating MMR at work.
// We could also add a filter to the MMR search, as we did with the similarity search above.
vectorStore
.maxMarginalRelevanceSearch("sad music", {
k: 3,
})
.then((results) => {
console.log(`\n\nMMR Results:\n${JSON.stringify(results)}`);
})
.catch((e) => {
if (e.name === "NotFoundError") {
console.log("No results found");
} else {
throw e;
}
});
};
API 参考
- ZepVectorStore 来自
@langchain/community/vectorstores/zep
- FakeEmbeddings 来自
@langchain/core/utils/testing
- Document 来自
@langchain/core/documents
示例:使用 LangChain 嵌入类,例如 OpenAIEmbeddings
import { ZepVectorStore } from "@langchain/community/vectorstores/zep";
import { OpenAIEmbeddings } from "@langchain/openai";
import { TextLoader } from "langchain/document_loaders/fs/text";
import { randomUUID } from "crypto";
const loader = new TextLoader("src/document_loaders/example_data/example.txt");
const docs = await loader.load();
export const run = async () => {
const collectionName = `collection${randomUUID().split("-")[0]}`;
const zepConfig = {
apiUrl: "http://localhost:8000", // this should be the URL of your Zep implementation
collectionName,
embeddingDimensions: 1536, // this much match the width of the embeddings you're using
isAutoEmbedded: false, // set to false to disable auto-embedding
};
const embeddings = new OpenAIEmbeddings();
const vectorStore = await ZepVectorStore.fromDocuments(
docs,
embeddings,
zepConfig
);
const results = await vectorStore.similaritySearchWithScore("bar", 3);
console.log("Similarity Results:");
console.log(JSON.stringify(results));
const results2 = await vectorStore.maxMarginalRelevanceSearch("bar", {
k: 3,
});
console.log("MMR Results:");
console.log(JSON.stringify(results2));
};
API 参考
- ZepVectorStore 来自
@langchain/community/vectorstores/zep
- OpenAIEmbeddings 来自
@langchain/openai
- TextLoader 来自
langchain/document_loaders/fs/text