LangChain 활용 가이드

0. LangChain이란?

정의

LangChain은 대규모 언어 모델(LLM)을 외부 세계—데이터베이스, API, 파일 시스템, 웹—와 연결해 검색 → 추론 → 실행(행동) 이 한 흐름으로 돌아가게 해 주는 Python 기반 오픈소스 프레임워크이다.

즉, “프롬프트 한 번 호출”을 넘어 완전한 LLM 애플리케이션을 만들 때 필요한 연결·조립·관측·배포 기능을 통합 제공한다.

요소 핵심 기능 대표 모듈
연결(Connect) 벡터 스토어·SQL·HTTP API·파일 시스템 등 다양한 외부 자원과 LLM을 표준 인터페이스로 연결 langchain, langchain-community
조립(Compose) 체인(LCEL)·그래프(LangGraph)·에이전트로 복잡한 추론 루프를 선언형으로 조립 langchain-core, langgraph
관측(Observe) 토큰·시간·비용·정확도를 실시간 트레이싱·평가 LangSmith, Langfuse
배포(Serve) 작성한 체인을 FastAPI REST 또는 멀티-에이전트 서버로 바로 배포 LangServe, LangGraph Server

0-1. LangChain은 왜 필요한가?

  • LLM 한계
    • LLM은 본질적으로 “문자열을 생성”할 뿐,

· 긴 대화 앞부분을 잊는다.

· 실시간 DB·API·파일을 직접 조회하지 못한다.

· 코드 실행·파일 I/O 같은 행동을 수행하지 못한다.

  • LangChain이 해결하는 것

1. 연결 (Connect) – 외부 자원과 LLM을 쉽게 묶는다.
2. 조립 (Compose) – 체인·그래프·에이전트로 복잡한 추론·행동 루프를 선언형으로 만든다.
3. 관측 (Observe) – 토큰·시간·비용·정확도를 대시보드로 실시간 추적·테스트·평가한다.
4. 배포 (Serve) – 코드 몇 줄로 REST 서비스·멀티-에이전트 서버로 곧바로 배포한다.

LangChain은 “LLM 애플리케이션의 엔드-투-엔드 런타임”이다.

단순 프롬프트 호출만으로는 해결할 수 없는 데이터 연결·상태 관리·품질 관측·운영 문제를 한 번에 해결한다.

0-2. 핵심 라이브러리 스펙

단계 라이브러리 한 줄 역할
개발 langchain, langchain-core, langchain-community 체인·프롬프트·모델 I/O로 비즈니스 로직 구축
배포 LangGraph (상태 지닌 그래프), LangServe (REST API 래퍼) 복잡한 체인을 서버로 곧바로 배포
관측 LangSmith 트레이싱·테스트·평가를 통합한 관측 플랫폼

1. 전체 워크플로 & 학습 로드맵

undefined


2. Model I/O

2-1. LLM & Chat Model

from dotenv import load_dotenv
from langchain_openai import ChatOpenAI

load_dotenv()                                   # .env → OPENAI_API_KEY
llm = ChatOpenAI(
    model="gpt-3.5-turbo",   # 필수: OpenAI 모델명
    temperature=0.2,         # 창의성 (0.0~2.0)
    max_tokens=512,          # 응답 길이 제한
    streaming=False          # 실시간 스트림 출력 여부
)

print(llm.invoke("LangChain을 한 문장으로 설명해줘.").content)
파라미터 용도 기본값
model 사용할 OpenAI Chat 모델
temperature 창의성 / 무작위성 0.7
max_tokens 최대 응답 토큰 수 모델 기본
streaming 스트리밍 모드 on/off False
timeout 요청 제한 시간(sec) None

모델 교체 팁

ChatOpenAI만 바꾸면 Anthropic Claude, Mistral, Ollama 등도 동일 인터페이스로 사용할 수 있다.

2-2. Prompt Template

from langchain_core.prompts import ChatPromptTemplate

prompt = ChatPromptTemplate.from_messages([
    ("system",
     "당신은 기술 문서 작성가이다. 짧고 명확하게 대답한다."),
    ("user",
     "키워드 '{keyword}'를 JSON으로 요약해줘 "
     "→ summary, features[3] 필드 필수")
])
메서드 설명
from_messages() (role, content) 튜플 리스트로 프롬프트 생성
format() {placeholder} 채워 단일 문자열 반환
format_messages() 채워진 message 객체 리스트 반환 (체인 입력용)

2-3. Output Parser

from langchain_core.output_parsers import JsonOutputParser

parser = JsonOutputParser()   # {"answer": "..."} 기본 구조

raw    = llm.invoke(prompt.format(keyword="LangChain"))  # ① LLM 호출
result = parser.invoke(raw)                              # ② JSON → dict
print(result["summary"])
Parser 결과 용도 주요 메서드
StrOutputParser str 자유 형식 답변·요약 invoke()
JsonOutputParser dict 단순 JSON 응답 get_format_instructions(), invoke()
CommaSeparatedListOutputParser list[str] 태그·키워드 등 CSV invoke()
PydanticOutputParser Pydantic 모델 타입 검증 필요 시 get_format_instructions(), invoke()

