LlamaIndex와 LangChain 중 선택하기: 종합 가이드

LlamaIndex와 LangChain 중 선택하기: 종합 가이드

주요 요점

  • LlamaIndex: 고급 질의응답 및 문서 이해와 같은 작업을 위해 데이터 수집, 구조화, 개인 또는 도메인 특화 데이터 활용에 특화되어 있습니다.
  • LangChain: 대화형 에이전트, 번역, 복잡한 워크플로우를 포함한 다양한 사용 사례를 지원하며, LLM으로 애플리케이션을 개발, 배포, 확장하기 위한 오픈소스 종합 프레임워크를 제공합니다.
  • Custom LLM 통합: LlamaIndex 및 LangChain 프레임워크에서 Custom LLM을 구현하기 위한 포괄적인 단계별 코드 가이드를 제공하며, 각 프레임워크가 Novita AI와 같은 외부 API를 통합하고 활용하는 접근 방식을 보여줍니다.

소개

인공지능과 자연어 처리 분야가 급속도로 발전함에 따라, 대규모 언어 모델(LLM)을 다루는 개발자에게 두 가지 프레임워크가 강력한 도구로 부상했습니다: LlamaIndex와 LangChain입니다. 이 블로그 포스트는 LlamaIndex와 LangChain을 비교하여 각각의 주요 기능, 사용 사례 및 실제 응용 프로그램을 종합적으로 탐구하는 것을 목표로 합니다. 각 프레임워크의 핵심 기능, 가격 모델 및 통합 기능을 자세히 살펴봄으로써, 특정 요구에 가장 적합한 도구를 선택하는 데 필요한 지식을 제공할 것입니다.

LlamaIndex란 무엇인가?

LlamaIndex는 LLM에 맥락적으로 관련된 사용자 특화 데이터를 제공하여 LLM을 강화하도록 설계된 정교한 데이터 프레임워크입니다. 공개 데이터로 사전 훈련된 범용 LLM과 달리, LlamaIndex는 API 뒤에 있거나 데이터베이스 내에 있거나 PDF와 같은 비정형 형식에 갇혀 있는 개인 데이터, 도메인 특화 데이터 또는 문제 중심 데이터에 액세스하고 활용할 수 있게 합니다.

주요 기능 및 역량

  • 데이터 수집(Data Ingestion): LlamaIndex는 API, PDF, SQL 데이터베이스를 포함한 다양한 소스에서 기본 형식의 데이터를 원활하게 수집하는 데이터 커넥터를 제공합니다.
  • 데이터 구조화(Data Structuring): 수집된 데이터를 LLM이 효율적으로 사용할 수 있도록 최적화된 중간 표현으로 구조화하여 높은 성능을 보장합니다.
  • 자연어 액세스(Natural Language Access): LlamaIndex는 데이터에 대한 자연어 액세스를 허용하는 엔진을 제공하여 쿼리 엔진을 통한 질의응답을 용이하게 하고 채팅 엔진을 통한 대화형 상호작용을 가능하게 합니다.
  • 지식 워커(Knowledge Workers): 이 프레임워크에는 간단한 헬퍼부터 복잡한 API 통합에 이르기까지 다양한 도구로 강화된 LLM 기반 지식 워커 역할을 하는 에이전트가 포함됩니다.
  • 관찰 가능성 및 평가(Observability and Evaluation): 엄격한 실험, 평가 및 모니터링을 위한 통합 기능을 포함하여 애플리케이션의 지속적인 개선 사이클을 보장합니다.

사용 사례

LlamaIndex는 다음과 같은 다양한 사용 사례를 지원합니다.

  • 검색 증강 생성(RAG) 을 위한 고급 질의응답 시스템
  • 의미 있고 맥락을 인식하는 대화에 참여할 수 있는 챗봇
  • 비정형 문서에서의 문서 이해 및 데이터 추출
  • 연구를 수행하고 작업을 실행할 수 있는 자율 에이전트
  • 텍스트와 이미지 등 다양한 데이터 유형을 통합하는 멀티모달 애플리케이션
  • 특정 데이터에 대한 모델 파인튜닝 을 통한 성능 향상

LangChain이란 무엇인가?

LangChain은 LLM으로 구동되는 애플리케이션의 개발, 프로덕션화 및 배포를 간소화하도록 특별히 설계된 최첨단 프레임워크입니다. LLM 애플리케이션 수명 주기의 모든 단계를 처리하는 포괄적인 도구 및 라이브러리 제품군을 제공하여 원활하고 효율적인 개발 프로세스를 보장합니다.

