-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlangchain-qdrant.ts
88 lines (72 loc) · 2.48 KB
/
langchain-qdrant.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
import { Ollama } from "@langchain/community/llms/ollama";
import { OllamaEmbeddings } from "@langchain/community/embeddings/ollama";
import { RecursiveCharacterTextSplitter } from "langchain/text_splitter";
import { TextLoader } from "langchain/document_loaders/fs/text";
import { ChatPromptTemplate } from "@langchain/core/prompts";
import { pull } from "langchain/hub";
import { createStuffDocumentsChain } from "langchain/chains/combine_documents";
import { StringOutputParser } from "@langchain/core/output_parsers";
import { QdrantVectorStore } from "@langchain/community/vectorstores/qdrant";
const Q = {
url: "http://localhost:6333",
collectionName: "rag",
};
const LLM = {
url: "http://localhost:11434",
model: "llama2",
};
const action = process.argv[2];
switch (action) {
case "import":
console.log("Embedding story into database...");
save("./data/zenon-story.txt");
break;
case "ask":
const question = "What Crystal of Aether was?";
console.log("Asking question: " + question);
answer(question).then(console.log);
break;
}
async function save(filePath: string) {
const embeddings = new OllamaEmbeddings();
const textLoader = new TextLoader(filePath);
const docs = await textLoader.load();
const textSplitter = new RecursiveCharacterTextSplitter({
chunkSize: 1000,
chunkOverlap: 200,
});
const splits = await textSplitter.splitDocuments(docs);
await QdrantVectorStore.fromDocuments(splits, embeddings, {
collectionName: Q.collectionName,
url: Q.url,
});
}
async function answer(question: string) {
const embeddings = new OllamaEmbeddings();
const qdrant = await QdrantVectorStore.fromExistingCollection(embeddings, {
collectionName: Q.collectionName,
url: Q.url,
});
const retrievedDocs = await qdrant.similaritySearch(question, 2);
const llm = new Ollama({
baseUrl: LLM.url,
model: LLM.model,
});
const prompt = await pull<ChatPromptTemplate>("rlm/rag-prompt");
/* Prompt:
You are an assistant for question-answering tasks. Use the following pieces of retrieved context to answer the question.
If you don't know the answer, just say that you don't know. Use three sentences maximum and keep the answer concise.
Question: {question}
Context: {context}
Answer:
*/
const ragChain = await createStuffDocumentsChain({
llm,
prompt,
outputParser: new StringOutputParser(),
});
return await ragChain.invoke({
question,
context: retrievedDocs,
});
}