랭체인JS 실습 - 로컬 RAG 애플리케이션 구축하기

in #kr-dev4 months ago

최근 로컬에서 대형 언어 모델(LLM)을 실행하는 것의 중요성이 점점 더 강조되고 있습니다. 이번 글에서는 LangChain을 사용하여 로컬에서 실행할 수 있는 RAG(Retrieval-Augmented Generation) 애플리케이션을 구축하는 방법을 소개하겠습니다.

1. 문서 로딩

먼저, 로컬 임베딩과 벡터 저장을 위해 필요한 패키지를 설치합니다. 이 예제에서는 cheerio를 사용하여 웹 페이지를 로드하고 텍스트를 분할합니다.

import { CheerioWebBaseLoader } from "@langchain/community/document_loaders/web/cheerio";
import "cheerio";
import { RecursiveCharacterTextSplitter } from "langchain/text_splitter";

const loader = new CheerioWebBaseLoader(
  "https://lilianweng.github.io/posts/2023-03-15-prompt-engineering/"
);

const docs = await loader.load();

const textSplitter = new RecursiveCharacterTextSplitter({
  chunkSize: 500,
  chunkOverlap: 0,
});

const allSplits = await textSplitter.splitDocuments(docs);
console.log(allSplits.length);
// 106

위 코드는 지정된 URL에서 문서를 로드하고, 이를 500자 크기의 청크로 분할합니다. 분할된 문서의 개수를 출력하여 확인할 수 있습니다.

2. 임베딩 생성 및 벡터 저장

다음으로, 로컬 임베딩을 생성하고 이를 벡터 저장소에 저장합니다. 여기서는 OllamaEmbeddingsCacheBackedEmbeddings를 사용합니다.

import { OllamaEmbeddings } from "@langchain/community/embeddings/ollama";
import { CacheBackedEmbeddings } from "langchain/embeddings/cache_backed";
import { LocalFileStore } from "langchain/storage/file_system";
import { MemoryVectorStore } from "langchain/vectorstores/memory";

const embeddings = new OllamaEmbeddings({
  model: "nomic-embed-text",
  baseUrl: "http://localhost:11434",
});

const cacheBackedEmbeddings = CacheBackedEmbeddings.fromBytesStore(
  embeddings,
  new LocalFileStore({ rootPath: "./cache" }),
  {
    namespace: embeddings.model,
  }
);

const vectorStore = await MemoryVectorStore.fromDocuments(
  allSplits,
  cacheBackedEmbeddings
);

위 코드는 로컬에서 임베딩을 생성하고, 이를 캐시하여 벡터 저장소에 저장합니다. 이렇게 하면 유사성 검색을 통해 문서를 효율적으로 검색할 수 있습니다.

3. 모델 설정

이제 로컬 LLM을 설정합니다. 여기서는 ChatOllama를 사용합니다.

import { ChatOllama } from "@langchain/community/chat_models/ollama";

const llm = new ChatOllama({
  baseUrl: "http://localhost:11434",
  model: "aya",
});

위 코드는 로컬에서 실행되는 Ollama 모델을 설정합니다.

4. 체인 구성

검색된 문서와 간단한 프롬프트를 전달하여 요약 체인을 만들 수 있습니다. LangChain 프롬프트 허브에서 기본 RAG 프롬프트를 가져와 사용합니다.

import { StringOutputParser } from "@langchain/core/output_parsers";
import { ChatPromptTemplate } from "@langchain/core/prompts";
import { pull } from "langchain/hub";

const prompt = await pull<ChatPromptTemplate>("rlm/rag-prompt");
console.log(
  prompt.promptMessages.map((msg: any) => msg.prompt.template).join("\n")
);
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:

위 코드는 LangChain 프롬프트 허브에서 RAG 프롬프트를 가져와 출력합니다.

5. RAG QA 봇 구성

마지막으로, 사용자 질문에 따라 벡터 저장소에서 자동으로 검색하고 답변을 생성하는 RAG QA 봇을 구성합니다.

import { RunnableSequence } from "@langchain/core/runnables";
import { formatDocumentsAsString } from "langchain/util/document";

const retriever = vectorStore.asRetriever();

const chain = RunnableSequence.from([
  {
    question: (input: { question: string }) => input.question,
    context: (input: { question: string }, callbacks) => {
      const retrieverAndFormatter = retriever.pipe(formatDocumentsAsString);
      return retrieverAndFormatter.invoke(input.question, callbacks);
    },
  },
  prompt,
  llm,
  new StringOutputParser(),
]);

const question = "What are the approaches to Task Decomposition?";
const response = await chain.invoke({ question });
console.log(response);
The approaches to task decomposition include gradually simplifying the setup, using an Automatic Prompt Engineer (APE), and utilizing LangChain and other libraries for combining language models with other components to build applications.

위 코드는 사용자의 질문을 받아 벡터 저장소에서 관련 문서를 검색하고, 이를 기반으로 답변을 생성합니다.

결론

이 글에서는 LangChainJS을 사용하여 로컬에서 실행할 수 있는 RAG 애플리케이션을 구축하는 방법을 소개했습니다. 문서 로딩, 임베딩 생성, 모델 설정, 체인 구성, 그리고 RAG QA 봇 구성을 통해 로컬 환경에서 효율적으로 문서를 검색하고 질문에 답변할 수 있는 시스템을 만들 수 있습니다. 이를 통해 데이터 프라이버시를 유지하면서도 강력한 검색 및 생성 기능을 활용할 수 있습니다.

Posted using Obsidian Steemit plugin

Sort:  

[광고] STEEM 개발자 커뮤니티에 참여 하시면, 다양한 혜택을 받을 수 있습니다.

Congratulations, your post has been upvoted by @upex with a 0.21% upvote. We invite you to continue producing quality content and join our Discord community here. Keep up the good work! #upex

Coin Marketplace

STEEM 0.17
TRX 0.16
JST 0.029
BTC 62213.63
ETH 2420.81
USDT 1.00
SBD 2.59