주요 기능 및 역량

  • 개발(Development): LangChain은 LLM 애플리케이션 생성을 단순화하는 오픈소스 빌딩 블록, 구성 요소 및 서드파티 통합을 제공합니다. 핵심 구성 요소인 LangGraph는 스트리밍 데이터 및 사람이 개입하는 워크플로우(human-in-the-loop)에 대한 강력한 지원과 함께 상태 저장 에이전트 구축을 가능하게 합니다.
  • 프로덕션화(Productionization): LangSmith는 LLM 체인의 성능을 검사, 모니터링 및 평가하기 위한 강력한 도구입니다. 애플리케이션 성능에 대한 심층적인 통찰력을 제공하여 지속적인 최적화와 안정적인 배포를 보장합니다.
  • 배포(Deployment): LangGraph Cloud는 LangGraph 애플리케이션을 프로덕션 준비가 된 API 및 어시스턴트로 변환하여 LLM 애플리케이션을 다양한 시스템에 쉽게 확장하고 통합할 수 있도록 합니다.
  • 계층적 구조(Hierarchical Organization): 프레임워크는 여러 계층에 걸쳐 상호 연결된 부분으로 계층적으로 구성되어 애플리케이션 개발의 모듈성과 유연성을 보장합니다.

오픈소스 라이브러리

  • langchain-core: 기본 추상화와 LangChain Expression Language를 제공하여 프레임워크의 기초 역할을 합니다.
  • langchain-community: 서드파티 서비스를 통합하고 LangChain의 기능을 확장합니다.
  • 파트너 패키지: langchain-openai, langchain-anthropic과 같은 특정 통합을 제공하는 경량 패키지로 프레임워크의 다재다능함을 향상시킵니다.
  • langchain: 애플리케이션의 인지 아키텍처를 형성하는 체인, 에이전트 및 검색 전략으로 구성됩니다.
  • LangGraph: 그래프 기반 단계 모델을 사용하여 LLM으로 상태 저장 다중 행위자 애플리케이션을 구축하기 위한 강력한 도구로, LangChain과 통합하거나 독립적으로 사용할 수 있습니다.
  • LangServe: LangChain 체인을 REST API로 배포하여 웹 서비스와의 쉬운 통합을 지원합니다.
  • LangSmith: LLM 애플리케이션의 디버깅, 테스트, 평가 및 모니터링을 위한 포괄적인 도구 제품군을 제공하는 개발자 플랫폼입니다.

대상 및 사용 사례

LangChain은 LLM의 힘을 활용하려는 초보자부터 전문가까지 모든 수준의 개발자를 위해 설계되었습니다. 모듈식이고 확장 가능한 아키텍처는 광범위한 사용 사례에 적합하며, 여기에는 다음이 포함되지만 이에 국한되지는 않습니다.

  • 대화형 에이전트 및 챗봇 구축
  • 언어 번역 및 요약 도구 개발
  • 콘텐츠 생성 및 분류 시스템 구축
  • LLM을 사용한 복잡한 워크플로우 구현

LlamaIndex vs LangChain: 주요 차이점

핵심 기능

  • LangChain 은 LLM으로 데이터 인식 및 에이전트 기반 애플리케이션 생성을 간소화하도록 설계된 포괄적인 프레임워크입니다. 다양한 LLM 기반 애플리케이션을 위한 광범위한 도구를 제공하며, 유연성과 고급 AI 기능에 중점을 둡니다.
  • LlamaIndex(이전 GPT Index)는 LLM을 위한 개인 또는 도메인 특화 데이터를 수집, 구조화 및 액세스하는 데 특화된 데이터 프레임워크입니다. 정보의 인덱싱 및 검색을 단순화하여 텍스트 기반 검색 및 정확한 응답 생성에 이상적입니다.

사용 사례

  • LangChain 은 텍스트 생성, 언어 번역, 텍스트 요약, 텍스트 분류와 같은 다양한 애플리케이션에 사용할 수 있는 다재다능한 도구입니다. 뛰어난 메모리 관리 및 체인 기능 덕분에 길고 맥락에 맞는 대화를 유지하는 데 특히 적합합니다.
  • LlamaIndex 는 텍스트 검색과 고품질 응답이 최우선인 시나리오에서 탁월합니다. 일반적인 사용 사례로는 콘텐츠 생성, 문서 검색 및 검색, 챗봇 및 가상 비서를 위한 LLM 증강 등이 있습니다.

가격 및 가용성

  • LangChain 은 오픈소스 무료 도구로, 소스 코드를 GitHub과 같은 플랫폼에서 다운로드할 수 있어 누구나 사용할 수 있습니다.
  • LlamaIndex 는 상용 제품이며 가격은 사용량에 따라 결정되므로 애플리케이션 내에서 사용되는 범위에 따라 비용이 발생할 수 있습니다.

