LangChain
-
@tool이 내부에서 하는 일 — Pydantic BaseModel이 LLM의 호출 인터페이스가 되는 과정IT 2026. 6. 30. 21:00
LangGraph로 AI 에이전트를 만들다 보면 도구(tool) 함수를 정의하는 방식이 눈에 들어온다. 함수 위에 @tool 하나 붙이면 LLM이 그 함수를 알아서 호출한다. 마치 마법처럼 보이지만, 내부에서는 Pydantic BaseModel이 핵심 역할을 한다. 이 글은 그 메커니즘을 분해한다 — @tool이 Python 함수에서 무엇을 만들어내는지, 왜 굳이 BaseModel인지, 그리고 실제로 어떤 문제들이 있었는지.LLM이 함수를 호출하려면 무엇이 필요한가LLM은 텍스트를 입력받아 텍스트를 출력하는 모델이다. "search_movie 함수를 query='크리스토퍼 놀란 영화'로 호출해"라고 지시하려면 LLM에게 두 가지를 알려줘야 한다. 첫째, 그 함수가 어떤 인자를 받는지. 둘째, 각 인자의 ..
-
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)는 다른 ..
-
LLM을 분류기로 쓰기 — SystemMessage와 HumanMessage로 Classifier Node 만들기IT 2026. 6. 27. 21:00
LLM을 쓸 때 우리는 보통 "질문을 던지면 자유롭게 답해주는 것"으로 생각한다. 그런데 LLM은 전혀 다른 방식으로도 동작할 수 있다. "이 입력이 영화 추천 요청인가, 영화 정보 질문인가, 일반 대화인가"를 판단하는 분류기(Classifier)로 쓰는 것이다. LangGraph에서 라우팅을 구현할 때 이 패턴이 결정적인 역할을 한다.왜 LLM을 분류기로 쓰는가규칙 기반 분류를 먼저 떠올리기 쉽다. "추천"이라는 단어가 있으면 recommend, "정보"가 있으면 info. 하지만 사용자 입력은 예측 불가능하다. "요즘 볼만한 거 없을까?" 같은 표현은 어떤 규칙으로 잡을 것인가. LLM은 자연어를 이해하기 때문에 이런 모호한 표현도 정확히 분류할 수 있다.분류기 노드의 목적은 단 하나다. 입력을 받아..
-
bind_tools — LLM이 도구를 인식하는 방법IT 2026. 6. 26. 21:00
LLM은 기본적으로 텍스트 생성기다. 입력을 받아 다음에 올 확률이 높은 토큰을 순서대로 출력하는 것이 전부다. "계산기를 호출하라"거나 "데이터베이스를 조회하라"는 기능은 처음부터 없다. 그렇다면 LangGraph에서 에이전트가 도구를 사용할 수 있는 이유는 무엇일까? 답은 bind_tools에 있다.LLM은 도구를 어떻게 알게 되는가정확히 말하면, LLM이 도구를 "알게" 되는 것이 아니다. bind_tools(tools)는 도구 목록의 스키마—이름, 설명, 파라미터—를 LLM 호출 시 프롬프트에 자동으로 끼워 넣는다. LLM 입장에서는 그냥 더 긴 프롬프트를 받는 것이다.차이는 응답 형태에 있다. 스키마를 받은 LLM은 일반 텍스트 대신 JSON 구조의 tool_calls 필드를 포함한 응답을 내놓..
-
LangGraph가 등장한 이유 — 선형 체인을 넘어 그래프로IT 2026. 6. 25. 21:00
LangChain이 해결한 문제는 명확했다. LLM을 쓸 수 있는 형태로 만들기 위한 반복 작업을 없애는 것이다. 그런데 에이전트를 실제로 만들다 보면 또 다른 벽에 부딪힌다."결과가 부족하면 다시 검색한다." 이 한 문장을 코드로 표현하는 순간, 선형 체인(Chain)은 한계를 드러낸다. 루프가 없기 때문이다. 체인은 A → B → C로 흘러갈 수는 있어도, "C가 충분하지 않으면 B로 돌아가라"는 구조를 표현할 방법이 없다.LangGraph는 그 한계를 해결하기 위해 2024년에 등장했다. LangChain의 연장선이지만, 패러다임이 다르다. 선형(linear)에서 그래프(graph)로 달라졌다.1. 배경 — LangChain의 체인(Chain)이 충분하지 않았던 이유LangChain의 초기 핵심 개..
-
로컬 챗봇 시리즈 #3 — 도구에 '지금 누구의 첨부인지' 어떻게 알려주나: ContextVar 패턴IT 2026. 5. 8. 22:00
들어가며 — "이 PDF에서 5장 요약해줘"의 진짜 어려움PDF·DOCX·코드 파일을 챗봇에 던져서 그것에 관해 묻고 싶다는 욕구는 평범하지만, 구현은 의외로 까다롭다. 본문을 통째로 시스템 프롬프트에 박으면 컨텍스트가 폭발한다 — 300페이지 PDF면 50만 토큰. 그렇다고 모델이 PDF에 접근할 수단이 없으면 답을 못 한다.해법 자체는 RAG 풀의 표준이다 — "본문은 디스크에 두고, 모델이 필요할 때 도구로 검색하게 한다". search_attachment LangChain Tool 하나만 있으면 끝. 그런데 정작 그 도구를 만들면서 가장 흥미로운 문제가 따로 튀어나왔다 — "도구가 '지금 누구의 첨부를 검색해야 하는지' 어떻게 알지?". 이번 글은 이 한 문제와 ContextVar라는 표준 라이브..