Step 1: 이론 학습 (1주차)
개요
- Java 운영 환경 로그 종류 및 구조 이해
- GC 로그 포맷 학습 (JDK 8 / JDK 9+ unified logging)
- lena-ts-log-analysis 서비스 아키텍처 파악
- 관련 문서 숙지 (README, CONTRACT, DECISIONS, REQUIREMENTS)
상세 노트 목록
| 번호 | 제목 | 로컬 파일 | 원본 링크 |
|---|---|---|---|
| 1 | RAG (Retrieval-Augmented Generation) | 이론01_RAG.md | 이론01_RAG (내부 문서) |
| 2 | LangChain, LangGraph | 이론02_LangChain_LangGraph.md | 이론02_LangChain, LangGraph (내부 문서) |
학습 요약
이론01: RAG
- RAG(Retrieval-Augmented Generation): 외부 문서 DB에서 검색한 내용을 바탕으로 LLM이 답변을 생성하는 기술
- 구성 모델: Embedding 모델 (텍스트→벡터) + Generating 모델 (답변 생성)
- RAG 발전 단계:
- Naive RAG: 검색 한 번 → 생성 한 번
- Advanced RAG: Pre/Post-Retrieval 최적화 추가
- Modular RAG: 독립 모듈 조합 (Router, Reranker, Compressor 등)
- Agentic RAG: AI Agent가 자율적으로 판단·반복하며 답변 도달
- Vector DB: 벡터 임베딩을 저장/검색하는 DB (OpenSearch, Aurora pgvector, Bedrock Knowledge Bases 등)
이론02: LangChain, LangGraph
- LangChain: LLM 기반 앱을 쉽게 만들기 위한 범용 프레임워크 (선형 파이프라인)
- 구성: Prompt → Chain → Memory → Retrieval → Agent
- LCEL 문법으로
|파이프 연산자 사용
- LangGraph: LangChain의 복잡한 흐름 한계를 해결하는 확장 라이브러리 (그래프 구조)
- 구성: State (공유 데이터) → Node (작업 함수) → Edge (연결/분기) → Compilation
- CheckPointer로 상태 저장, 대화 히스토리 유지
- 순환/조건 분기/반복 가능
- 비교: LangGraph(그래프, 자유도 높음) vs CrewAI(팀/역할) vs AutoGen(대화 기반)
병합된 상세 노트
이론01_RAG
원본: 이론01_RAG (내부 문서)
0. RAG란?
정의
RAG(Retrieval-Augmented Generation)이란 검색 증강 생성으로, 외부 문서 데이터베이스에서 검색한 내용을 바탕으로 상세하고 정확한 답변을 생성하는 기술
- 검색(Retrieval): 사용자가 질문하면, 외부에서 정보를 검색
- 증강(Augmented): 검색된 문서 조각들과 원래 사용자의 질문을 결합
- 생성(Generation): 합쳐진 정보를 LLM에게 전달 이후 답변 생성
RAG 구성에 필요한 모델
RAG를 구성하기 위해서는 2개의 모델이 필요
| 역할 | 하는 일 | 예시 | 특징 |
|---|---|---|---|
| Embedding | 텍스트 → 벡터 변환 | OpenAI text-embedding | 가볍고 빠르며 저렴 |
| Generating | 검색된 컨텍스트로 답변 생성 | GPT-4, Claude, Llama | 텍스트를 생성하며 Embedding 모델에 비해 비쌈 |
RAG 성능을 결정하는 요소
| 단계 | 영향 요소 | 이유 |
|---|---|---|
| 문서 분할 | Chunk 크기, 분할 전략 | Chunk의 크기에 따라 맥락과 관계 없는 내용 혹은 유실이 될 수 있음 |
| 임베딩 모델 | 모델 품질 | Chunk된 데이터를 얼마나 정확한 벡터로 표현하느냐 |
| 벡터DB 검색 | 검색 알고리즘 | 관련 문서를 잘 찾아오나 |
| 생성 LLM | 모델 성능 | 찾아온 문서를 얼마나 잘 이해하고 답변하느냐 |
1. RAG의 흐름
Data 가공 단계
특징:
- 저장된 문서를 코드를 통해 분할 (청크)
- 해당 청크를 임베딩 모델로 전달하여 텍스트를 벡터로 변환
- VectorDB에 변환된 벡터 데이터를 저장
Chunking
- 긴 문서를 통째로 처리하면 의미가 희석되거나 모델의 처리 한계를 넘어서기 때문에 Chunk라고 불리는 적당한 크기의 조각으로 자르는 작업
- 길이 단위로 자르는 방식과 의미 단위로 자르는 방식
Embedding
- Chunk 조각을 컴퓨터가 이해할 수 있는 “숫자 배열”로 변환하는 작업
- 비슷한 의미를 가진 텍스트를 숫자 공간 상에 가까운 위치에 배치
AWS 아키텍처:

Runtime 단계
Naive RAG
특징:
- 자연어 쿼리를 Embedding Model에 전달하여 벡터 변환
- 변환된 벡터를 기반으로 VectorDB에서 검색
- Dense 검색: 의미 유사도
- Sparse 검색: 키워드
- Hybrid 검색: Dense와 Sparse
- 반환된 문서를 이용하여 Prompt를 생성하여 Large Language Model에 전달
AWS 아키텍처:

Advanced RAG
목표: 검색 품질 향상
특징: Naive RAG의 한계인 “검색 한 번, 생성 한 번”을 보완하기 위해 검색 전/중/후에 최적화 단계를 추가하는 방식
- Pre-Retrieval (검색 전) - 질문을 다듬는 단계
- Query Rewriting: 질문을 검색에 유리한 형태로 재작성
- Query Expansion: 동의어/관련어를 추가해서 검색 범위를 넓힘
- Query Decomposition: 복잡한 질문을 쪼갬
- HyDE: 검색 품질을 높이기 위해 LLM이 가상의 답변 문서를 생성하여 그 문서를 임베딩해 검색하는 기법
- Retrieval (검색 중) - 검색 자체를 개선
- Hybrid Search: Dense(의미) + Sparse(키워드) 검색 결합
- Semantic Chunking: 고정 크기가 아닌 의미 단위로 문서 분할
- Post-Retrieval (검색 후) - 결과를 정제
- 검색된 청크를 재순위 매기거나 압축하여 LLM에 제공할 때 품질을 개선
- Rerank: Cross-encoder 모델로 검색된 청크의 관련성을 재평가하고 순위 재정렬
- Filtering: 관련없는 문서 제거
- Compression: 질문과 관련된 핵심 부분만 추출
AWS 아키텍처:

Modular RAG
정의: RAG 시스템을 하나의 고정된 파이프라인으로 보지 않고, 여러 개의 독립적인 모듈로 쪼개서 조합하는 방식
목표: 구조적 유연성
특징:
- 개발자가 사전에 설계
- 각 기능이 독립된 부품으로 분리되어 유연하고 확장성을 가짐
- 비선형적
- 설계된 대로만 동작
모듈 유형:
- Memory: 이전 대화 맥락 확인
- Query Transformation: 사용자의 질문을 LLM이 검색하기 좋게 다시 쓰거나 여러 개로 쪼개는 단계
- Router: 질문 전달 경로 지정
- Retriever: 결정된 경로에 따라 벡터 DB나 외부 검색 엔진에서 실제 데이터 반환
- Reranker: 반환된 문서들 중 질문과 가장 관련 있는 것들이 위로 오도록 순서 재배치
- Context Compressor: Reranker가 골라낸 긴 문서에서 답변에 불필요한 노이즈를 제거하고 핵심만 남겨 LLM의 부담 제거
- Generator: 압축된 핵심 정보와 질문을 합쳐 최종 답변 작성
- Verifier: 생성된 답변이 문서 내용에 기반했는지와 사실인지 확인
패턴 방식:
- Linear: 모듈을 순서대로 실행, 가장 일반적인 Naive RAG와 비슷하지만 각 모듈 교체 가능
- Conditional: 라우터가 질문 유형에 따라 다른 경로를 선택
- Branching: 여러 검색을 동시에 실행하고 결과를 합침
- Loop: 결과가 만족스러울 때까지 검색-생성 반복
Agentic RAG
정의: AI Agent를 RAG 파이프라인에 통합하여, 에이전트가 스스로 판단하고 행동하며 반복하면서 최선의 답변에 도달하는 방식
목표: 자율적 판단
특징:
- 모듈 조합을 미리 설계할 필요 없이 에이전트가 실시간으로 결정
- 에이전트가 하는 작업: 쿼리 재작성 / 추가 검색 필요 여부 판단 / 소스 선택 / 답변 검증 / 불만족 시 재시도
에이전트 유형:
- 라우팅 에이전트: 질문의 유형/의도를 분석하여 적절한 데이터 소스나 처리 경로 분기 (멀티 소스 RAG의 기본 구조)
- 쿼리 에이전트: 복잡한 질문을 여러 하위 질문으로 분해, 독립적으로 검색 후 결과 종합 (비교/분석/다단계 추론에 적합)
- ReAct 에이전트: 생각·행동·관찰 루프를 반복하며 정답 도달 (가장 범용적, 기본 Agent 패턴)
- 계획 및 실행 에이전트: ReAct의 효율화 버전, 전체 계획을 한 번 수립 후 한 번에 실행
- Tool-Use Agent: 벡터 검색 외에도 여러 외부 도구를 상황에 맞게 호출 (OpenAI Function Calling, Anthropic Tool Use)
AWS 아키텍처:

2. Vector DB란
정의: 벡터 임베딩을 기본적으로 저장 및 관리하고, 임베딩이 설명하는 비정형 데이터(문서, 이미지, 동영상, 오디오 등)를 처리할 수 있는 데이터베이스
특징:
- 벡터(숫자 배열)을 저장하고, 유사한 벡터를 빠르게 찾아주는 데이터베이스
- RAG 뿐만이 아니라 이미지 검색, 추천 시스템, 이상 탐지 등에서 사용
- 유사한 것을 찾아야 할 때 사용
동작 원리:
- 저장(임베딩): 텍스트/이미지/오디오 같은 비정형 데이터를 숫자 배열인 벡터로 변환, 비슷한 의미의 데이터는 가까운 좌표에 위치
- 인덱싱: 데이터를 특정한 구조로 정리하는 과정
- 유사도 계산: 사용자의 쿼리를 벡터로 변환한 뒤, 저장된 벡터들과의 거리를 계산해 ‘비슷함’의 정도를 측정
- 후처리: 검색된 결과 중 가장 유사도가 높은 상위 답변들을 반환, 필요시 메타데이터를 결합해 최종 결과 반환
주요 벡터 DB:
- 솔루션: Chroma, Pinecone, Milvus, Qdrant, Weaviate
AWS 관리형 서비스:
| 서비스 | 특징 |
|---|---|
| OpenSearch Service | 하이브리드 검색 가능, 키워드 검색에 강점, 최근 벡터 검색 기능 추가 |
| RDS Aurora (pgvector) | PostgreSQL에 벡터 확장 |
| Bedrock Knowledge Bases | RAG를 전체적으로 관리해주는 서비스, 벡터DB + 임베딩 + 검색을 AWS가 처리 |
| Neptune (그래프 DB) | 지식 그래프 기반 검색이 필요할 때 사용 |
참고
Graph RAG
정의: 데이터를 점(노드)과 선(엣지)의 지도로 만들어, 질문과 관련된 맥락을 샅샅이 추적해 답변하는 기술
목표: 관계 이해
특징:
- 데이터 속 숨겨진 개체와 그들 간의 관계를 그려 정확도를 상승
- 그래프 DB를 사용
| 항목 | Vector RAG | Graph RAG |
|---|---|---|
| 검색 | 텍스트 유사도 기반 | 개체 간 관계 및 경로 기반 |
| 추론 | 단편적인 정보 검색에 강함 | 복잡한 다단계 추론에 탁월 |
| 적합 질문 | 단순 팩트 질문 | 관계성 질문 (상관/인과 관계 또는 연관 내용 등) |
이론02_LangChain, LangGraph
원본: 이론02_LangChain, LangGraph (내부 문서)
0. LangChain, LangGraph이란?
LangChain이란?
- LLM 기반 어플리케이션을 쉽게 만들기 위한 범용 프레임워크
- 표준화된 모듈로 제공
- 선형적 구조
- 단순 파이프라인 적합
LangGraph란?
- LangChain의 복잡한 흐름 한계를 해결하기 위해 나온 확장 라이브러리
- 그래프 구조
- 복잡한 워크플로우 또는 멀티 에이전트 적합
1. LangChain
구성 요소
Prompt — 프롬프트 템플릿, 프롬프트를 재사용 가능한 템플릿으로 관리
from langchain.prompts import ChatPromptTemplate
prompt = ChatPromptTemplate.from_template(
"너는 {role}이야. 다음 질문에 답해줘: {question}"
)Chain — 모듈 연결 파이프라인, 여러 단계를 하나의 파이프라인으로 연결. LCEL(LangChain Expression Language) 문법으로 | 파이프 연산자를 사용
chain = prompt | llm | parser
result = chain.invoke({"role": "요리사", "question": "파스타 만드는 법"})Memory — 대화 이력 관리, stateless로 이전 대화 유지 불가
Retrieval — 외부 데이터 검색, 외부 문서 로드/임베딩/벡터DB 저장/검색 등 RAG 관련 모듈 포함, 필요시 동작
Agent — 도구 선택, 상황에 따라 특정 도구(웹 검색, DB 조회, 로그 파싱 등)를 쓸지 스스로 판단 및 실행
흐름