2-4. Mini Chain Example

from langchain.schema.runnable import RunnablePassthrough

chain = prompt | llm | parser
print(chain.invoke({"keyword": "LangChain"}))

3. LCEL — 파이프 한 줄로 체인 조립

LCEL(LangChain Expression Language)은 | 파이프로 Runnable을 연결해 선언형으로 로직을 표현한다 (LangChain).

3-1. 실행 인터페이스

작업 동기 비동기
단일 입력 invoke() ainvoke()
스트림 출력 stream() astream()
배치 처리 batch() abatch()

3-2. 병렬 실행

from langchain_core.runnables import RunnableParallel, RunnablePassthrough
capital = PromptTemplate.from_template("{c} 수도?") | llm | parser
area    = PromptTemplate.from_template("{c} 면적?") | llm | parser

info = RunnableParallel(capital=capital, area=area)
print(info.invoke({"c": "대한민국"}))

4. RAG 파이프라인

4-1. 문서 로드

from langchain_community.document_loaders import PyPDFLoader

loader = PyPDFLoader("./spri_ai_brief.pdf")
docs   = loader.load()          # 23 page
  • PDF를 page 단위로 읽는다.
  • 페이지가 많으면 loader.load_and_split()로 스트리밍 처리도 가능하다.

4-2. 텍스트 분할

from langchain_text_splitters import RecursiveCharacterTextSplitter

splitter = RecursiveCharacterTextSplitter(
    chunk_size=1000,
    chunk_overlap=50
)
chunks = splitter.split_documents(docs)
  • LLM 입력 한도를 넘지 않도록 청크로 나눈다.
  • 오버랩으로 경계 정보 손실을 줄인다.

4-3. 임베딩

from langchain_openai import OpenAIEmbeddings
emb = OpenAIEmbeddings()        # text-embedding-ada-002 등 명시 가능
  • 각 chunk를 고차원 벡터로 변환한다.

4-4. 벡터 스토어

1) 로컬 FAISS

from langchain_community.vectorstores import FAISS

store = FAISS.from_documents(chunks, emb)
store.save_local("faiss_index")
store = FAISS.load_local("faiss_index", emb)

2) 실전용 DB (Pinecone)

import pinecone
from langchain_pinecone import PineconeVectorStore

pinecone.init(api_key="YOUR_KEY", environment="us-west1-gcp")
pc_store = PineconeVectorStore.from_documents(
    documents=chunks,
    embedding=emb,
    index_name="my-index",
    namespace="pdf-demo"
)
  • FAISS: 서버 없이 빠르고 가볍다.
  • Pinecone: 수백만~수억 벡터, 다중 서비스 공유에 적합하다.

4-5. Retriever

dense = store.as_retriever(search_kwargs={"k": 4})
  • 역할: 쿼리를 임베딩하여 후보 문서를 빠르게 찾는다.
  • 이 단계가 Recall(포괄적 검색)을 담당한다.

4-6. Reranker

from langchain_community.rerankers import CohereReranker
reranker = CohereReranker(model="baai/bge-reranker-large-ko")
  • 역할: (쿼리, 문서) 쌍을 교차-인코딩해 정밀 점수 부여 → 최종 순위 결정
  • 정확도는 ↑, 속도는 ↓. 한국어 모델을 쓰면 한글 표현에 더 강하다.

4-7. 프롬프트

from langchain_core.prompts import ChatPromptTemplate

rag_prompt = ChatPromptTemplate.from_messages([
    ("system", "검색된 문맥만 근거로 답하라. 모르면 모른다. 한국어."),
    ("user",   "{question}\n\n# Context\n{context}")
])
구역 역할 기법 · 팁
System 대화 전체 규칙·페르소나·출력 형식 지정 역할 부여: “법률 전문 챗봇”, “제품 매뉴얼 기반 챗봇” 등
강제 규칙: “제공된 문맥만 근거”, “한국어로 답변”, “모르면 모른다고 말함”
User 실제 질문 + 컨텍스트 주입 플레이스홀더: {question}, {context}처럼 런타임에 값 삽입
구분자: # Context·""" 등으로 LLM이 근거 범위를 분명히 알도록 표시
Assistant (옵션) 예시답변(Few-shot) · 출력 예시 Few-shot: 정답 예시 2~3개 넣으면 톤과 포맷이 안정됨
포맷 예시: json\n{"answer": "..."}\n 처럼 결과 형식 샘플 제공

1. 근거 강제(Grounded Answering)

"검색된 문맥만 근거로 답하라"

  • 효과: 모델이 문맥 외 내용을 추론(환각)할 확률 ↓
  • : 모르면 “모른다”·“문맥에 없다”로 답하게 명시.

