-
LangChain이 등장한 이유 — LLM 시대의 새로운 개발 패러다임IT 2026. 6. 22. 21:00
2022년 말 ChatGPT가 공개된 이후, 개발자들 사이에서 한 가지 공통된 질문이 등장했다.
"LLM을 내 서비스에 어떻게 집어넣지?"답은 간단해 보였다. API를 호출하면 된다. 그런데 실제로 해보면 달랐다. 대화 이력을 직접 관리해야 하고, 외부 검색 기능을 붙이려면 연결 코드를 따로 짜야 하고, LLM이 여러 번 판단을 반복하도록 루프를 구현해야 했다. 강력한 언어 모델을 손에 쥐었는데, 정작 그것을 "쓸 수 있는 형태"로 만드는 데 시간의 대부분을 써야 했다.
LangChain은 그 반복을 없애려는 시도로 2022년 10월에 등장했다.
1. 배경 — GPT 등장 이후 개발자들이 맞닥뜨린 문제
LLM(Large Language Model, 거대 언어 모델) API는 사실 단순하다. 텍스트를 보내면 텍스트가 돌아온다. 문제는 그 단순함이 함정이라는 점이다. 실제 애플리케이션을 만들려면 훨씬 많은 것이 필요하다.
ChatGPT 공개 이전, 그러니까 LLM이 일반 개발자의 손에 닿기 전, 전형적인 웹 애플리케이션은 DB와 비즈니스 로직만 연결하면 됐다. 그런데 LLM을 끼워 넣는 순간 아래 그림처럼 복잡해진다.
이 다이어그램이 보여주는 것은 개발자가 직접 연결해야 하는 선의 수다. 대화 이력 관리, 프롬프트 조합, API 호출, 도구 연결 — 이 네 가지가 전부 "내 코드"여야 한다. 프로젝트가 바뀌면? 처음부터 다시 짠다. 모델을 OpenAI에서 Anthropic으로 바꾸면? 호출 방식이 달라서 또 코드를 고친다. 이게 LangChain 이전의 현실이었다.
2. 문제 정의 — 반복되는 4가지 패턴
수많은 개발자가 같은 코드를 각자의 프로젝트에서 반복 구현하고 있었다. 패턴으로 추려보면 정확히 4가지다.
이 4가지는 독립적이지 않다. 하나가 없으면 다른 것도 불완전해진다. LLM 추상화가 없으면 메모리를 어떤 형식으로 저장할지도 모델마다 달라진다. 메모리가 없으면 도구 호출 결과를 다음 판단에 넘길 수가 없다. 도구가 없으면 워크플로우가 LLM 단독 호출로만 구성된다. 그리고 워크플로우가 없으면 전체를 다시 추상화해야 한다. 악순환이다.
LangChain은 이 4가지를 동시에 해결하는 표준 레이어를 제공한다는 선언으로 출발했다.
3. LangChain의 해결 방법 — 4개의 추상화 레이어
LangChain의 핵심 아이디어는 간단하다. 반복되는 패턴을 레이어로 분리해, 교체 가능한 부품처럼 만든다. Node.js 생태계에서 Express.js가 HTTP 요청/응답의 반복을 없애준 것처럼, LangChain은 LLM 애플리케이션의 반복을 없애준다.
가장 아래 Model I/O가 기반이다. OpenAI, Anthropic, Ollama(로컬 LLM 실행 도구) 등 제공사마다 다른 API 형식을 동일한 인터페이스 뒤로 숨긴다. 그 위에 Chains가 올라온다. LLM 호출 → 파싱 → 다음 호출로 이어지는 파이프라인을 선언적으로 정의할 수 있다. Memory는 대화 이력을 자동으로 수집하고 프롬프트에 주입한다. 최상위의 Agents + Tools는 LLM이 외부 세계와 상호작용하는 메커니즘을 담는다.
각 레이어는 독립적이다. Memory만 교체하거나, 모델만 바꾸거나, 도구만 추가할 수 있다. 나머지는 손대지 않아도 된다.
4. 핵심 설계 원칙 — 에이전트 루프
LangChain이 단순한 API 래퍼가 아닌 이유는 에이전트 루프(ReAct loop) 때문이다. ReAct는 "Reasoning + Acting"의 줄임말로, LLM이 생각하고 행동하는 사이클을 반복하는 패턴이다.
이 루프가 없으면 LLM은 질문에 한 번 답하고 끝난다. 루프가 있으면 LLM이 "검색이 더 필요하다", "계산이 필요하다"고 판단해 도구를 호출하고, 그 결과를 보고 다시 판단하는 과정을 반복한다.
이 순환 구조가 LangChain의 핵심이다. LLM이 "모르겠다, 검색해야겠다"고 판단하면 자동으로 검색 도구를 호출한다. 검색 결과를 받아 "아직 부족하다"고 판단하면 다시 루프를 돈다. "충분하다"고 판단하는 순간 루프를 탈출해 최종 답변을 만든다. 개발자는 이 루프의 흐름을 직접 코딩하지 않는다 — LangChain이 판단 기준(도구 목록, 종료 조건)만 설정하면 루프는 자동으로 작동한다.
함정 하나: 루프가 무한히 돌 수 있다. LLM이 충분하다고 판단을 못 내리거나, 도구가 계속 실패하면 루프는 멈추지 않는다. 그래서 LangChain은
max_iterations파라미터로 최대 반복 횟수를 설정할 수 있다. 프로덕션에서는 항상 설정해야 한다.단, 이 루프는 구조가 고정되어 있다. 단일 에이전트, 단선 루프다. '판단 → 도구 호출 → 결과 관찰 → 재판단'이라는 순서는 항상 같다. 결과에 따라 흐름이 갈라지거나, 에이전트 A가 에이전트 B에게 서브태스크를 위임하는 구조는 LangChain만으로는 표현할 수 없다. 도구를 병렬로 실행하거나, 조건에 따라 다른 경로로 분기하는 것도 마찬가지다. 이 고정된 구조가 LangChain의 경계다.
5. 효과 — 무엇이 달라졌는가
백 줄 넘던 보일러플레이트가 얼마나 줄어드는지 코드로 보자.
LangChain 이전 — 검색 기능 있는 챗봇 직접 구현
conversation_history = [] # 이력을 직접 관리해야 함 def chat(user_input: str) -> str: conversation_history.append({"role": "user", "content": user_input}) # 검색 필요 여부 판단 → 파싱 → 루프 제어 모두 직접 구현 reply = call_llm(conversation_history + [system_hint]) if reply.startswith("SEARCH:"): result = search_web(reply[7:].strip()) conversation_history.append({"role": "assistant", "content": result}) return chat(user_input) # 재귀로 루프 흉내 conversation_history.append({"role": "assistant", "content": reply}) return replyLangChain 사용 — 동일한 기능, 선언적으로
model = init_chat_model("gpt-4o-mini", model_provider="openai") tools = [TavilySearchResults(max_results=3)] # ReAct 루프, 이력 관리 자동 — 10줄 이하로 동일 기능 구현 agent = create_react_agent(model, tools) response = agent.invoke({"messages": [{"role": "user", "content": "오늘 날씨 알려줘"}]})전자는 50줄 이상이고, 루프 제어·파싱·이력 추가를 개발자가 직접 관리한다. 후자는 10줄이 안 되며, 루프와 이력은 프레임워크가 맡는다. 더 중요한 점은 모델 전환이다.
init_chat_model("gpt-4o-mini")를init_chat_model("claude-3-5-sonnet-20241022", model_provider="anthropic")으로 바꾸는 것만으로 Anthropic 모델로 전환된다. 나머지 코드는 손대지 않는다.아래는 LangChain 도입 전후의 구조적 차이를 나란히 비교한 것이다.
Before에서 개발자 코드가 모든 화살표의 출발점이었다면, After에서는 LangChain 프레임워크가 중간에서 조율한다. 개발자는 "무엇을 쓸지"만 선언하고, "어떻게 연결할지"는 프레임워크가 담당한다. 이 구조적 전환이 코드량 감소의 이유이자, 생태계 확장의 기반이 된다. 수천 개의 사전 구현 도구(Tool)가 이미 LangChain Hub에 등록되어 있고, 웬만한 벡터DB(Qdrant, Pinecone, Chroma 등)와 외부 서비스 연결도 import 한 줄로 해결된다.
6. 마무리 — 어디까지 왔고 어디로 가는가
LangChain이 해결한 4가지 패턴 — Model I/O, Chains, Memory, Agents — 은 각각 선형이다. Chains는 A → B → C 순서로 실행되고 분기가 없다. Agent의 ReAct 루프는 단일 에이전트가 반복할 뿐이다. 흐름이 갈라지거나, 여러 에이전트가 역할을 나눠 협업하는 구조는 LangChain의 범위 밖이다.
이 한계를 허문 것이 LangGraph다. LangGraph는 LangChain 위에 올라가는 별도 라이브러리로, 노드(에이전트·함수)와 엣지(전이 조건)로 워크플로우를 그래프로 정의한다. 조건 분기, 병렬 실행, 에이전트 간 위임, 체크포인트, 휴먼인더루프가 여기서 가능해진다. 챗봇 하나가 아니라, 리서치 에이전트·요약 에이전트·검토 에이전트가 협업하는 멀티 에이전트 시스템이 LangGraph로 돌아간다.
이 흐름을 보면 LangChain이 해결한 것은 단순히 "코드를 줄이는 것"이 아니었다. LLM을 신뢰할 수 있는 시스템의 한 부품으로 편입시키는 방법론을 만든 것이다. 어떤 도구를 쓰는가보다 더 중요한 질문은 이것이다 — "에이전트에게 무엇을 맡기고, 어떻게 신뢰할 것인가?"
LangChain은 그 질문에 대한 현재까지의 가장 잘 정돈된 대답이다. 완전한 대답은 아직 없다. 그래서 지금도 발전하고 있다.
이 글은 생성형 AI의 도움을 받아 작성되었습니다. 원본 자료를 기반으로 AI가 초안을 생성하고, 작성자가 검토·편집하였습니다.
'IT' 카테고리의 다른 글
Pydantic Field로 LLM 출력 스키마를 제약하는 방법 (0) 2026.06.23 ProviderStrategy vs ToolStrategy — 구조화 출력 전략 선택 (0) 2026.06.23 LangChain ToolRuntime으로 런타임 컨텍스트 주입하기 (0) 2026.06.23 LangChain @tool 데코레이터의 3요소 — 에이전트가 도구를 이해하는 방법 (0) 2026.06.22 LangChain이 LLM을 다루는 방식: 추상화, 팩토리, 체이닝 (0) 2026.06.22 JSON-RPC의 id는 누가 정하고 충돌하면 어떻게 되나 (0) 2026.06.21 서브에이전트를 200% 활용하는 노하우 — description부터 병렬 실행까지 (0) 2026.06.20 플러그인으로 서브에이전트 배포하기 — /plugin install부터 마켓플레이스까지 (0) 2026.06.19 서브에이전트를 GitHub로 배포하기 — 팀 공유부터 오픈소스까지 (0) 2026.06.19 서브에이전트를 어디에 두어야 하나 — 글로벌·프로젝트·플러그인 배치 전략 (0) 2026.06.19