사용자 정의 및 유연성

  • LangChain 은 고급 사용자 정의 옵션을 제공하므로 특정 요구 사항에 맞게 애플리케이션을 미세 조정해야 하는 개발자에게 적합합니다.
  • LlamaIndex 는 사용자 친화적인 기능과 도구를 제공하여 개인 또는 도메인 특화 데이터를 LLM에 원활하게 통합할 수 있도록 하며, 사용 편의성과 간편한 데이터 관리에 중점을 둡니다.

데이터 처리

  • LangChain 은 다양한 데이터 유형 및 소스와 함께 작동하도록 설계되었으며, 데이터 구성을 위한 Schema 구성 요소와 효율적인 정보 검색을 위한 Indexes를 제공합니다.
  • LlamaIndex 는 다른 인덱스에서 인덱스를 구성할 수 있는 기능을 강조하여 여러 데이터 소스가 포함된 복잡한 쿼리 및 워크플로우에 매우 효과적입니다.

통합

  • LangChain 은 서드파티 서비스와의 통합을 제공하며 특정 LLM 공급자를 위한 파트너 패키지로 확장할 수 있습니다.
  • LlamaIndex 는 다양한 데이터 소스의 원활한 통합을 위한 데이터 커넥터를 제공하여 데이터 품질과 성능을 향상시킵니다.

LlamaIndex vs LangChain: 실용적인 예제 비교

Ming on Medium의 글을 인용하여, LlamaIndex와 LangChain을 비교하는 몇 가지 실제 예제를 소개합니다.

로컬 LLM으로 챗봇 만들기

아래 코드 예제는 두 프레임워크에서 LLM을 초기화하고 채팅 상호작용의 출력을 출력하는 방법을 보여줍니다.

LlamaIndex 코드:

from llama_index.llms import ChatMessage, OpenAILike

llm = OpenAILike(
    api_base="http://localhost:1234/v1",
    timeout=600,
    api_key="loremIpsum",
    is_chat_model=True,
    context_window=32768,
)
chat_history = [
    ChatMessage(role="system", content="You are a bartender."),
    ChatMessage(role="user", content="What do I enjoy drinking?"),
]
output = llm.chat(chat_history)
print(output)

LangChain 코드:

from langchain.schema import HumanMessage, SystemMessage
from langchain_openai import ChatOpenAI

llm = ChatOpenAI(
    openai_api_base="http://localhost:1234/v1",
    request_timeout=600,
    openai_api_key="loremIpsum",
    max_tokens=32768,
)
chat_history = [
    SystemMessage(content="You are a bartender."),
    HumanMessage(content="What do I enjoy drinking?"),
]
print(llm(chat_history))

로컬 파일을 위한 RAG 시스템 구축

다음 코드 스니펫은 데이터를 로드하고, 인덱스를 생성하며, 쿼리를 수행하는 방법을 보여줍니다.

LlamaIndex 코드:

from llama_index import ServiceContext, SimpleDirectoryReader, VectorStoreIndex

service_context = ServiceContext.from_defaults(  
    embed_model="local",  
    llm=llm, # This should be the LLM initialized in the task above.
)  
documents = SimpleDirectoryReader(
    input_dir="mock_notebook/",
).load_data()  
index = VectorStoreIndex.from_documents(  
    documents=documents,
    service_context=service_context,
)
engine = index.as_query_engine(  
    service_context=service_context,  
)
output = engine.query("What do I like to drink?")  
print(output)

LangChain 코드:

from langchain_community.document_loaders import DirectoryLoader  
  
# pip install "unstructured[md]"  
loader = DirectoryLoader("mock_notebook/", glob="*.md")  
docs = loader.load()  
  
from langchain.text_splitter import RecursiveCharacterTextSplitter  
  
text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)  
splits = text_splitter.split_documents(docs)  
  
from langchain_community.embeddings.fastembed import FastEmbedEmbeddings  
from langchain_community.vectorstores import Chroma  
  
vectorstore = Chroma.from_documents(documents=splits, embedding=FastEmbedEmbeddings())  
retriever = vectorstore.as_retriever()  
  
from langchain import hub  
  
# pip install langchainhub  
prompt = hub.pull("rlm/rag-prompt")  
  
  
def format_docs(docs):  
    return "\n\n".join(doc.page_content for doc in docs)  
  
  
from langchain_core.runnables import RunnablePassthrough  
  