2. 역할(Role) 지정

  • 시스템 메시지 첫 줄에 “너는 ~ 전문가” 식으로 정체성을 고정.
  • 특정 톤(반말, 존댓말)·형식(~한다/~했다)도 같이 적는다.

3. 컨텍스트 경계 선언

# Context
{context}
################
  • 구분선을 사용해 LLM이 어디부터 어디까지가 참고자료인지 명확히 인식.

4. 플레이스홀더 사용

  • {question} {context} {date} 등 변수로 두고 체인에서 .format() 또는 LCEL 파이프에서 주입.
  • 코드 유지·재사용이 쉬워진다.

5. 출력 형식 고정

결과를 반드시 아래 JSON 형태로 반환:
{"answer": "...", "cite": "..."}
  • 후처리(JSON 파싱, 테이블 파싱) 시 깨짐을 방지.
  • JsonOutputParser.get_format_instructions()로 자동 삽입도 가능

4-8. 체인 결합

from langchain.schema.runnable import RunnablePassthrough

chain = (
    {"context": dense, "question": RunnablePassthrough()}
    | rag_prompt
    | llm
    | parser
)

result = chain.invoke("IDC가 예측한 AI SW CAGR은?")
print(result["summary"])

모델 역할 한눈에

단계 컴포넌트 역할 핵심 포인트
임베딩 OpenAIEmbeddings 텍스트 → 벡터 의미 보존
리트리버 Dense (FAISS/Pinecone) 후보 문서 Recall top-k
리랭커 bge-reranker-large-ko 순위 재정렬 교차 인코딩
LLM GPT-4o 등 최종 답 생성 프롬프트 제약

5. 메모리 & 대화 컨텍스트

from langchain.memory import VectorStoreRetrieverMemory

memory = VectorStoreRetrieverMemory(
            retriever=store.as_retriever(k=3))

memory.save_context(
    inputs={"human": "자기소개 해줘"},
    outputs={"ai": "저는 컴퓨터과학 전공 신입 개발자입니다."})

print(memory.load_memory_variables(
         {"prompt": "전공이 뭐였지?"})["history"])

6. 에이전트 — 도구 Orchestrator

  1. Agent : 의사 결정
  2. Tools / Toolkits : 외부 액션(API, DB, 크롤러)
  3. AgentExecutor : 루프를 돌며 “계획 → 실행 → 관찰 → 수정”
from langchain.agents import load_tools, initialize_agent

tools = load_tools(["serpapi"], {"serpapi_api_key": "..."})
agent = initialize_agent(
    tools, llm, agent="zero-shot-react-description")

agent.invoke("오늘 서울 날씨 알려주고, 내일 우산 필요할지 알려줘.")

7. 품질 관리 — LangSmith 평가

  • Trace : 각 스텝 토큰·비용·시간 시각화
  • Evaluate : BLEU/ROUGE + LLM-as-Judge 지원 (docs.smith.langchain.com)
  • Monitor : 프로덕션 호출 실시간 대시보드
from langsmith import Client, RunEvaluator, Run

client = Client()
evaluator = client.create_evaluator(
    "llm-judge",
    model="gpt-4o-mini",
    rubric="helpfulness"
)
run = Run(chain, inputs={"question": "..."})
client.evaluate_run(run.id, evaluator.id)

8. 배포 전략

시나리오 권장
단일 체인 → REST LangServe – FastAPI 래퍼 한 줄
상태·분기·루프 LangGraph – 멀티-에이전트 그래프 서버
사내 운영 + 관측 LangServe + LangSmith

9. 빠른 실습 — “PDF Q&A 서버” 50줄 완성

# app.py
from fastapi import FastAPI
from langserve import add_routes
from my_chain import chain      # 위 4-8에서 만든 LCEL 체인

app = FastAPI()
add_routes(app, chain, path="/qa")
uvicorn app:app --reload  # http://localhost:8000/qa

10. 결론

  1. 학습 순서 : Model I/O → LCEL → RAG → Agent → Evaluation
  2. 프로젝트 착수 전 : 요구사항에 맞는 리트리버·메모리·에이전트 토폴로지를 먼저 설계해 재작업을 최소화하자.
  3. 운영 : LangServe로 배포하고 LangSmith로 모니터링·회귀 테스트를 자동화한다.

참고 문헌

  1. LangChain 공식 문서 – https://python.langchain.com
  2. LCEL 소개 – https://python.langchain.com/docs/concepts/lcel/
  3. LangServe – https://python.langchain.com/docs/langserve/
  4. LangSmith Evaluation Quick-Start – https://docs.smith.langchain.com/evaluation
  5. LangSmith Evaluation Concepts – https://docs.smith.langchain.com/evaluation/concepts
  6. LangChain Changelog (2025-07) – https://changelog.langchain.com/?date=2025-07-01
  7. LangGraph Server Docs – https://langchain-ai.github.io/langgraph/concepts/langgraph_server/
위로 스크롤