튜토리얼은 따라가는데 혼자 설계하려면 손이 멈추는 이유
AI 개발자에 입문하면 가장 많이 듣는 툴, LangChain.
LangChain 공식 튜토리얼을 보면 에이전트를 만드는 건 생각보다 쉬워 보인다.
Tool 붙이고,
Memory 추가하고,
Agent를 하나 선언하면 끝이다.
그런데 막상 내 문제를 풀어보려고 하면 손이 멈춘다.
“뭐부터 해야 하지?”
이 글은 에이전트가 무엇인지 설명하려는 글이 아니다.
왜 혼자 설계하려고 하면 항상 구조에서 막히는지
그 이유를 지금 시점의 나 기준으로 정리해본 글이다.
(2026-08 업데이트 — 실제로 막혔던 순환 구조 사례와, 6개월 뒤 달라진 결론을 추가했다.)

튜토리얼은 되는데, 혼자서는 안 되는 이유
생각해보면 간단하다.
튜토리얼에는 항상 ->
- 문제 정의가 이미 되어 있고
- Tool의 역할이 정해져 있으며
- Agent가 무엇을 해야 하는지도 명확하다.
하지만 실무에서는 이 중 어느 하나도 정해져 있지 않다.
그래서 나는 Agent를 만드는 단계가 아닌 “문제를 쪼개는 단계”에서 계속 멈췄다.
실제로 막힌 지점: 순환 구조
당시 만들던 건 챗봇 에이전트였다.
LangChain으로 노드를 구성하다가, 정확히는 순환 구조에서 막혔다.
입력을 분류하고, 도구를 부르고, 결과를 검증한다 — 여기까지는 그럭저럭 흘러갔다.
문제는 검증이 실패했을 때였다.
이럴 땐 뭘 다시 불러야 하지?
같은 노드를 몇 번까지 돌려도 되지?
후보가 여럿이면 우선순위는 어떻게 주지?
이런 걸 먼저 설계하고 코드를 짰어야 했는데, 나는 무작정 만들었다.
# 당시 구조를 재현하면 이런 모양이었다 (의사코드)
graph.add_node("classify", classify_intent) # 입력 분류
graph.add_node("call_tool", run_tool) # 도구 실행
graph.add_node("validate", validate_result) # 결과 검증
graph.add_edge("classify", "call_tool")
graph.add_edge("call_tool", "validate")
# 문제의 지점: 검증에 실패하면 어디로 돌아가야 하나?
graph.add_conditional_edges("validate", route_on_failure)
# route_on_failure 안에서 답해야 했던 질문들:
# - 다시 부를 노드는? (classify? call_tool?)
# - 같은 노드를 몇 번까지 다시 돌려도 되나?
# - 후보가 여럿이면 우선순위는 누가 정하나?
돌이켜보면 LangChain이 어려웠던 게 아니다.
그래프에 순환이 생기는 순간 따라오는 설계 — 종료 조건, 재진입 규칙, 우선순위 — 를 하나도 정하지 않았던 거다.
LLM과 Agent를 같은 것으로 착각했다
입사 초반에는 LLM이 똑똑하면 Agent도 알아서 잘 돌아갈 거라 생각했다.
사실 지금도 LLM과 Agent를 혼동해서 쓰는 경우를 많이 봤다.
그만큼 급격하게 바뀌는 환경이기도 하고,
개념들이 서로 겹쳐 보이기 때문이라고 생각한다. (머신러닝 안에 딥러닝, 그 안에 AI처럼)
정리하면 LLM은 질문에 답하는 역할에 가깝고 Agent는 일을 나누고 흐름을 관리하는 구조에 가깝다.
이 둘을 구분하지 못하면 계속 “왜 얘가 이걸 했지?” 같은 상황이 반복된다.
Tool / Memory / Planner를 다시 정의해보니
이걸 문서 기준이 아니라 내가 실제로 쓰면서 이해한 기준으로 정리해보면 이렇다.
- Tool: 기능 목록이 아니라 선택 가능한 행동들
- Memory: 로그가 아니라 맥락을 유지하기 위한 장치
- Planner: 마법이 아니라 분기 기준
이렇게 나누고 나니 Agent를 “한 덩어리”가 아니라 역할이 있는 구성 요소로 보기 시작했다.

