작성자: Liam Bush
배경
모든 성공적인 플랫폼에는 신뢰할 수 있는 지원이 필요합니다. 하지만 우리는 팀원들이 기술 질문에 대한 답을 찾는 데 수시간을 소비하고 있다는 것을 깨달았습니다. 이러한 마찰은 단순히 엔지니어들의 속도를 늦추는 것이 아니라, 사용자들에게 심각한 병목 현상(bottleneck) 을 일으키고 있었습니다.
우리는 바로 우리가 옹호하는 도구들인 LangChain, LangGraph, LangSmith를 사용하여 이 문제를 해결하기로 했습니다. 원래 chat.langchain.com은 프로토타입으로 구축되었으며, 명시적으로 두 가지 기능을 제공하도록 설계되었습니다:
- 제품 Q&A: 사용자와 우리 팀이 제품 질문에 대한 즉각적이고 권위 있는 답변을 얻을 수 있도록 지원
- 고객 프로토타입: LangChain 스택을 사용하여 정교하고 신뢰할 수 있는 agent(에이전트)를 구축하는 방법을 보여주는 살아있는 예시로서의 역할
우리는 강력한 의도와 기능적인 제품을 가지고 있었습니다. 하지만 솔직히 고백하자면, 우리 지원 엔지니어들은 LangChain Chatbot을 적극적으로 사용하지 않고 있었습니다. 바로 여기서 진짜 배움이 시작되었습니다. 이것은 우리 자신의 agent(에이전트)를 어떻게 고쳤는지, 그리고 고객이 적용하고 사용할 수 있는 진정으로 신뢰할 수 있는 프로덕션급 애플리케이션을 구축하는 것에 대해 무엇을 배웠는지에 대한 이야기입니다.
우리 팀이 Chat LangChain을 적극적으로 사용하지 않은 이유는 제품이 망가져서도 아니고, 믿지 않아서도 아니었습니다. 하지만 누군가 “프로덕션에서 스트리밍이 작동하지 않는 이유가 뭔가요?” 라고 물었을 때, 문서만을 리소스로 사용하는 것보다 더 철저한 무언가가 필요했습니다. 우리 모두 알다시피 문서는 항상 부족합니다.
그래서 그들은 자신만의 워크플로우를 만들었습니다:
- 1단계: 우리 문서(docs.langchain.com)를 검색하여 기능이 무엇을 해야 하는지 이해합니다.
- 2단계: 우리 지식 베이스(support.langchain.com)를 확인하여 다른 사용자가 같은 문제를 겪었는지, 어떻게 해결되었는지 확인합니다.
- 3단계:
Claude Code를 열어 실제 구현을 검색하고, 코드가 실제로 무엇을 하는지 확인합니다.
공식 스토리를 위한 문서. 실제 문제를 위한 지식 베이스. 진실을 위한 코드베이스.
자동화하기로 결정
이 세 단계의 절차는 믿을 수 없을 정도로 잘 작동했습니다. 우리는 그들이 하루에 수십 번 이것을 하는 것을 보고 생각했습니다: 이 정확한 워크플로우를 자동화하면 어떨까?
그래서 우리는 세 개의 전문화된 subagent(서브에이전트)를 가진 내부 Deep Agent(복잡한 다단계 작업을 처리할 수 있는 agent(에이전트)를 구축하기 위한 라이브러리)를 구축했습니다. 하나는 문서용, 하나는 지식 베이스용, 하나는 코드베이스 검색용으로, 각각이 후속 질문을 하고 결과를 필터링한 후 인사이트를 메인 orchestrator agent(오케스트레이터 에이전트)에게 전달합니다.
메인 agent(에이전트)는 모든 것을 종합하여 다음과 같은 답변을 제공합니다:
출력 예시:
“subgraph(서브그래프)에서 streaming(스트리밍)하려면 LangGraph streaming 문서에 따라 stream 설정에서 subgraphs: true를 설정하세요. 이 정확한 문제를 설명하는 ‘Why is token streaming not working after upgrade’라는 제목의 지원 문서가 있습니다. 중첩된 agent(에이전트)에서 토큰 수준 업데이트를 받으려면 subgraph streaming을 활성화해야 합니다. 구현은 pregel/main.py 3373-3279번째 줄에 있으며, subgraphs 플래그가 중첩된 graph(그래프) 출력이 stream(스트림)에 포함되는지 여부를 제어합니다.”
우리 엔지니어들은 이것을 좋아했습니다.
복잡한 디버깅에서 매주 수 시간을 절약했습니다. 프로덕션 문제를 설명하면 문서를 인용하고, 알려진 솔루션을 참조하며, 중요한 정확한 코드 라인을 가리키는 포괄적인 답변을 받을 수 있었습니다.
그리고 깨달음이 찾아왔습니다
그러자 누군가 명백한 질문을 했습니다: 이것이 우리에게 이렇게 잘 작동한다면, 우리 공개 Chat LangChain은 왜 이런 방식으로 작동하지 않을까요?
합당한 지적이었습니다. 우리의 공개 도구는 문서를 조각으로 나누고, embedding(임베딩)을 생성하고, vector database(벡터 데이터베이스)에 저장하고 있었습니다. 문서가 업데이트될 때마다 끊임없이 재색인해야 했습니다. 사용자들은 답변을 받았지만, citation(인용)은 개선이 필요했고 context(컨텍스트)는 단편적이었습니다.
우리는 우연히 작동하는 것을 복사하는 것만으로 내부적으로 더 나은 것을 구축했습니다. 이제 공개 제품에도 같은 접근 방식을 적용할 때가 되었습니다.
재구축을 시작했을 때, 우리는 두 가지 광범위한 질문 카테고리에 의해 구동되는 두 가지 다른 아키텍처를 결합해야 한다는 것을 빠르게 깨달았습니다. 대부분의 질문은 문서와 지식 베이스를 사용하여 답변할 수 있었습니다. 나머지는 코드의 기반에 대한 분석이 필요했습니다.
새로운 Agent를 구축한 방법
간단한 문서용: Create Agent
우리는 chat.langchain.com의 기본 모드로 createAgent(langchain의 Agent 추상화)를 선택했는데, 속도 측면에서 가장 우수하기 때문입니다.
planning(계획) 단계도 없고, orchestration(오케스트레이션) 오버헤드도 없습니다. 즉각적인 tool call(도구 호출)과 답변만 있을 뿐입니다. agent(에이전트)는 문서를 검색하고, 필요한 경우 지식 베이스를 확인하며, 결과가 불명확한 경우 query(쿼리)를 개선하고, 답변을 반환합니다. 대부분의 문서 질문은 3-6번의 tool call(도구 호출) 로 처리할 수 있으며, Create Agent는 이를 몇 초 만에 실행합니다.
모델 옵션:
최종 사용자에게 여러 모델에 대한 액세스 권한을 제공합니다. Claude Haiku 4.5, GPT-4o Mini, GPT-4o-nano가 있으며, Haiku 4.5가 tool calling(도구 호출)에서 탁월하게 빠르면서도 강력한 정확도를 유지한다는 것을 발견했습니다. createAgent와 Haiku 4.5의 조합은 대부분의 query(쿼리)에 대해 15초 미만의 응답을 제공하며, 이는 정확히 문서 Q&A가 요구하는 것입니다.
최적화 방법:
우리는 LangSmith를 사용하여 모든 대화를 추적하고, agent(에이전트)가 불필요한 tool call(도구 호출)을 하는 위치를 식별하며, prompt(프롬프트)를 개선했습니다. 데이터는 agent(에이전트)에게 더 나은 후속 질문을 하도록 가르치면 대부분의 질문을 3-6번의 tool call(도구 호출)로 답변할 수 있음을 보여주었습니다. LangSmith의 평가 도구를 통해 다양한 prompting(프롬프팅) 전략을 A/B 테스트하고 속도와 정확도 모두에서 개선을 측정할 수 있었습니다.

