Runnable
LangChain에서 입력 → 출력 변환을
표준 인터페이스(invoke/ainvoke/stream/batch 등으로
실행 가능하게 만든 단위
| 메서드 | 기능 |
|---|---|
invoke | 한 번에 하나 실행 (동기) |
ainvoke | 한 번에 하나 실행 (비동기) |
batch | 여러 입력 동시 실행 (병렬 처리 최적화) |
stream | 결과 실시간 스트리밍 (타자기 효과) |
astream | 비동기 스트리밍 |
파이프 연산자(|) 지원 (LCEL)
Runnable끼리는 파이프(|)로 연결 가능
각 단계가 입력/출력 스키마를 노출
입력받은 데이터를 아무런 변경 없이 그대로 다음 단계로 전달
여러 작업을 병렬로 실행하고, 결과를 모아서 하나의 dict으로 반환
일반 python 함수를 Runnable으로 변환
Prompt
변수(사용자 입력)를 받아서 프롬프트를 생성하는 템플릿
역할이 구분된 채팅 메시지 목록 형식으로 프롬프트를 생성하는 템플릿
예시(Example)를 프롬프트 안에 넣는 템플릿
사용자의 현재 질문과 가장 관련성이 높은 예제를 선택하는 클래스
채팅 모델을 위해, 예제들을 '대화 기록(메시지 리스트)' 형태로 주입하는 템플릿
Output Parsers
LLM의 출력을 구조화된 형태로 변환하는 컴포넌트
텍스트 형태의 응답을 사용자가 정의한 Schema에 맞게 변환
| 메서드 | 역할 | 설명 |
|---|---|---|
get_format_instructions() | 지침 제공 | LLM에게 "데이터를 어떤 모양(필드, 타입)으로 내뱉어야 하는지" 알려주는 안내문(문자열)을 생성. |
parse() | 분석 및 변환 | LLM이 내뱉은 문자열을 받아서, 미리 정의된 Pydantic 스키마와 일치하는지 검증하고, Python 객체로 변환. |
모델 호출 단계에서 스키마를 강제하고, 결과를 Pydantic으로 돌려주는 래퍼
(모델이 텍스트를 생성하는 게 아니라,
API 레벨에서 정확한 데이터 구조를 출력하도록 강제됨)
콤마로 이어진 긴 문장을, 리스트(List) 형태로 반환
로컬 모델은 PydanticOuputParser가 동작하지 않는 경우가 많으므로, 대안으로 StructuredOutputParser를 사용.
High Param 모델에서, 주어진 JSON 스키마에 맞게 결과를 도출
Pandas DataFrame에서 요구하는 데이터를 추출하는 도구
LLM의 출력을 datetime 형식으로 파싱
LLM 출력이 정해진 보기(Enum 값) 중 하나인지 검증하고,
맞으면 해당 Enum 값으로 파싱
LLM 출력이 파싱될 때 형식/스키마 오류가 나면, 그 오류를 수정하는 도구
Model
LangChain은 LLM을 위한 선택적 캐싱 레이어를 제공
컴퓨터의 메모리(RAM)에 저장.
컴퓨터의 하드디스크에 저장.
객체(모델/체인/프롬프트 설정 등)를 파일로 저장할 수 있는 형태(JSON 등)로 변환하는 과정
| 메서드 | 이름의 뜻 | 결과물 형태 |
|---|---|---|
dumpd | Dump to Dictionary | Python 딕셔너리 (dict) |
dumps | Dump to String | JSON 문자열 (str) |
Python 객체를 이진 형태로 직렬화해서 저장하는 포맷
효율적이나, 보안 위험이 있음.
모델을 다운로드하는 대신, 허깅페이스 서버에서 돌아가는 모델에 API로 요청을 보내 생성 결과만 응답으로 받는 방식
| 항목 | Inference API (Serverless) | Inference Endpoints (Dedicated) |
|---|---|---|
| 목적 | 빠른 프로토타입/실험/소규모 호출 | 프로덕션/대용량/엔터프라이즈 |
| 인프라 | 공유(다른 사용자 요청과 자원 공유) | 전용(내 엔드포인트에 리소스 할당) |
| 성능/지연 | 트래픽 상황에 따라 변동 가능, 대량 사용 시 제한 가능 | 더 예측 가능(지연/처리량 튜닝 가능) |
| 확장 | 제한적/자동 관리지만 제어권 적음 | AutoScaling 등 확장 옵션 제공 |
| 안정성 | 베스트에포트 성격(제한/변동 가능) | 가동 시간 보장/SLA, 운영 지원 포함 가능 |
| 설정 가능 범위 | 적음(간편) | 많음(클라우드/리전/인스턴스/보안 등 선택) |
| 비용 | 무료(제한 있음) 또는 저비용 중심 | 유료(전용 리소스 비용 발생) |
Hugging Face 모델을 로컬에서 실행하는 LangChain의 도구
오픈소스 LLM을 로컬에서 실행하게 해주는 도구
GPU 사용 등 실행 설정을 최적화함
Ollama에서 제공하는 모델 사용
Hugging Face에서 GGUF 모델을 받아서 사용
Hugging Face에서 .gguf 형식의 모델 파일을 받음
Modelfile 생성
그 Modelfile을 이용해 커스텀 모델 생성
format="json" 파라미터 추가"resonse in JSON format." 추가Memory
대화에서 오간 사용자 입력 + AI 응답을 순서대로 버퍼에 계속 저장해두는 메모리
최근 대화 k개만 기억하고,
오래된 대화는 잊어버리는 슬라이딩 윈도우 방식의 메모리
토큰 비용과 메모리 용량 관리
대화 턴 수가 아닌, 토큰 수 기준으로 얼마나 저장할지 결정하는 메모리
대화 속 엔티티(사람/회사/제품/장소 등)별로 사실(facts)을 뽑아서 저장하는 메모리
대화에서 나온 정보를
[주어–관계–목적어] 형태의 관계로 뽑아 지식 그래프(KG)로 저장하고,
이후 질문에 맞는 관련 관계들을 검색해 다시 컨텍스트로 넣어주는 메모리
대화가 길어질수록 전체 기록을 그대로 넣지 않고,
지금까지의 대화를 요약(Summary)으로 압축해서 저장하는 메모리
대화가 한 턴 진행될 때마다(혹은 일정 시점마다)
LLM을 사용해 이전 요약 + 새 대화 내용을 합쳐 업데이트된 요약을 생성
Buffer + Summary를 결합한 형태
최근 대화는 그대로(버퍼로) 유지하고,
오래된 대화는 삭제하지 않고 요약으로 압축해 남기는 메모리
max_token_limit 을 넘어가면대화를 Vector Store에 저장해두고,
메모리를 불러올 때마다 현재 질문과 의미적으로 가장 비슷한 상위 K개를 검색해서 가져오는 메모리
체인에 메모리를 직접 연결해서 대화 기록을 넣고 저장
램(RAM)이 아닌, DB에 파일로 저장하는 방법
SQLAlchemy를 통해 대화 기록을 DB에 자동으로 저장하고 불러오는 LangChain의 기능
필수 요소
session_idconnection멀티턴 대화에서 이전 발화를 기억하기 위해,
일반 LCEL 체인(prompt | llm | parser)에 세션별 대화 기록을
자동으로 불러와 프롬프트에 주입
문서 로더(Document Loader)
LangChain에서 텍스트 데이터를 다루는 기본적인 단위
구조
page_contentmetadata파일을 읽어와서, Document 객체 리스트로 변환해주는 도구
웹 URL을 입력받아 BeautifulSoup으로 본문을 추출해
LangChain 문서(Document)로 변환해 주는 웹 크롤러
내 컴퓨터(클라이언트) → 프록시 서버 → 목적지 서버(웹사이트/API)
실제 IP 주소 대신 프록시 서버를 거쳐 웹사이트에 접속해 차단을 피함
텍스트 분할(Text Splitter)
필요성
- 검색 품질 향상
- 비용 절감, 할루시네이션 방지
분할 과정
- 구조 파악
- 단위 선정
- 크기 설정 (Chunk Size)
- 겹치기 (Chunk Overlap)
\n\n 단위로 분할,
토큰(Token)이 아니라 문자 수(Character count)를 기준으로 청크 크기 측정
'문단 → 문장 → 단어' 순서로 텍스트를 분할
기본 구분자 목록: "\n\n", "\n", " ", ""
LLM의 토큰 제한을 지키기 위한 분할기
토큰 수를 기준으로 청크의 크기 측정
문맥/문법을 고려한 문장 분리
문자 수를 기준으로 청크의 크기 측정
베딩(벡터 변환) 모델의 윈도우 크기에 최적화된 크기로 분할
토큰 수를 기준으로 청크의 크기 측정
텍스트를 의미론적으로 유사한 청크로 분할
작동 원리
문장 분리
텍스트를 문장 단위로 분할
임베딩 & 그룹화
각 문장을 AI(임베딩 모델)를 통해 벡터로 변환
유사도 비교 및 병합
인접한 문장 그룹끼리 Cosine Similarity를 계산
유사도가 높으면 → 병합(Merge)
유사도가 낮으면 → 분할(Split)
인접한 텍스트 조각들 사이의 의미 변화량(semantic distance)을 계산,
변화량이 평균 대비 비정상적으로 큰 지점에서 청크를 분할
전체 문장 간의 변화량 중 상위 25%(Q3)를 기준으로,
이보다 더 크게 변화하는 지점(이상치)을 찾아내어 분할하는 방식
작동 원리
문장 사이의 유사도 거리(Distance)를 계산
Q1: 하위 25% 지점
Q3: 상위 25% 지점 (변화가 큰 구간)
기준점(Threshold)을 설정
특정 프로그래밍 언어에 사용되는 구분자(separators)로 분할
마크다운 텍스트를 지정한 헤더 레벨(#, ##, ### 등)을 기준으로 분할,
각 헤더 아래 내용을 하나의 청크로 묶어 관리
HTML의 <h1>, <h2> 같은 태그를 기준으로 문서를 나누고,
해당 텍스트의 상위 헤더가 무엇인지 metadata에 기록
사용 방법
① HTML 문자열 직접 분할
HTML 코드가 문자열로 있을 때 사용
② 파이프라인 연결 (URL 로드 + 추가 분할)
웹페이지를 긁어온 뒤 1차로 HTML 구조대로 분할, 2차로 글자 수로 조절
한계점
: 복잡한 구조에서는 제목(h1)과 본문(article)이 서로 다른 div 박스(하위 트리)에 담겨 있을 수 있음
JSON 데이터를 깊이 우선 탐색(DFS)하여 더 작은 JSON 청크를 생성하는 분할기
작동 원리
JSON 값 기준 분할
JSON 형태를 유지하도록 데이터를 괄호나 따옴표 짝이 맞게 분할
문자 수 기준:
글자 수를 기준으로 청크 크기를
min_chunk_size ~ max_chunk_size 범위로 맞추기 위해 분할
주의점
: 내용물(Value) 자체가 너무 길 땐, 작업이 끝난 뒤에
텍스트 분할기(RecursiveCharacterTextSplitter) 추가를 고려