rag_chain = (  
    {"context": retriever | format_docs, "question": RunnablePassthrough()}  
    | prompt  
    | llm # This should be the LLM initialized in the task above.
)  
print(rag_chain.invoke("What do I like to drink?"))

비교 결과, RAG 시스템에 중점을 둔 LlamaIndex는 더 간단한 접근 방식을 제공하는 반면, LangChain은 더 추상적이고 고수준의 방법을 제공하는 것으로 보입니다.

LlamaIndex vs LangChain: LlamaIndex에서 Custom LLM 사용하기

Novita AI의 LLM API를 LlamaIndex와 통합하려면 Novita AI API 호출을 LlamaIndex 프레임워크 내에서 래핑하는 커스텀 어댑터를 생성해야 합니다. 아래는 이를 수행하는 방법에 대한 개념적인 예제입니다. 이 예제는 API 및 LlamaIndex 프레임워크 작업에 대한 기본적인 이해가 있다고 가정합니다.

1단계: Novita AI LLM용 커스텀 어댑터 정의

먼저 Novita AI LLM용 커스텀 어댑터를 정의합니다.

class NovitaAILLM:
    def __init__(self, api_key):
        from openai import OpenAI
        self.client = OpenAI(api_key=api_key, base_url="https://api.novita.ai/v3/openai")

    def complete_chat(self, messages, stream=False, max_tokens=512):
        response = self.client.chat.completions.create(
            model="Nous-Hermes-2-Mixtral-8x7B-DPO",
            messages=messages,
            stream=stream,
            max_tokens=max_tokens
        )
        return response

2단계: LlamaIndex 서비스 컨텍스트에 통합

다음으로 이 어댑터를 LlamaIndex 서비스 컨텍스트에 통합해야 합니다. 다음은 이를 수행하는 방법에 대한 개념적인 예제입니다.

from llama_index import (
    KeywordTableIndex,
    SimpleDirectoryReader,
    ServiceContext,
)
from llama_index.llms import LLM

class NovitaAILLMAdapter(LLM):
    def __init__(self, api_key):
        self.novitailm = NovitaAILLM(api_key)

    def generate_text(self, prompt, stop_sequences=None, **kwargs):
        # Prepare the messages for the chat completion
        messages = [
            {"role": "system", "content": prompt}
        ]
        # Call the Novita AI LLM to complete the chat
        response = self.novitailm.complete_chat(messages)
        if isinstance(response, list):  # If streaming, collect all chunks
            return "".join([chunk.choices[0].delta.content for chunk in response])
        else:
            return response.choices[0].message.content

# Initialize the Novita AI LLM adapter with your API key
novitailm_adapter = NovitaAILLMAdapter(api_key="<YOUR Novita AI API Key>")

# Create the service context with the custom LLM adapter
service_context = ServiceContext.from_defaults(llm=novitailm_adapter)

# Load documents and build the index as before
documents = SimpleDirectoryReader("data").load_data()
index = KeywordTableIndex.from_documents(documents, service_context=service_context)

# Now you can use the index with the custom LLM for queries
query_engine = index.as_query_engine()
response = query_engine.query("What did the author do after his time at Y Combinator?")
print(response)

이 예제는 Novita AI의 LLM용 커스텀 어댑터를 생성하고 LlamaIndex 프레임워크에 통합하는 방법을 보여줍니다. <YOUR Novita AI API Key>를 실제 Novita AI API 키로 바꿔야 합니다.

이는 개념적인 예제이며, 사용 중인 라이브러리의 특정 버전과 Novita AI LLM의 정확한 API 세부 사항에 맞게 조정이 필요할 수 있습니다. 가장 정확하고 최신 정보는 공식 문서를 참조하십시오.

LlamaIndex vs LangChain: LangChain에서 Custom LLM 사용하기

Novita AI LLM APICustom LLM 방식으로 LangChain과 통합하려면 LangChain의 LLM 클래스를 확장하고 Novita AI의 API를 로직에 사용하는 커스텀 클래스를 생성해야 합니다.

다음은 이를 수행하는 방법에 대한 단계별 가이드입니다.

1단계: OpenAI Python 라이브러리 설치

먼저 Novita AI의 API와 상호작용하는 데 사용할 OpenAI 라이브러리가 설치되어 있는지 확인합니다.

pip install 'openai>=1.0.0'

2단계: 필요한 라이브러리 가져오기

LangChain 및 OpenAI 라이브러리에서 필요한 모듈을 가져옵니다.

from typing import Any, Dict, Iterator, List, Optional
from langchain_core.callbacks.manager import CallbackManagerForLLMRun
from langchain_core.language_models.llms import LLM
from langchain_core.outputs import GenerationChunk
from openai import OpenAI