내가 진짜로 몰랐던 건 ‘구조를 나누는 기준’이었다
지금 돌아보면 Agent가 어려웠던 이유는 기술이 아니라 설계 기준이 없었기 때문이다.
- 이 판단은 LLM이 해야 할까?
- 아니면 코드로 분리해야 할까?
- 이 상태는 Memory에 남겨야 할까?
이제 에이전트를 개발하기 전에 항상 이 질문을 던진다.
무작정 만드는 것이 아니라 만들기 전에도, 만들면서도, 다 만들고 QA를 진행할 때도 항상 고민하는 부분이다.
그래야 내가 만들려고 하는 진정한 의미의 에이전트 구현이기 때문이다.
실제로 에이전트를 만들 때 이 질문을 가지고 시작한다면 설계가 훨씬 수월해 질 것이다.
지금 시점에서 정리한 최소 Agent 구조
아직 완벽하진 않지만 나는 Agent를 이렇게 나눈다.
- LLM: 판단 담당
- Tool: 실행 담당
- Memory: 상태 유지
- Orchestrator: 흐름 제어 (실제로는 코드일 수도 있고, LangChain 내부 로직일 수도 있다)
이 정도만 명확해져도 혼자서 구조를 잡는 데 큰 도움이 된다.
이전에는 “왜 안 되지?”였다면
지금은 “어디서 나눠야 하지?”를 먼저 본다.
(2026-08 업데이트) 그 후 6개월: 순환 대신 순차
이 글을 쓰고 6개월이 지났다.
LangChain은 지금도 챗봇에 쓰고 있다.
달라진 건 구조다.
지금은 순환 그래프 대신 순차 배열을 주로 쓴다.
분류 → 검색 → 생성 → 검증처럼, 노드를 한 방향으로만 흐르게 놓는다.
돌아보면 순환이 필요해 보였던 지점의 대부분은 “재시도”였고, 재시도는 그래프의 순환이 아니라 노드 안의 루프로 충분했다.
바꾸고 나서 얻은 건 셋이다.
첫째, 흐름이 결정론적이라 디버깅이 쉽다 — 어떤 입력이 와도 노드 방문 순서가 같아서, 로그만 보면 어디서 틀어졌는지 보인다.
둘째, 종료 조건을 고민할 필요가 없다 — 끝까지 가면 끝난다.
셋째, 우선순위 문제가 사라진다 — 배열의 순서가 곧 답이다.
이 관점은 이후 글들에서 더 밀고 나갔다.
흐름 제어는 LLM의 판단이 아니라 코드의 영역이라는 결론은 Orchestrator는 Agent가 아니다에, 도구를 열어줄 때의 기준은 Tool을 열어줄 때 내가 세운 3가지 원칙에 정리했다.
6개월 전의 나에게 한 줄만 남긴다면 이거다.
“순환 그래프를 그리기 전에, 순차로 풀 수 없는지부터 물어라.”
마무리하며
이 글은 정답을 정리한 글이 아니다. (사실 첫 글이라 떨린다)
지금 시점의 내가 어디까지 이해했는지를 기록한 글이다.
나중에 다시 읽었을 때
“아, 이때는 여기까지 왔었구나”라고 느낄 수 있다면 좋겠다.

함께 읽으면 좋은 글
글쓴이 · Plutojoshua
핀테크에서 LLM과 AI 에이전트를 실제 서비스에 적용하는 개발자다. 카카오 AI 앰배서더로 Kanana 모델을 앱에 직접 연동해 검증하고, 비전공자로 시작해 실제 코드와 측정값을 근거로 “왜 그렇게 설계했는지”를 1인칭으로 기록한다. 운영자 소개는 About, 코드는 GitHub에서 볼 수 있다.
“LangChain으로 Agent를 만들 때, 왜 항상 ‘구조’에서 막힐까”에 대한 2개의 생각