장단점
장점:
- 일회성 작업을 빠르게 구현 가능
- 커뮤니티 및 문서화 풍부
- 외부 도구, 데이터 소스 그리고 LLM과의 통합 모듈 준비
단점:
- 일회성으로 이전 단계로 되돌아가는 순환 구조 구현하기 어려움
- 메모리 공유를 하지 않기 때문에 상태를 유지하는데 좋지 않음
2. LangGraph
구성 요소
State
- 어플리케이션의 공유 데이터베이스
- 그래프의 모든 노드가 읽고 수정할 수 있는 구조화된 데이터
- 현재까지의 대화 기록 또는 계산된 변수 등을 저장
- 각 노드가 State를 읽고 업데이트하면서 흐름이 진행
from typing import Annotated, TypedDict
from langgraph.graph.message import add_messages
class State(TypedDict):
messages: Annotated[list, add_messages]
input: str # 일반 문자열도 대입 가능
loop_count: int # 반복 횟수를 추적하기 위한 변수 (선택 사항)Node
- 실제 작업을 수행하는 함수 또는 Agent
- 입력: 현재 State → 출력: State 업데이트
def node_a(state: State):
return {"messages": [("system", "Node A: 작업 수행 중...")]}
def node_b(state: State):
return {"messages": [("assistant", "Node B: LLM이 최종 답변을 생성했습니다.")]}
def node_c(state: State):
return {"messages": [("system", "Node C: 도구 실행을 완료했습니다.")]}Edge
- 노드 간의 연결, 다음에 어느 노드로 갈지 정의
- Normal: 항상 정해진 노드로 이동
- Conditional: State를 보고 동적으로 이동
from langgraph.graph import END
def router(state: State):
# 조건 1, 조건 2, 반복 로직을 판단
user_input = state["messages"][-1].content
if "반복" in user_input:
return "node_a" # 반복 경로
elif "조건1" in user_input:
return "node_b" # 조건 1 (LLM 호출 경로)
else:
return "node_c" # 조건 2 (도구 실행 경로)Graph Compilation — 모든 요소를 하나로 묶어 실행 가능한 객체 생성
from langgraph.graph import StateGraph, START
from langgraph.checkpoint.memory import MemorySaver
workflow = StateGraph(State)
# 1. 노드 추가
workflow.add_node("node_a", node_a)
workflow.add_node("node_b", node_b)
workflow.add_node("node_c", node_c)
# 2. 엣지 연결
workflow.add_edge(START, "node_a") # 시작 -> Node A
# 3. 조건부 분기 (Router) 설정
workflow.add_conditional_edges(
"node_a",
router,
{
"node_a": "node_a", # 반복: 다시 node_a로
"node_b": "node_b", # 조건 1: node_b로
"node_c": "node_c" # 조건 2: node_c로
}
)
# 4. 종료 연결
workflow.add_edge("node_b", END)
workflow.add_edge("node_c", END)
# 5. 상태 저장소 설정 및 컴파일
memory = MemorySaver()
app = workflow.compile(checkpointer=memory)CheckPointer
- State를 저장해서 대화 히스토리 유지, 중단 후 재개
- Saver의 경우 SQLite, PostgreSQL 등 다양한 DB를 선택하여 State를 저장 가능
from langgraph.checkpoint.memory import MemorySaver
memory = MemorySaver()
app = workflow.compile(checkpointer=memory)흐름

장단점
장점:
- 워크플로우를 세분화하여 사용 가능
- 시스템 전체의 State를 명시적으로 정의하여 일관성 유지에 용이
- 인간이 개입하여 결과를 수정 또는 승인하는 기능 지원
단점:
- 그래프 아키텍처와 상태 관리에 대한 개념 이해가 필요
- 구현이 복잡
3. 그 외 프레임워크, CrewAI / AutoGen
LangGraph와 비슷한 프레임워크는 CrewAI와 AutoGen이 있다.
핵심 차이:
| LangGraph | CrewAI | AutoGen | |
|---|---|---|---|
| 핵심 개념 | 그래프 | 팀 (역할 분담) | 대화 |
| 흐름 제어 | 개발자가 직접 설계 | 역할 / 목표 정의 | 에이전트끼리 대화 |
| 자유도 | 높음 | 중간 | 낮음 |
| 지원 | LangChain | OpenSource | Microsoft |