3단계: Custom LLM 클래스 정의

LLM 클래스를 확장하여 Novita AI의 API를 사용하는 커스텀 LLM을 생성합니다.

class NovitaAILLM(LLM):
    def __init__(self, api_key: str, model_name: str = "Nous-Hermes-2-Mixtral-8x7B-DPO"):
        self.api_key = api_key
        self.model_name = model_name
        self.client = OpenAI(api_key=api_key, base_url="https://api.novita.ai/v3/openai")

    def _call(
        self,
        prompt: str,
        stop: Optional[List[str]] = None,
        run_manager: Optional[CallbackManagerForLLMRun] = None,
        **kwargs: Any,
    ) -> str:
        """Run the LLM on the given input."""
        response = self.client.chat.completions.create(
            model=self.model_name,
            messages=[{"role": "user", "content": prompt}],
            stream=False,
            max_tokens=512,
        )
        return response.choices[0].message.content

    def _stream(
        self,
        prompt: str,
        stop: Optional[List[str]] = None,
        run_manager: Optional[CallbackManagerForLLMRun] = None,
        **kwargs: Any,
    ) -> Iterator[GenerationChunk]:
        """Stream the LLM on the given prompt."""
        response = self.client.chat.completions.create(
            model=self.model_name,
            messages=[{"role": "user", "content": prompt}],
            stream=True,
            max_tokens=512,
        )
        for chunk in response:
            chunk_text = chunk.choices[0].delta.content or ""
            yield GenerationChunk(text=chunk_text)

    @property
    def _identifying_params(self) -> Dict[str, Any]:
        """Return a dictionary of identifying parameters."""
        return {
            "model_name": self.model_name,
        }

    @property
    def _llm_type(self) -> str:
        """Get the type of language model used by this chat model. Used for logging purposes only."""
        return "NovitaAILLM"

4단계: Custom LLM 초기화 및 사용

Novita AI API 키로 커스텀 LLM 인스턴스를 생성하고 텍스트를 생성하는 데 사용합니다.

# Replace with your actual Novita AI API key
novita_api_key = "<YOUR Novita AI API Key>"

# Initialize the custom LLM
novita_llm = NovitaAILLM(api_key=novita_api_key)

# Generate text
prompt = "Hi there!"
response = novita_llm._call(prompt=prompt)
print(response)

# Or stream the response
for chunk in novita_llm._stream(prompt=prompt):
    print(chunk.text, end="")

이 코드는 주어진 프롬프트를 기반으로 텍스트를 생성하기 위해 Novita AI의 API를 사용하는 커스텀 LLM을 설정합니다. _call 메서드는 비스트리밍 응답에 사용되고 _stream 메서드는 스트리밍 응답에 사용됩니다. Novita AI의 API 문서 및 특정 요구 사항에 따라 model_name 및 기타 매개변수를 조정하십시오.

결론

결론적으로, LlamaIndex와 LangChain은 각각 고유한 강점을 가진 LLM 작업을 위한 귀중한 도구입니다. LlamaIndex는 데이터 수집 및 검색에 탁월하여 특정 데이터의 효율적인 처리와 고급 질의응답 시스템이 필요한 프로젝트에 이상적입니다. LangChain은 모듈식 아키텍처와 광범위한 통합을 통해 LLM 애플리케이션을 개발하고 배포하기 위한 보다 포괄적인 프레임워크를 제공합니다. 둘 사이의 선택은 프로젝트의 특정 요구 사항에 따라 달라집니다.

자주 묻는 질문(FAQ)

LangChain과 LlamaIndex를 함께 사용할 수 있나요?

네. LLM 프로젝트의 특정 요구 사항에 따라 다릅니다.

LangChain은 프로덕션 환경에 적합한가요?

네, LangChain 0.1 이상은 프로덕션에 바로 사용할 수 있습니다.

RAG에 어떤 것이 더 좋은가요? LlamaIndex 또는 LangChain?

데이터 검색 및 검색 기능이 주된 관심사라면 LlamaIndex를 추천합니다. 복잡한 워크플로우를 처리할 수 있는 유연한 프레임워크가 필요한 시나리오에는 LangChain이 더 적합합니다.

Novita AI 는 AI 비전을 실현하는 올인원 클라우드 플랫폼입니다. 통합 API, 서버리스, GPU 인스턴스 — 비용 효율적인 도구를 제공합니다. 인프라 걱정 없이 무료로 시작하여 AI 비전을 현실로 만드세요.

추천 자료

LangChain으로 LLM 만들기: 단계별 가이드

스트리밍 LangChain 마스터하기: LLM과 상호작용을 위한 팁