문단 클릭 = 시작 위치 선택 · 재생은 우하단 버튼/P (재생 중 클릭 = 점프)

6주차 — LangGraph Corrective RAG · ReAct 에이전트

일반 RAG에 자체 검증 단계를 더한 Corrective RAG를 LangGraph 그래프(모든 노드는 "맵을 받아 맵을 토하는 함수")로 조립하고, "에이전트 = 모델이 제어권을 갖는 것"이라는 정의 위에서 ReAct(Thought→Action→Observation) 에이전트를 로컬 LM Studio 환경으로 완성하라 — 도입부의 comsat-embed 임베딩 튜닝 레시피(하드 네거티브·티처 스코어·KL 증류)가 이론 축이다.


0. 사전 필수 용어 (선행지식)

  1. RAG(Retrieval-Augmented Generation, 검색 증강 생성) — LLM이 답하기 전에 관련 문서를 검색해 프롬프트에 넣어 주는 구조. 비유하면 "오픈북 시험"이다. 이번 주 전체가 RAG의 검색 단계를 검증·보정하는 이야기다(§2~§4).
  2. 대조학습(Contrastive Learning) — 정답(포지티브)에는 점수를 올리고 오답(네거티브)에는 점수를 깎아, 임베딩 공간에서 정답을 가깝게·오답을 멀게 배치하는 학습법. 비유하면 "짝 맞추기 게임을 반복해 비슷한 것끼리 모으는 훈련". §3-A의 하드 네거티브 마이닝이 이 학습의 재료다.
  3. 유한 상태 기계(FSM)와 그래프 — 시스템을 "상태 + 상태 간 이동(엣지)"으로 그리는 모델. 비유하면 순서도(플로우 차트)다. LangGraph는 LLM 워크플로우를 이 그래프로 설계한다(§3-B). 강의 표현 그대로 — "랭그래프는 플로우 차트 잘 그리는 사람이 이긴다."
  4. 구조화 출력(Structured Output) — LLM 응답을 자유 문장이 아니라 약속된 JSON 구조로 강제하는 기법. 비유하면 "서술형 대신 OMR 카드로 답하게 하기". §4 Step 2의 문서 평가(예/아니오 분기)가 이것 없이는 불가능하다.
  5. 도구 호출(Tool Calling) — LLM이 외부 함수(검색·계산 등)를 호출하겠다고 선언하면 실행계가 대신 실행해 결과를 돌려주는 구조. 비유하면 "비서가 전화기를 드는 것". §3-D ReAct 에이전트의 행동(Action)이 곧 도구 호출이다.