이 30초 trace(추적)에는 7번의 tool call(도구 호출)이 포함됩니다: 4번의 문서 검색, 1번의 지식 베이스 문서 조회, 2번의 문서 읽기, 그리고 최종 응답을 streaming(스트리밍)하는 데 20초가 소요됩니다. 여기서 보기
코드를 사용한 답변용: Subgraph를 가진 Deep Agent
많은 질문들은 문서, 지식 베이스, 알려진 문제의 상호 참조를 리소스로 활용하는 것 외에도 구현 세부 사항을 확인하기 위해 코드베이스를 깊이 파고드는 검색이 필요했습니다.
아키텍처:
이러한 작업을 위해 전문화된 subgraph(서브그래프) 가 있는 Deep Agent를 구축했습니다: 하나는 문서 검색용, 하나는 지식 베이스 검색용, 하나는 코드베이스 검색용입니다.
각 subagent(서브에이전트)는 독립적으로 작동하며, 후속 질문을 하고, 정보를 필터링하고, 메인 orchestrator agent(오케스트레이터 에이전트)에게 전달하기 전에 가장 관련성 높은 인사이트만 추출합니다. 이는 각 도메인 전문가가 필요한 만큼 깊이 파고들 수 있도록 하면서 메인 agent(에이전트)가 context(컨텍스트)에 압도되는 것을 방지합니다.
코드베이스 검색의 이점:
코드베이스 검색 subagent(서브에이전트)는 특히 강력합니다. pattern matching(패턴 매칭)을 사용하여 우리의 private repository(프라이빗 리포지토리)를 검색하고, 파일 구조를 탐색하여 context(컨텍스트)를 이해하며, 라인 번호 정밀도로 특정 구현을 읽을 수 있습니다.
트레이드오프:
이 deep agent 아키텍처는 실행하는 데 더 오래 걸립니다. 복잡한 query(쿼리)의 경우 1-3분이 소요되지만, 그 철저함은 그만한 가치가 있습니다. 초기 응답이 핵심 질문을 다루지 못할 때 DeepAgent를 활용합니다.
면책 조항: 이 모드는 출시 시 일부 사용자에게만 활성화되며 며칠 내에 일반 공개될 예정입니다.
Vector Embedding에서 벗어난 이유
문서 검색에 대한 표준 접근 방식 — 문서를 조각으로 나누고, embedding(임베딩)을 생성하고, vector database(벡터 데이터베이스)에 저장하고, 유사성으로 검색 — 은 PDF와 같은 비구조화된 콘텐츠에는 잘 작동합니다. 하지만 구조화된 제품 문서의 경우 세 가지 문제에 계속 부딪혔습니다.
청킹은 구조를 파괴합니다. 문서를 500토큰 조각으로 나누면 헤더, 하위 섹션, context(컨텍스트)를 잃게 됩니다. agent(에이전트)는 왜 또는 언제인지 설명하지 않고 "set streaming=True"를 인용했습니다. 사용자는 필요한 것을 찾기 위해 페이지를 뒤져야 했습니다.
끊임없는 재색인. 우리 문서는 매일 여러 번 업데이트됩니다. 모든 변경 사항은 재청킹, 재임베딩, 재업로드를 의미했습니다. 이는 우리의 속도를 늦췄습니다.
모호한 인용. 사용자는 답변을 확인하거나 정보의 출처를 추적할 수 없었습니다.
돌파구는 우리가 잘못된 문제를 해결하고 있다는 것을 깨달은 것이었습니다. 문서는 이미 정리되어 있습니다. 지식 베이스는 이미 분류되어 있습니다. 코드베이스는 이미 탐색 가능합니다. 우리는 더 스마트한 retrieval(검색)이 필요한 것이 아니라 agent(에이전트)에게 그 기존 구조에 대한 직접 액세스를 제공해야 했습니다.
더 나은 접근 방식: 직접 API 액세스와 스마트 프롬프팅
청킹과 임베딩 대신, 우리는 agent(에이전트)에게 실제 것에 대한 직접 액세스를 제공했습니다. 문서의 경우 Mintlify의 API를 사용하며, 이는 모든 헤더, 하위 섹션, 코드 예제가 그대로 포함된 전체 페이지를 반환합니다. 지식 베이스의 경우 먼저 제목으로 지원 문서를 query(쿼리)한 다음, 가장 유망한 문서를 전체적으로 읽습니다. 코드베이스 검색의 경우 LangGraph Cloud deployment(배포)에 코드베이스를 업로드하고 pattern matching(패턴 매칭)에는 ripgrep을 사용하고, 구조 이해에는 디렉토리 탐색을 사용하며, 특정 구현 추출에는 파일 읽기를 사용합니다.
agent(에이전트)는 유사성 점수를 기반으로 검색하지 않습니다. 사람이 검색하는 것처럼 검색합니다 — 키워드, 개선, 후속 질문을 사용하여.
여기서 마법이 일어납니다. 우리는 agent(에이전트)에게 한 번 검색하고 찾은 것을 반환하라고만 말하지 않습니다. 충분한 정보를 가지고 있는지에 대해 비판적으로 생각하도록 prompt(프롬프트)합니다. 결과가 모호하거나 불완전한 경우 agent(에이전트)는 query(쿼리)를 개선하고 다시 검색합니다. 문서가 설명 없이 개념을 언급하는 경우 agent(에이전트)는 해당 개념을 구체적으로 검색합니다. 여러 해석이 가능한 경우 agent(에이전트)는 가장 관련성 높은 것으로 범위를 좁힙니다.
도구 설계: 인간 워크플로우를 위한 구축
우리는 retrieval(검색) 알고리즘이 작동하는 방식이 아니라 인간이 실제로 검색하는 방식을 반영하도록 도구를 설계했습니다.
문서 검색 도구는 Mintlify의 API를 query(쿼리)하고 완전한 페이지를 반환합니다. 누군가 streaming(스트리밍)에 대해 질문하면 agent(에이전트)는 다른 섹션의 세 개의 분리된 단락을 받는 것이 아니라, 사람이 읽는 것과 정확히 같이 구조화된 전체 streaming(스트리밍) 문서 페이지를 받습니다.
@tool
def SearchDocsByLangChain(query: str, page_size: int = 5, language: Optional[str] = None) -> str:
"""LangChain 문서 검색 via Mintlify API"""
params = {"query": query, "page_size": page_size}
if language:
params["language"] = language
response = requests.get(MINTLIFY_API_URL, params=params)
return _format_search_results(response.json())하지만 여기서 멈추지 않습니다. 초기 결과가 실제로 질문에 답하는지 평가하도록 agent(에이전트)에게 prompt(프롬프트)합니다. 이것이 올바른 섹션인가? 명확히 해야 할 관련 개념이 있는가? 더 구체적인 검색어가 더 나을까?
agent(에이전트)는 4-6번의 tool call(도구 호출) 예산을 가지고 있으며, 응답하기 전에 이해를 개선하기 위해 전략적으로 사용하도록 권장합니다.
실제로 어떻게 보이는지:
사용자가 “agent(에이전트)에 memory(메모리)를 추가하려면 어떻게 해야 하나요?” 라고 묻습니다.
agent(에이전트)는 "memory"를 검색하고 checkpointing(체크포인팅), 대화 기록, Store API를 다루는 결과를 얻습니다. 무작위로 하나를 선택하는 대신 agent(에이전트)는 질문이 모호하다는 것을 깨닫습니다 — memory(메모리)는 thread(스레드) 내 대화 상태 유지 또는 여러 대화에 걸친 사실 저장을 의미할 수 있습니다.
thread(스레드) 수준 persistence(영속성)의 범위를 좁히기 위해 "checkpointing"으로 다시 검색하고, 지원 문서 “How do I configure checkpointing in LangGraph?” 를 가져오며, 이것이 cross-thread memory(크로스 스레드 메모리)를 다루지 않는다는 것을 인식합니다.
그래서 공백을 채우기 위해 "store API"를 검색합니다.
최종 답변은 대화 기록을 위한 checkpointing(체크포인팅)과 장기 memory(메모리)를 위한 Store API를 모두 다루며, 사용된 지원 문서와 문서에 대한 정확한 citation(인용)을 제공합니다.
이 반복적인 검색 프로세스는 Create Agent로 몇 초 만에 이루어지지만, 응답의 품질을 근본적으로 변화시킵니다. agent(에이전트)는 단순히 검색하는 것이 아니라 사용자가 실제로 필요로 하는 것에 대해 reasoning(추론)하고 있습니다.
우리는 지식 베이스(Pylon 기반) 검색을 2단계 프로세스로 구축했는데, 이는 사람들이 지식 베이스를 사용하는 방식이기 때문입니다.
먼저 agent(에이전트)는 문서 제목을 검색합니다 — 때로는 수십 개 — 그리고 관련성이 있어 보이는 것을 식별하기 위해 스캔합니다. 그런 다음 해당 문서만 전체적으로 읽습니다.
@tool
def search_support_articles(collections: str = "all", limit: int = 50) -> str:
"""1단계: 스캔할 문서 제목 가져오기"""
articles = pylon_client.list_articles(collections=collections, limit=limit)
return json.dumps([{
"id": a["id"],
"title": a["title"],
"url": a["url"]
} for a in articles])
@tool
def get_article_content(article_ids: List[str]) -> str:
"""2단계: 가장 관련성 높은 문서 읽기"""
articles = pylon_client.get_articles(article_ids)
return "\\n\\n---\\n\\n".join([
f"# {a['title']}\\n\\n{a['content']}\\n\\nSource: {a['url']}"
for a in articles
])이것이 작동하는 이유:
이는 agent(에이전트)가 정보에 압도되는 것을 방지합니다. 30개의 전체 문서를 context window(컨텍스트 윈도우)에 전달하는 대신, agent(에이전트)는 실제로 중요한 2-3개로 필터링하고, 철저히 읽고, 핵심 인사이트를 추출합니다.
prompting(프롬프팅)은 이를 강화합니다: 양보다 질에 집중하고, 필요한 경우 검색 범위를 좁히고, 질문에 직접 답하는 정보만 반환하십시오.
여기서 우리의 Deep Agent가 빛을 발합니다.
우리는 agent(에이전트)에게 오프닝의 워크플로우를 반영하는 세 가지 도구를 제공했습니다 — 우리 엔지니어들이 Claude Code를 사용할 때 따르는 것과 같은 패턴:
@tool
def search_public_code(pattern: str, path: Optional[str] = None) -> str:
"""1단계: 패턴과 일치하는 코드 찾기"""
cmd = ["rg", pattern, str(path or search_path)]
return subprocess.run(cmd, capture_output=True, text=True).stdout
@tool
def list_public_directory(path: str, max_depth: int = 2) -> str:
"""2단계: 파일 구조 이해하기"""
cmd = ["tree", "-L", str(max_depth), str(path)]
return subprocess.run(cmd, capture_output=True, text=True).stdout
@tool
def read_public_file(file_path: str, start_line: int = 1, num_lines: int = 100) -> str:
"""3단계: 실제 구현 읽기"""
with open(file_path, "r") as f:
lines = f.readlines()
return "\\n".join(lines[start_line-1:start_line-1+num_lines])작동 방식:
먼저 ripgrep을 사용하여 코드베이스에서 패턴을 검색합니다. 그런 다음 파일이 어떻게 구성되어 있는지 이해하기 위해 디렉토리 구조를 나열합니다. 마지막으로 관련 섹션에 집중하여 특정 파일을 읽고, 라인 번호와 함께 구현을 반환합니다.
실제 사례:
사용자가 프로덕션에서 streaming(스트리밍) 토큰이 중단된다고 보고합니다. 문서 subagent(서브에이전트)는 streaming(스트리밍) 설정이 buffer(버퍼) 설정과 관련이 있다는 것을 발견합니다. 지식 베이스 subagent(서브에이전트)는 업그레이드 후 token streaming(토큰 스트리밍) 문제에 대한 지원 문서를 찾아냅니다.
하지만 실제 구현을 찾는 것은 코드베이스 subagent(서브에이전트)입니다 — "streaming buffer"를 검색하고, callbacks/streaming.py로 이동하여, 기본 buffer(버퍼) 크기가 하드코딩된 47-83번째 줄을 반환합니다.
이것이 실제 문제를 해결하는 종류의 깊은 조사입니다.
차이점은? Deep Agent는 세 가지 도메인 모두에서 병렬로 작업할 수 있으며, 중간 발견 사항을 하나의 일관된 답변으로 요약합니다.
Deep Agent와 Subgraph가 Context 과부하를 해결하는 방법
세 가지 도구 모두에 액세스할 수 있는 단일 시스템으로 deep agent를 처음 구축했을 때, 찾은 모든 것을 반환했습니다. 메인 agent(에이전트)는 다섯 개의 문서 페이지, 열두 개의 지식 베이스 문서, 스무 개의 코드 스니펫을 한 번에 받았습니다.
context window(컨텍스트 윈도우)가 폭발했고, 최종 응답은 관련 없는 세부 사항으로 부풀어 오르거나 핵심 인사이트를 완전히 놓쳤습니다.
그때 우리는 전문화된 subgraph(서브그래프)로 재구성했습니다.
작동 방식:
각 subagent(서브에이전트)는 독립적으로 작동합니다. 도메인을 검색하고, 모호성을 명확히 하기 위해 후속 질문을 하고, 결과를 필터링하며, 핵심 데이터만 추출합니다: 질문에 답하는 데 필요한 필수 사실, citation(인용), context(컨텍스트).
메인 orchestrator agent(오케스트레이터 에이전트)는 원시 검색 결과를 절대 보지 못합니다. 각 도메인 전문가로부터 개선된 인사이트만 받습니다. 여기에서 전체 trace와 프롬프트를 보세요.
이것이 중요한 이유:
문서 subagent(서브에이전트)는 다섯 개의 전체 페이지를 읽을 수 있지만 두 개의 핵심 단락만 반환합니다. 지식 베이스 subagent(서브에이전트)는 스무 개의 문서 제목을 스캔할 수 있지만 세 개의 관련 요약만 반환합니다. 코드베이스 subagent(서브에이전트)는 오십 개의 파일을 검색할 수 있지만 라인 번호가 있는 특정 구현만 반환합니다.
메인 agent(에이전트)는 포괄적인 답변으로 종합할 수 있는 깨끗하고 큐레이션된 정보를 얻습니다.
프로덕션 준비 완료
우아한 agent(에이전트) 설계조차도 실제 사용자와의 접촉에서 살아남으려면 프로덕션 인프라가 필요합니다. 우리는 그렇지 않으면 prompt(프롬프트)를 어지럽힐 운영상의 우려 사항을 처리하기 위해 모듈식 middleware(미들웨어)를 구축했습니다.
middleware = [
guardrails_middleware, # 주제를 벗어난 query(쿼리) 필터링
model_retry_middleware, # API 실패 시 재시도
model_fallback_middleware, # 필요한 경우 모델 전환
anthropic_cache_middleware # 비용 절감을 위해 비용이 많이 드는 호출 캐시
]각 레이어가 하는 일:
Guardrail(가드레일) 은 주제를 벗어난 query(쿼리)를 필터링하여 agent(에이전트)가 LangChain 질문에 집중하도록 합니다.
Retry middleware(재시도 미들웨어) 는 일시적인 API 실패를 우아하게 처리하므로 사용자는 암호 같은 오류 메시지를 보지 않습니다.
Fallback middleware(폴백 미들웨어) 는 모델을 사용할 수 없는 경우 Haiku, GPT-4o Mini, Gemini Nano 간에 전환합니다.
Caching(캐싱) 은 동일한 query(쿼리)에 대한 결과를 재사용하여 비용을 절감합니다.
이러한 레이어는 사용자에게 보이지 않지만 안정성에 필수적입니다. 인프라가 실패 모드, 비용 최적화, 품질 관리를 처리하는 동안 agent(에이전트)가 reasoning(추론)에 집중할 수 있게 해줍니다.
Agent를 사용자에게 제공하기
훌륭한 agent(에이전트)를 구축하는 것은 전투의 절반에 불과합니다. 나머지 절반은? 빠르고 지능적으로 느껴지는 방식으로 사용자에게 제공하는 것입니다.
우리는 LangGraph SDK를 사용하여 streaming(스트리밍)과 state(상태) 관리의 모든 복잡성을 처리합니다.
누군가 Chat LangChain을 열면 LangGraph SDK를 사용하여 대화 기록을 가져옵니다:
const userThreads = await client.threads.search({
metadata: { user_id: userId },
limit: THREAD_FETCH_LIMIT,
})모든 thread(스레드)는 metadata(메타데이터)에 사용자 ID를 저장하므로 대화는 세션 간에 비공개이며 지속됩니다. LangGraph SDK는 필터링을 자동으로 처리합니다.
실시간 응답 스트리밍:
사용자가 메시지를 보내면 LangGraph SDK는 생성되는 대로 응답을 stream(스트림)합니다:
const streamResponse = client.runs.stream(threadId, "docs_agent", {
input: { messages: [{ role: "user", content: userMessage }] },
streamMode: ["values", "updates", "messages"],
streamSubgraphs: true,
})
for await (const chunk of streamResponse) {
if (chunk.event === "messages/partial") {
setMessages(prev => updateWithPartialContent(chunk.data.content))
}
}사용자가 보는 것:
세 가지 stream(스트림) 모드가 agent(에이전트)의 전체 사고 프로세스를 보여줍니다:
messages— agent(에이전트)가 작성하는 동안 토큰이 점진적으로 나타남updates— tool call(도구 호출)이 agent(에이전트)가 검색하는 것을 보여줌values— 처리 후 최종 완전한 state(상태)
사용자는 agent(에이전트)가 생각하고, 문서를 검색하고, 지식 베이스를 확인하고, 토큰별로 응답을 구축하는 것을 지켜봅니다. 로딩 스피너가 없습니다.
대화 메모리
메시지 간에 동일한 thread_id를 전달하면 LangGraph의 checkpointer(체크포인터)가 나머지를 처리합니다. 대화 기록을 저장하고, 각 턴에 대한 context(컨텍스트)를 검색하며, 세션 간 state(상태)를 유지합니다. 우리는 7일 TTL을 설정합니다. 그게 전부입니다.
결과
새로운 시스템을 출시한 이후 극적인 개선을 보았습니다.
공개 Chat LangChain의 경우 사용자는 정확한 citation(인용)과 함께 15초 미만의 응답을 받습니다. 관련 문서 페이지나 지식 베이스 문서에 직접 링크하기 때문에 즉시 답변을 확인할 수 있습니다. 그리고 더 이상 재색인에 수 시간을 소비하지 않습니다 — 문서가 자동으로 업데이트됩니다.
내부적으로 우리 지원 엔지니어들은 가장 복잡한 티켓을 처리하기 위해 Deep Agent를 사용합니다. 문서를 검색하고, 알려진 문제를 상호 참조하며, private codebase(프라이빗 코드베이스)를 파고들어 실제로 무슨 일이 일어나고 있는지 설명하는 구현 세부 사항을 찾습니다. agent(에이전트)는 엔지니어를 대체하지 않습니다 — 증폭시킵니다, 연구를 처리하여 문제 해결에 집중할 수 있게 합니다.
핵심 교훈
- 사용자의 워크플로우를 따르세요: 바퀴를 재발명하지 마세요. 최고의 사용자(또는 내부 전문가)가 이미 사용하고 있는 성공적인 워크플로우를 자동화하세요. LangChain의 경우 문서, 지식 베이스, 코드베이스를 확인하는 3단계 절차를 복제하는 것을 의미했습니다.
- Vector Embedding이 적절한지 평가하세요: 제품 문서 및 코드와 같은 구조화된 콘텐츠의 경우 vector embedding(벡터 임베딩)을 사용하면 문서 구조가 깨지고, citation(인용)이 모호해지며, 끊임없는 재색인이 필요할 수 있습니다. vector embedding(벡터 임베딩)은 비구조화된 콘텐츠나 더 짧은 블록 또는 clustering(클러스터링) 사용 사례에 환상적입니다.
- Agent에게 구조에 대한 직접 액세스를 제공하세요: 이 접근 방식은 agent(에이전트)가 콘텐츠의 기존 구조에 대한 직접 API 액세스를 허용합니다. 이를 통해 agent(에이전트)는 키워드와 개선을 사용하여 사람처럼 검색할 수 있습니다.
- Retrieval보다 Reasoning을 우선시하세요: 인간 워크플로우를 반영하도록 도구를 설계하세요: 문서 제목을 스캔한 다음 콘텐츠를 읽고, 코드에 pattern matching(패턴 매칭)과 디렉토리 탐색을 사용하세요. 초기 결과가 모호한 경우 agent(에이전트)가 후속 질문을 하고 query(쿼리)를 개선하도록 prompt(프롬프트)하여, 최종 답변이 사용자의 실제 필요를 다루도록 보장하세요.
- Context를 관리하기 위해 Deep Agent와 Subgraph를 사용하세요: 복잡한 다중 도메인 질문의 경우 전문화된 **subgraph(서브그래프)**가 있는 Deep Agent를 사용하면 메인 orchestrator agent(오케스트레이터 에이전트)가 원시 검색 결과에 압도되는 것을 방지합니다. 각 subagent(서브에이전트)는 개선된 인사이트를 전달하기 전에 도메인에서 “핵심 데이터”만 필터링하고 추출합니다.
- 프로덕션 Middleware의 필요성: 우아한 agent(에이전트) 설계조차도 안정적이려면 강력한 인프라가 필요합니다. guardrail(가드레일)(주제를 벗어난 query(쿼리) 필터링), retry(재시도)(API 실패 시), fallback(폴백)(모델 전환), **caching(캐싱)**을 위한 모듈식 middleware(미들웨어) 구현은 프로덕션급 안정성, 비용 최적화, 품질 관리에 필수적입니다.
다음 단계
공개 코드베이스 검색(며칠 내 출시) — 문서와 지식 베이스가 충분하지 않을 때, agent(에이전트)는 구현을 확인하고 정확한 라인 번호를 인용하기 위해 공개 repository(리포지토리)를 검색합니다.
직접 시도해 보세요
Chat LangChain은 chat.langchain.com에서 사용할 수 있습니다. 가장 빠른 응답을 위해 Claude Haiku 4.5로 시도하거나, GPT-4o Mini 및 GPT-4o Nano로 실험하여 다양한 모델의 성능을 확인하세요.
대화에 참여하세요
속도와 깊이의 균형을 맞추는 agent(에이전트)를 구축하는 것은 어렵고, 우리는 여전히 배우고 있습니다. 유사한 문제를 해결하고 있다면 여러분이 발견한 것을 듣고 싶습니다.
포럼에서 LangChain 커뮤니티에 참여하거나 Twitter에서 팔로우하세요.
팀과 커뮤니티의 업데이트를 받으려면 뉴스레터를 구독하세요.