분류 전체보기
-
Pydantic BaseModel이란 무엇인가 — 타입 힌트를 진짜 검증으로 바꾸는 도구IT 2026. 6. 29. 23:00
Python으로 LLM 에이전트나 웹 API를 만들다 보면 Pydantic BaseModel이라는 이름을 자주 만난다. LangChain의 도구 정의에서도, FastAPI의 요청 본문에서도, 설정 파일 로딩에서도 BaseModel이 등장한다. 그런데 "BaseModel을 상속받아 클래스를 만든다"는 설명만 보면 그게 정확히 뭘 해주는 도구인지 잡히지 않는다. 이 글은 BaseModel 하나만 떼어내서 본다 — 이 이름이 무엇을 의미하는지, 어떤 문제를 풀려고 태어났는지, 그리고 그 문제를 어떻게 푸는지.먼저 풀어야 할 문제: 타입 힌트는 거짓말을 막지 못한다Python에는 타입 힌트(type hint)가 있다. 함수 파라미터에 query: str, top_k: int처럼 "이 자리에는 이런 타입이 와야 ..
-
LangGraph가 Annotated를 쓰는 이유 — 덮어쓰기 문제와 리듀서의 등장IT 2026. 6. 29. 22:00
LangGraph 코드를 처음 보면 눈에 걸리는 문법이 있다.class AgentState(TypedDict): messages: Annotated[list[BaseMessage], add_messages]list[BaseMessage]만 써도 될 것 같은데, 왜 Annotated를 끼워 넣고 add_messages를 붙이는 걸까. 이 글은 그 "왜"를 배경부터 따라간다. 이 문법이 등장할 수밖에 없었던 이유, 없었을 때 생기는 문제, 그리고 리듀서라는 개념이 어떻게 그것을 깔끔하게 해결했는지를 순서대로 본다.1. 배경 — 여러 노드가 하나의 상태를 공유한다LangGraph 에이전트는 여러 노드(Python 함수)가 차례로 또는 조건에 따라 실행된다. 이 노드들이 데이터를 주고받는 방식은 함수 인자..
-
RAG 에이전트 완전 조립 — create_agent부터 동작 추적까지IT 2026. 6. 29. 21:00
RAG 파이프라인을 구성하는 세 가지 재료가 있다. 문서를 저장한 벡터 DB에서 검색해 오는 리트리버, 그 리트리버를 LLM이 호출할 수 있는 형태로 포장한 도구(@tool), 그리고 질문의 의도에 따라 어떤 도구를 몇 번 쓸지 스스로 결정하는 에이전트. 이 세 가지를 하나로 묶는 접착제가 create_agent다.이 글에서는 create_agent로 에이전트를 조립하는 방법부터 시작해, 단일 카테고리 질문과 복합 카테고리 질문이 내부에서 어떻게 다르게 처리되는지, 그리고 messages 배열을 읽어 에이전트 동작을 추적하는 방법까지 순서대로 살펴본다.1. create_agent로 RAG 에이전트 조립에이전트를 만드는 데 필요한 최소 재료는 세 가지다. LLM(model), 도구 리스트(tools), 그..
-
검색 결과를 에이전트 도구로 — build_context와 @tool 패턴IT 2026. 6. 28. 23:00
RAG 파이프라인을 에이전트에 붙이려는 순간 벽을 만난다. 리트리버는 list[Document]를 돌려주는데, 에이전트 도구는 문자열을 기대한다. 이 둘을 연결하는 접착제가 build_context이고, @tool 데코레이터는 그 함수를 에이전트가 직접 선택하고 호출할 수 있는 도구로 탈바꿈시킨다. 이 글은 그 연결 고리가 어떻게 작동하는지, 그리고 도구를 하나로 합치지 않고 카테고리별로 분리하는 이유가 무엇인지를 살펴본다.1. 리트리버와 에이전트 사이의 다리 — build_context리트리버는 질문과 유사한 청크를 벡터 DB에서 꺼내 문서 목록으로 반환한다. 그런데 에이전트 도구의 반환 타입은 문자열이어야 한다. 에이전트는 도구가 돌려준 문자열을 자신의 프롬프트에 이어 붙여 최종 답변을 생성하기 때문..
-
RAG의 배경과 make_retriever — LLM이 모르는 문서를 검색하는 방법IT 2026. 6. 28. 22:00
1. 배경 — LLM이 모르는 것들LLM은 학습 시점에 공개된 데이터만 알고 있다. 인터넷에 공개된 텍스트, 코드, 논문이 재료다. 반면 영화 정보 자료, 사내 위키, 어제 올라온 뉴스, 그리고 내가 작성한 문서는 학습에 포함되지 않는다. "올해 개봉한 '그 영화'의 OST를 누가 작곡했어?"를 물으면 LLM은 그냥 모른다.이 문제를 해결하는 방법으로 파인튜닝(fine-tuning)이 먼저 떠오른다. 우리 문서를 데이터셋으로 만들어 LLM에 추가 학습시키는 것이다. 하지만 파인튜닝은 비용이 크고, 문서가 업데이트될 때마다 재학습이 필요하다는 결정적인 문제가 있다. 영화 정보 한 줄이 바뀔 때마다 모델을 다시 굽는 건 현실적이지 않다.RAG(Retrieval-Augmented Generation)는 다른 ..
-
생성과 검증의 분리 — generator 노드와 validator 노드 설계IT 2026. 6. 28. 21:00
LangGraph로 자기수정 파이프라인을 구현할 때 가장 흔히 저지르는 실수는 "하나의 노드가 초안을 쓰고 스스로 검토하게" 만드는 것이다. 이 글은 왜 그게 문제인지, 그리고 generator와 validator를 별도 노드로 분리했을 때 무엇이 달라지는지를 코드와 함께 설명한다.왜 생성과 검증을 분리해야 하는가LLM에게 "글을 쓰고 스스로 검토해"라고 요청하면 자기 평가에 관대해진다. 사람도 자기가 쓴 글을 교정할 때 오탈자를 잘 못 잡는 것과 같은 이치다. 동일한 컨텍스트 안에서 생성 직후에 평가가 이어지면, LLM은 이미 작성한 내용을 합리화하는 방향으로 판단을 내린다.위 구조의 핵심 문제는 단 한 번의 LLM 호출이 생성과 평가를 모두 담당한다는 점이다. 초안 작성 단계에서 만들어진 내용이 자기..
-
LangGraph 자기 수정 패턴의 State 설계 — 루프를 위한 5가지 필드IT 2026. 6. 27. 23:00
LLM 기반 코드를 짜다 보면 어느 순간 "한 번 생성해서 끝내는 게 아니라, 결과물을 검토하고 부족하면 다시 고치는 루프"가 필요해진다. 글쓰기라면 초고를 쓰고 → 편집자가 피드백을 주고 → 그 피드백을 반영해 고쳐 쓰는 과정이다. LangGraph에서 이 구조를 자기 수정 패턴(self-correction loop)이라 부른다.문제는 이 루프를 코드로 옮길 때다. 단순히 while을 돌리면 되는 게 아닌가 싶지만, LangGraph는 그래프 기반 실행 엔진이라 루프의 상태를 State라는 공유 객체에 담아서 노드 간에 넘겨야 한다. 그래서 "어떤 필드를 State에 두어야 루프가 제대로 작동하는가"가 설계의 핵심이 된다. 이 글은 그 5가지 필드를 역할별로 정리한다.자기 수정 패턴이 무엇인가먼저 패턴..
-
LangGraph 조건부 라우팅 — 상태 값으로 다음 노드를 결정하는 방법IT 2026. 6. 27. 22:00
LangGraph로 멀티스텝 AI 파이프라인을 만들다 보면 반드시 마주치는 패턴이 있다. 입력이 어떤 종류인지에 따라 다른 처리 경로로 보내는 것 — 이른바 조건부 라우팅(conditional routing)이다. 단순해 보이지만 실제로 구현하다 보면 "라우팅 함수가 정확히 무엇을 해야 하는가", "add_conditional_edges의 세 번째 인자는 언제 필요한가" 같은 질문에서 한 번씩 막힌다. 이 글은 그 지점을 정확히 짚는다.라우팅 함수의 역할: 오직 "어디로 갈지"만 결정LangGraph에서 라우팅 함수를 처음 만들 때 가장 흔한 실수는 이 함수 안에서 무언가를 "생성"하려는 것이다. 라우팅 함수의 역할은 단 하나다 — state를 보고 다음에 실행할 노드의 이름을 문자열로 반환하는 것. 응..