선행지식이 부족하면 AI 엔지니어링 EP17 (컨텍스트 증강과 RAG), AI 엔지니어링 EP18 (AI 에이전트와 도구) 학습자료를 먼저 보라. LangGraph 자체는 공식 문서(https://langchain-ai.github.io/langgraph/)가 Tier 1 출처다.


1. 주제 정의

이 강의(뉴런데브 RAG 스터디 6주차)는 책 6장·7장의 두 실습을 다룬다.

노트북 주제 핵심
practice6-1 자체교정 RAG(Corrective RAG) — LangGraph 로컬 LM Studio 구현 사람이 사전에 규정한 워크플로우
practice7-1 ReAct 에이전트 — 도구 기반 검색 에이전트 모델이 제어권을 갖는 에이전트

책 원본 노트북은 클라우드 API + Tavily 웹 검색 조합이지만, 본 실습은 전부 LM Studio 로컬 모델로 재현한다.

  • 완성 모델: Gemma 12B instruct 계열 (LM Studio 로드)
  • 임베딩 모델: qwen3-embedding-8b (LM Studio)
  • 벡터 저장소: Chroma (책과 동일)
  • 웹 검색: Tavily (.envTAVILY_API_KEY)

도입부 30분은 별도 주제로, Sionic AI가 공개한 한국어·일본어 Retrieval Benchmark 1위 임베딩 모델 comsat-embed의 테크 리포트(2026-07 공개, 강의 화면 기준)를 레시피 단위로 해부한다 — 이 부분이 §3-A의 이론 축이다.

📚 참고: 6장 앞부분의 LangGraph 기초 소개·간단한 챗봇 예제는 강의에서 의도적으로 건너뛰었다. 이 노트도 Corrective RAG부터 시작한다.


2. 풀려는 문제

문제 1 — 일반 RAG는 검색 결과를 의심하지 않는다. 리트리버가 무엇을 가져오든 그대로 답변을 생성한다. 임베딩 유사도로 찾아온 문서가 실제로는 관련 없다면? Corrective RAG는 여기에 자체 검증 단계를 추가한다: LLM이 문서를 보고 "관련 아닌데?"라고 판단하면 질문을 바꾸거나 웹 검색으로 보완한 뒤에야 답을 만든다. 강의 표현으로 "재작성 RAG".

문제 2 — 고정 워크플로우는 유연하지 않다. 사람이 미리 정한 순서(파이프라인)는 정확하지만, 상황에 따라 도구를 고르고 반복 여부를 판단하는 일은 못 한다. 그 제어권을 모델에게 넘긴 것이 에이전트이고, 그 최초의 형태가 ReAct 패턴이다.

문제 3 (도입부) — 임베딩 모델 학습의 진짜 병목은 데이터셋. "우리는 모든 손실함수와 학습 방법을 다 안다. 문제는 데이터셋을 확보하는 것" — 특히 정답과 미묘하게만 다른 하드 네거티브를 만들기가 어렵다. comsat-embed 리포트는 이 데이터셋 레시피를 문단 수준으로 공개한 드문 사례다.


3. 핵심 개념·구조

3-A. 임베딩 튜닝 레시피 — comsat-embed 해부

파이프라인: 다양한 코퍼스 수집(공개 도메인·허깅페이스 등) → 문서 풀 구성 → LLM으로 합성 쿼리 생성(쿼리-문서 쌍) → 하드 네거티브 마이닝 → 티처 스코어 부여 → KL 증류 학습.

  • 이지 네거티브: 누가 봐도 오답. 정답 "나는 오늘 시청에서 사람을 만났어"에 대해 "나는 오늘 비행기를 탔어" 수준.
  • 하드 네거티브: "나는 오늘 경복궁에서 사람을 만났어" — 미묘하게 다른데 다르다고 판정해야 하는 것. 만들기 어렵지만 이것이 모델의 미묘한 의미 구분 능력을 만든다.
  • 인배치 네거티브: 배치 안 다른 샘플의 정답을 전부 네거티브로 쓰는 관행. 손쉽지만 전부 이지 네거티브라서, 그럴듯하게 닮았지만 관련 없는 문서를 식별하는 능력은 못 만든다.
  • 티처 스코어: 네거티브들에 True/False가 아니라 "얘는 100점, 얘는 97, 얘는 52, 얘는 34" 식의 점수를 부여. 점수 분포를 학생 모델이 모방하도록 KL 발산(KL Divergence) 손실로 증류(Distillation)한다. 대조학습의 고전 손실인 InfoNCE를 개선한 형태이며, 수식의 온도값 T를 어떻게 주느냐에 따라 분포의 날카로움 — 즉 미묘한 차이를 얼마나 엄격하게 갈라낼지 — 이 달라진다.
  • 멀티 포지티브: 하나의 쿼리에 여러 정답(1:N), 여러 쿼리에 하나의 정답(N:1)을 함께 구성 — "몸이 아픈데 뭘 먹어야 돼?/감기야, 타이레놀" 예시.
  • 학습·테스트 분리(벤치마크 암기용 데이터 배제)도 레시피에 명시.

💡 실무 노하우: 벤치마크(MTEB) 해석법 — 0.7선을 넘는 모델들은 "구멍구멍"이라 서로 대단한 차이가 아니다. 상위권은 전부 LLM 기반 임베딩이고, 옛 방식 임베딩은 0.6~0.68대에 몰린다. 그리고 특정 언어 특화 튜닝 모델은 그 언어만 과적합된 것이므로, 벤치마크 1위라는 문구보다 "내 문서의 언어 구성"이 판단 기준이다(§7 참조).

3-B. LangGraph — 상태·노드·엣지

LangGraph는 상태(State)·노드(Node)·엣지(Edge)로 LLM 워크플로우를 그리는 프레임워크다(OSS: https://github.com/langchain-ai/langgraph).

class GraphState(TypedDict):
    question: str      # 사용자가 입력 → transform_query 가 더 나은 질문으로 덮어씀
    generation: str    # generate 가 채우는 최종 답변
    web_search: str    # grade_documents 가 "예"/"아니오"로 판정
    documents: List[str]  # retrieve 가 채움 → grade_documents 가 걸러냄 → web_search 가 보충
  • 모든 노드는 함수다. 상태 맵을 받아 새 맵을 만들어 반환한다("맵을 받아 맵을 토하는 노드"). 정적 구조체가 아니라 동적 맵에 "키에 대한 약속"만 있는 구조 — 앞 노드가 question 키를 채웠을 것이라 믿고 꺼내 쓴다.
  • 조건 분기 함수도 노드다. 단, 맵이 아니라 값(문자열) 을 반환하고, 그 값이 add_conditional_edges의 매핑에서 실제 노드 이름으로 매핑된다. switch문처럼 여러 갈래 분기도 가능하다.
  • LangChain과 LangGraph는 경쟁 관계가 아니다. 랭체인으로 만든 체인을 노드 안에 집어넣는 식으로 연동한다 — 랭체인이 기능 함수라면 랭그래프는 큰 그림(플로우)이다.

✅ 확인: 좋은 습관 — 노드에서 기존 맵을 수정하지 말고 새 맵을 만들어 반환하라. 그래프가 돌면서 생기는 수많은 상태 꼬임 문제를 예방한다.

3-C. Corrective RAG 그래프 구조

START → retrieve → grade_documents ─(decide_to_generate)─┬→ generate → END
                                                          └→ transform_query → web_search_node → generate
GraphState 필드 처음 채워지는 곳 이후 바뀌는 곳
question 사용자 입력 transform_query가 더 나은 질문으로 덮어씀
documents retrieve가 검색 결과로 채움 grade_documents가 관련 없는 문서를 걸러냄, web_search_node가 웹 결과를 보충
web_search grade_documents가 "예/아니오" 판정
generation generate가 최종 답변으로 채움

핵심 판정 로직: 검색된 문서 하나하나에 대해 "질문과 관련 있는가"를 이진 점수(예/아니오) 로 평가하고, 하나라도 걸러지면 web_search="예" → 질문 재작성 후 웹 검색으로 보충한다. 10개 검색 결과가 필터를 거쳐 0개가 될 수도 있으므로, 웹 검색이 최소한의 문서를 채워 주는 안전망 역할을 한다.

3-D. ReAct — 에이전트의 정의와 사이클

  • 합의된 정의: 에이전트란 모델이 제어권을 갖는 것. 사람이 사전에 제어 형태를 규정하면 워크플로우(6장), 모델이 루프를 계속 돌지·최종 답변으로 빠져나갈지를 스스로 결정하면 에이전트(7장)다. 모델이 제어권을 더 많이, 더 오래 유지할수록 창발적 가치가 커진다 — 이것이 현대 에이전트 도구들의 경쟁 축이다.
  • ReAct 사이클: 생각(Thought=리즈닝) → 행동(Action=도구 호출) → 관찰(Observation=도구 결과). 관찰을 컨텍스트에 누적하며 반복하다가 모델이 "충분하다" 판단하면 Final Answer로 빠져나간다.
  • 이 판단을 프롬프트 규약("Thought/Action/Action Input/Observation 사이클을 준수하라")으로 강제한 것이 초창기 ReAct 논문 방식이다. 강의 평가 그대로 — "초창기 논문 기반의 조악한 에이전트. 현대 모델은 이런 프로토콜이 학습에 이미 포함되어 있어 수동 프롬프트가 필요 없다."

3-E. LLM의 정체 — 로짓·샘플링·궤적 학습

  • LLM은 다음 토큰에 대한 모든 단어의 확률 분포(로짓) 를 출력하는 기계다. 그 분포에서 하나를 고르는 것이 샘플링(temperature·top-k가 여기에 영향), 고르는 방식 자체가 디코딩(greedy 등 여러 방식이 있으나 현재는 확률적 방식이 주류).
  • 학습이란 정답 토큰의 확률은 좁고 뾰족하게, 오답은 넓게 퍼지게 확률을 밀어내는 일이다.
  • 현대 에이전트용 모델은 "질문에 어떤 궤적(trajectory) 의 제어를 할지"를 학습한다 — 궤적학습. 좋은 궤적에 점수를 주는 방식(여기도 KL 손실)의 강화학습이 RLVR 계열이고, 에이전트의 헤드로 쓸 모델은 전부 이 과정을 거쳐 나온다.
  • 월드 모델: 가상 환경을 시뮬레이션하는 모델. 예 — 진짜 컴퓨터 대신 "가짜 터미널"을 흉내내는 터미널 월드 모델 위에서 에이전트 궤적을 대량·저비용·무위험으로 생성해 RL 학습 데이터를 만든다. 강의는 Qwen 계열의 빠른 대규모 릴리스(언급: 수 주 단위, 2.7T 파라미터급) 배경으로 이 월드 모델 기반 합성 데이터 파이프라인을 지목했다.

3-F. 채팅 템플릿 — 도구는 어떻게 모델에게 전달되나

API 요청의 tools 섹션은 그대로 모델에 가지 않는다. 서버가 모델별 Jinja 템플릿(머스태시류 텍스트 템플릿)으로 시스템·메시지·도구 목록을 조립해 하나의 문자열 프롬프트로 만들어 모델에 밀어넣는다. 모델은 자신이 학습받은 특수 태그(예: tools 태그) 안의 도구 정의를 인식하도록 학습되어 있다.

💡 실무 노하우: LM Studio → 모델 탭 → 다운로드한 모델 클릭 → 오른쪽 사이드의 로드/인퍼런스 설정 아래에서 해당 모델의 Jinja 채팅 템플릿을 직접 볼 수 있다. 템플릿이 어려우면 통째로 복사해 LLM에게 해석시켜라. 또한 인퍼런스 설정에서 싱킹(리즈닝)을 끄면 응답이 훨씬 빨라진다 — 코딩같이 리즈닝 예산이 필요한 작업이 아니라면 꺼라.


4. 실습·구현 가이드 (Step 1·2·3·4)

Step 1 — 환경 준비

  1. LM Studio 설치, 모델 로드(강의 기준 Gemma 12B instruct 계열 — 양자화 버전이면 로컬에서도 충분한 품질).
  2. Tavily(https://tavily.com) 가입 → API 키 발급. 신용카드 없이 월 1000 크레딧 무료. "빙이나 구글에서 정식으로 데이터를 사 오는 검색이라 품질이 좋다. 직접 크롤링하면 소송감이다."
  3. 프로젝트 루트에 .env 파일 생성, TAVILY_API_KEY 저장.
  4. 라이브러리: langchain, langgraph, chromadb, tavily-python 등.

확인: LM Studio에서 채팅 모델·임베딩 모델(qwen3-embedding-8b)이 로드되고, .env가 읽히는지 확인.

Step 2 — practice6-1: Corrective RAG 구축

  1. 문서 로딩: 구글 코딩 스타일 가이드 3종(파이썬·자바·자바스크립트, 예: https://google.github.io/styleguide/pyguide.html)을 WebBaseLoader(url).load()로 수집, 리스트를 평탄화.
  2. 청크 분할: RecursiveCharacterTextSplitter.from_tiktoken_encoder(chunk_size=250, ...) — 문단→문장→단어 순으로 구분자를 시도해 문장이 중간에 뚝 끊기는 것을 피하는 스플리터. 토크나이저 기반이라 250에서 "최대한 문장이 안 잘리게" 잘라 준다. 결과 346개 청크.
  3. 색인: Chroma 컬렉션 생성(벡터 DB의 컬렉션 = RDBMS의 테이블) → LM Studio 임베딩으로 346개 전부 삽입 → vectorstore.as_retriever().
  4. 문서 평가기(구조화 출력):
class GradeDocuments(BaseModel):
    binary_score: str  # "예" / "아니오"

structured_llm_grader = llm.with_structured_output(GradeDocuments)
retrieval_grader = grade_prompt | structured_llm_grader

랭체인이 클래스를 JSON 스키마로 인식시켜 응답을 이 구조로 강제하고, 응답 JSON을 클래스 인스턴스로 역직렬화한다(Jackson을 떠올리면 쉽다). 시스템 프롬프트는 "검색 문서가 질문과 관련 있는지를 예/아니오로만 표시하라".

  1. 노드 함수 정의 — 전부 "맵 받아 맵 반환":
def retrieve(state):
    question = state["question"]
    documents = retriever.invoke(question)
    return {"documents": documents, "question": question}
  • grade_documents: 문서 하나하나를 retrieval_grader로 판정, 관련 있는 것만 남기고 web_search 예/아니오 세팅.
  • transform_query: "더 나은 질문으로 바꿔주세요" — 입력 질문을 웹 검색에 적합한 형태로 재작성.
  • web_search: TavilySearchResults(k=3) 호출, 결과를 하나의 Document로 합쳐 documents에 보충.
  • generate: 문서들을 빈 줄로 이어붙여 컨텍스트로 넣고 답변 생성. "제공된 자료를 바탕으로 답하고, 모르면 모른다고 하라."

  • 그래프 조립:

workflow = StateGraph(GraphState)
workflow.add_node("retrieve", retrieve)          # "이름", 함수
workflow.add_node("grade_documents", grade_documents)
# ... generate, transform_query, web_search_node 동일
workflow.add_edge(START, "retrieve")
workflow.add_edge("retrieve", "grade_documents")
workflow.add_conditional_edges("grade_documents", decide_to_generate,
    {"transform_query": "transform_query", "generate": "generate"})
workflow.add_edge("transform_query", "web_search_node")
workflow.add_edge("web_search_node", "generate")
workflow.add_edge("generate", END)
app = workflow.compile()

decide_to_generate(state)는 맵이 아니라 다음에 호출할 노드를 가리키는 문자열을 반환한다.

확인: 그래프 시각화 이미지를 뽑아 START→retrieve→grade_documents→(분기)→generate→END 흐름이 그림과 일치하는지 본다.

Step 3 — practice7-1: ReAct 에이전트 구축

  1. PDF 색인: 일본/미국 ICT 정책 보고서 PDF 2종을 각각 create_pdf_retriever(pdf_path=...)(내부는 PyMuPDFLoader→분할→Chroma)로 벡터 DB화 — PDF 1개당 검색기 1개(retriever_japan, retriever_usa).
  2. 도구화:
tool_japan = create_retriever_tool(
    retriever_japan, "일본 ICT 검색기", "일본 ICT 정책 관련 질문 검색")

create_retriever_tool은 도구 이름·설명 두 가지만 지정하면 인자 스키마를 리트리버에서 알아서 만들어 주는 편의 시설이다. 웹 검색처럼 직접 함수를 도구로 만들 때는 @tool 데코레이터 — 함수 이름→도구 이름, docstring→도구 설명, 인자 타입힌트→JSON 스키마로 자동 변환된다.

  1. 에이전트 조립: 도구 3종(일본 ICT 검색기·미국 ICT 검색기·Tavily 웹 검색)을 커스텀 한글 ReAct 프롬프트(Thought/Action/Action Input/Observation 사이클 규약)와 함께 create_react_agent로 묶고, AgentExecutor(max_iterations=8)로 감싼다 — 책에는 없는, 로컬 모델의 무한 루프 대비 안전장치.

확인: 에이전트 실행 로그에 Thought(리즈닝)→도구 선택→Observation이 순서대로 찍히는지 본다.

Step 4 — 실행·검증

  • CRAG 검증: app.stream(inputs)으로 실행하면 노드별 중간 출력이 흘러나온다(invoke는 끝나야 한 번에 나와 답답하다). ① 색인 문서와 관련된 질문("파이썬 코드 작성 가이드") → retrieve→grade_documents→generate 3노드 최단 경로로 종료. ② 무관한 질문 → 4개 검색 문서 중 2개가 "관련 없음" 판정 → transform_query→web_search_node를 거쳐 웹 검색 내용이 합쳐진 답변.
  • ReAct 검증: ① 웹 검색 한 번으로 풀리는 질문 → 도구 1회 호출 후 Final Answer. ② 두 나라 정책 비교 질문 → 미국 검색→관찰→일본 검색→관찰→Final Answer, 도구 2회. ③ 복합·모호한 질문 → 모델이 스스로 하위 작업으로 분해해 도구 3회 호출 후 종합. 이 모든 판단을 모델이 한다 — 그것이 에이전트다.

5. 사례·적용

  • 리라이터 = 가드레일 입력단. 질문 재작성(transform_query) 패턴을 일반화하면: 가드레일을 프롬프트 입력단에 두면 리라이터, 출력단에 두면 필터다. 부적절한 요청("○○ 사진 그려줘")을 리라이터가 "응답 불가로 안내하라"로 바꿔치기하는 식 — 상용 서비스에서 리라이터 프롬프트는 보통 업체 비밀이다.
  • 웹 검색 질의 변환의 근거. 자연어 문장은 키워드 검색에 부적합하다. BM25는 검색 키워드가 5개를 넘어가면 역색인이 역할을 못 해 일반 검색과 다름없어진다 — 그래서 의미를 보존한 채 키워드를 압축하는 재작성이 필요하다.
  • Chroma vs pgvector 사용처. PDF 1~2개, 컬렉션 하나 만드는 소규모엔 Chroma가 가볍고 빠르다. 데이터 규모가 커지면 pgvector로 가야 한다 — Chroma는 성능 한계가 명확하다(4주차 참조).
  • 월드 모델의 실전 가치. 터미널 월드 모델 위에서 코딩 에이전트를 돌리면 실제 컴퓨터 손상 위험 없이 궤적 데이터를 대량 합성할 수 있다. 전염병 확산·단백질 등 공학 시뮬레이터의 자리를 신경망 월드 모델이 대체하는 흐름과 같은 축이다.
  • 병렬 도구 호출. 고전 ReAct는 도구를 하나 호출하고 돌아오는 직렬 루프지만, 현대 모델은 한 번의 리즈닝에서 여러 도구를 동시에 호출한다(두 PDF를 병렬로 읽는 코딩 에이전트처럼). 직렬 사이클은 개념 학습용으로 이해하라.

💡 실무 노하우: 모델 카드(제조사가 공개하는 문서)에는 "일반 작업엔 이 설정, 정밀 코딩엔 이 설정" 같은 권장 샘플링 파라미터가 실려 있다 — 그대로 적용하면 품질이 좋아진다. 프롬프트 규약보다 제조사 가이드가 먼저다.


6. 핵심 원리

  1. 에이전트 = 모델이 제어권을 갖는 것. 루프를 더 돌지, 어떤 도구를 부를지, 언제 최종 답변으로 빠져나갈지를 모델이 결정하면 에이전트, 사람이 사전에 규정하면 워크플로우. 단 한 줄의 정의가 6장과 7장을 가른다.
  2. 모든 노드는 함수, 그래프는 함수형 파이프라인. 맵을 받아 새 맵을 토하는 함수를 이름으로 등록하고 엣지로 잇는다 — 함수형 프로그래밍에서 늘 쓰던 기법이며, 조건부 분기는 "상태를 받아 노드 이름 문자열을 토하는" 함수로 구현된다.
  3. 구조화 출력이 분기를 가능케 한다. LLM의 자유 문장으로는 if문을 못 탄다. 예/아니오를 JSON 스키마로 강제해야 그래프의 조건부 엣지가 성립한다.
  4. LLM = 다음 토큰 확률분포. 로짓 위의 샘플링(temperature·top-k)과 디코딩을 구분하라. 에이전트다운 제어 능력은 궤적학습(RLVR)이 만든 성향이지 마법이 아니다.
  5. 데이터셋이 모델을 만든다. 손실함수는 공개돼 있다 — 하드 네거티브를 얼마나 잘 만드느냐가 임베딩 모델의 성능을 가른다.

7. 한계·트레이드오프

  • 시스템 프롬프트 도구 주입은 제약이 약하다. 도구 목록을 일반 텍스트로 시스템 프롬프트에 넣으면 모델이 알아듣긴 해도 도구 선택 품질이 나빠진다. 모델은 자신이 학습받은 특수 태그 형식(채팅 템플릿)으로 도구를 받을 때 강하게 제약된다 — 실습 노트북은 모델 특성을 안 타려고 일부러 약한 방식을 썼다.
  • CRAG의 안전망에도 구멍은 있다. grade가 문서를 전부 걸러내 0건이 될 수 있고, 웹 검색조차 빈 결과를 돌려주면 컨텍스트가 비어 버린다. "최소 3건은 채우자" 같은 전략으로 보강하되, 그래도 빈 경우의 폴백을 설계하라.
  • grade 단계 = 문서당 LLM 호출 1회. 검증 품질과 지연·비용의 교환이다. 문서 수가 많으면 판정 비용이 검색 비용을 추월한다.
  • 언어 특화 튜닝은 범용성을 판다. 한국어 특화 임베딩은 한국어 벤치마크에선 이기지만 다국어 혼합 문서·코드 임베딩에는 오히려 불리하다("한국어만 과적합시킨 건 용도가 정해져 있다"). comsat-embed는 허깅페이스 공개지만 비상업용 라이선스(상업 이용은 별도 문의)라는 제약도 있다.
  • 고전 ReAct 프롬프트는 구식. 직렬 도구 호출·수동 사이클 규약은 프로토콜이 내장되지 않았던 시절의 유산이다. 학습 목적으로만 쓰고, 실서비스는 모델의 네이티브 도구 호출을 써라.

⚠️ 주의: LangGraph의 상태는 "키에 대한 약속"뿐인 동적 맵이다. 정적 타입 검증이 없으므로 앞 노드가 키를 안 채우면 런타임에야 깨진다 — 노드 계약(입력 키·출력 키)을 문서화하고 새 맵 반환 습관을 지켜라.


8. 다른 접근과 비교

A B 판단 기준
RAG 구조 일반 RAG — 검색 결과를 그대로 신뢰 Corrective RAG — 자체 검증 + 질문 재작성 + 웹 보완 검색 실패 비용이 크면 B, 지연·비용 민감하면 A
프레임워크 LangChain — 체인(기능 함수 레벨) LangGraph — 그래프(플로우 레벨, 분기·루프) 둘은 경쟁이 아니라 계층 관계: 체인을 노드 안에 넣는다
제어 방식 워크플로우 — 사람이 사전 규정, 예측 가능 에이전트 — 모델이 제어권, 창발적 작업이 정형이면 워크플로우가 정확·저렴, 개방형이면 에이전트
네거티브 구성 인배치 네거티브 — 공짜지만 전부 이지 하드 네거티브 마이닝 — 비싸지만 변별력 생성 미묘한 의미 구분이 필요한 검색이면 후자 필수
증류 라벨 이진(True/False) 티처 스코어(점수) + KL 증류 점수 분포는 순위·정도 정보를 보존 — 임베딩 증류의 표준
시뮬레이션 공학 시뮬레이터 — 사람 지식의 한계 내 월드 모델 — 데이터로 학습된 가상 환경 대량 궤적 합성이 목적이면 월드 모델

9. 메타인지 자기평가

각 질문에 스스로 답해 보고, 막히면 해당 절로 돌아가라.

  1. 일반 RAG와 Corrective RAG의 그래프를 각각 그릴 수 있는가? 조건부 엣지는 어디에 붙는가? (§3-C)
  2. LangGraph 노드 함수와 조건 분기 함수의 반환값 차이를 코드로 쓸 수 있는가? (§3-B, §4 Step 2)
  3. "에이전트란 무엇인가"를 한 줄로 답할 수 있는가? 그 정의로 practice6-1과 7-1을 분류할 수 있는가? (§3-D)
  4. 이지/하드/인배치 네거티브를 예문으로 구분하고, 인배치만으로 부족한 이유를 설명할 수 있는가? (§3-A)
  5. 티처 스코어를 점수로 주는 것과 KL 증류의 연결고리를 설명할 수 있는가? (§3-A)
  6. 도구 정의가 모델에게 전달되기까지의 경로(tools 섹션→채팅 템플릿→특수 태그)를 그릴 수 있는가? (§3-F)
  7. grade 이후 문서가 0건이 될 수 있는 이유와 그 안전망을 설명할 수 있는가? (§3-C, §7)
  8. 내 서비스 문서의 언어 구성을 근거로 임베딩 모델을 선택할 수 있는가? (§3-A, §7)

📚 참고: LangGraph 공식 문서 https://langchain-ai.github.io/langgraph/ · LangChain 도구 가이드 https://python.langchain.com/docs/concepts/tools/ · ReAct 원논문 "ReAct: Synergizing Reasoning and Acting in Language Models" (arXiv:2210.03629)

난이도
에피소드
질문
카드를 로딩 중...
답변

클릭하거나 Space를 눌러 뒤집기

0 / 0
학습 진도 0%
이동   Space 뒤집기   R 셔플   P 음성 버전 2026-07-29