많은 에이전트 튜토리얼들이 프레임워크 임포트(import)부터 시작합니다. 저는 모델을 호출하고, 구조화된 데이터를 반환하며, 도구를 순서대로 호출하는 일반 함수로 시작할 것을 권장합니다. 이 과정은 위에서 아래로 읽을 수 있는 순서여야 합니다. 단일 모델 호출만으로는 제품 전체가 되는 경우는 드뭅니다. 복합 AI 시스템 (compound AI system)은 모델 호출, 검색(retrieval), 도구(tools), 검증(validation), 제어 로직을 하나의 파이프라인으로 연결하며, 그 품질은 어떤 모델을 선택했는지만큼이나 이 조각들이 어떻게 잘 맞물리는지에 달려 있습니다.
프레임워크는 오케스트레이션(orchestration)과 상태 관리(state management)가 여러분의 에이전트가 이미 가지고 있는 문제를 해결할 때 빛을 발합니다. 그러한 문제가 발생하기 전까지는, 의존성(dependency)이 테스트해야 할 부분을 숨길 수 있으며, 특히 모델에 공급하는 데이터도 마찬가지입니다.
순수 함수로 먼저 시작해야 하는 이유?
함수는 워크플로우의 명확한 지도를 제공합니다. 무엇이 실행되는지, 어떤 순서로 실행되는지, 그리고 다음 단계로 무엇이 전달되는지를 알 수 있습니다. 분기(branching)는 명시적으로 유지됩니다. 여러분이 소유하는 경계(boundary)에서 입력과 출력을 기록할 수 있습니다. 무언가 실패했을 때, 오류는 여러분이 작성하고 읽을 수 있는 코드 내에서 표면화됩니다.
구조화된 출력 (Structured output)이 핵심입니다. 모델은 기본적으로 자유 텍스트(free text)를 방출하는데, 이는 인간에게는 괜찮지만 프로그램에는 취약합니다. 다음 단계가 코드 추출, 티켓 분류 또는 도구 이름 및 인자 선택과 같이 코드를 필요로 하는 경우, 스키마에 맞는 JSON을 요청해야 합니다. 항상 동일한 필드가 필요한 경우, 강제된 스키마(enforced schemas)가 느슨한 JSON 모드보다 우수합니다. 여전히 값은 검증하고 거부되거나 잘린 응답(truncated responses)을 처리해야 합니다.
아래는 프로덕션 코드는 아니지만 개요입니다. 스키마를 가진 하나의 계획 단계와 결정론적 도구 실행을 보여줍니다.
# Sketch: agent as functions + structured outputs (not production code)
from typing import Literal, Optional
from pydantic import BaseModel
...
이 루프는 프레임워크가 필요하지 않습니다. 검색(retrieval), 추가 모델 패스(model passes), 검사 등을 더 많은 함수로 추가하세요. 여러분은 복합 파이프라인을 직접 조립하고 있는 것입니다.
언제 프레임워크를 사용해야 한다는 신호가 나타날까요?
동일한 워크플로우를 작은 직접 빌드(direct build)와 비교해 보세요. 에이전트 프레임워크가 가치를 더하는 지점은 에이전트가 실제로 겪는 문제들을 중심으로 결정을 내리도록 합니다.
다음 사항들을 업그레이드 신호로 간주하세요:
-
실패 시 디버깅 용이성(Debuggability under failure). 에이전트가 오작동할 때, 탐색(spelunking) 없이 도구 호출과 애플리케이션 상태를 검사할 수 있습니까? 그렇지 않고 실패가 흔하다면, 실행 추적(run traces) 및 영속화된 단계 기록(persisted step records)이 의존성 도입을 정당화할 수 있습니다.
-
중단된 작업(Interrupted work). 부작용(side effect)(이메일 전송, 카드 청구, 행 작성 등)을 다시 수행하지 않고 장기 작업을 재개할 수 있습니까? 사용자나 워크플로우가 내구성 있는 체크포인트(durable checkpoints)를 필요로 한다면, 프레임워크가 제공할 수 있는 상태 관리 및 재생 의미론(state management and replay semantics)을 찾고 있는 것입니다.
-
분기 및 조정(Branching and coordination). 제어 흐름이 직선처럼 보이지 않고 병렬 분기, 인간 승인, 또는 하위 에이전트 간의 핸드오프처럼 보이기 시작한다면, 오케스트레이션 원시 요소(orchestration primitives)가 여러분이 지치게 관리하는 임시 상태 기계(ad hoc state machines)를 대체합니다.
-
검색 반복(Retrieval iteration). 컨텍스트를 가져오는 방식과 답변을 평가하는 방식을 프레임워크의 추상화와 싸우지 않고 변경할 수 있습니까? 실험이 느리다면, 스택을 단순화하거나 검색을 플러그인 방식으로 처리하는 도구를 선택해야 합니다.
Jerry Liu는 LlamaIndex의 공동 창업자이며, 에이전트 패턴이 성숙함에 따라 안정적인 추상화(stable abstractions)가 프로덕션 컨텍스트를 통해 차별화할 여지를 더 많이 남긴다고 주장해 왔습니다. 이것이 그의 회사가 투자하기로 결정한 부분입니다. 그는 애플리케이션 형태가 개방되어 있을 때 프레임워크 계층에서 여전히 가치를 발견합니다:
같은 에피소드에서 그는 그 변화를 컨텍스트 작업에 연결합니다:
추상화가 확고해지고 있었지만, 고품질의 프로덕션 컨텍스트에 대한 필요는 여전히 진화하고 있었습니다.
Jerry Liu, LlamaIndex, Chain of Thought 에피소드 61
각 프레임워크 기능은 무엇을 대체하는가?
현재 느끼고 있는 문제점과 기능을 매핑해 보세요. 제가 직접 구현한 버전(hand-rolled version)을 프레임워크가 제공할 수 있는 것과 비교하여 정리해 보겠습니다. 중단 및 재개: 사용자 정의 작업 ID,멱등성 도구(idempotent tools), 그리고 한쪽의 단계 테이블 vs 중앙 집중식 실행 상태, 체크포인트, 리플레이를 다른 쪽. 복잡한 분기 처리: 중첩된 조건문과 수동으로 작성한 상태 기계(state machines) 대 그래프 또는 워크플로우 원시 요소(primitives). 도구 연결 구조(Tool plumbing): 제공업체별 래퍼와 인자 구문 분석 vs 레지스트리 및 호출 규칙. 관찰 가능성 격차(Observability gaps): 산발적인 로깅 vs 도구 호출에 연결된 추적(traces).
만약 직접 구현한 방식이 여전히 팀에게 저렴하다면, 프레임워크가 스스로 비용을 정당화하지 못할 수도 있습니다. 간단한 워크플로우는 오케스트레이션이 거의 필요하지 않을 수 있습니다. 복잡한 워크플로우는 프레임워크의 이점을 누릴 수 있습니다. 어느 쪽 선택도 모델에 제공되는 컨텍스트를 테스트해야 할 필요성을 없애지는 않습니다.
실질적인 방법은 그 논쟁에서 나온 검사 질문들, 즉 도구 호출 및 실패 시 상태, 반복적인 작업 없이 재개 가능 여부, 분기 처리가 단순해졌는지 여부, 그리고 검색 변경 사항을 쉽게 평가할 수 있는지 등을 사용하여 두 빌드를 동일한 워크플로우로 비교하는 것입니다.
에이전트 아키텍처, 메모리, 컨텍스트를 해자(moat)로 삼는 것에 대해 더 알고 싶다면, AI 에이전트에 대한 최고의 Chain of Thought 에피소드 컬렉션은 한 프레임워크 창업가 외의 목소리를 원할 때 유용한 대체 자료 모음입니다.
공정하게 비교하려면 어떻게 해야 하는가?
워크플로우의 가장 작은 버전을 두 번 만드세요. 한 번은 함수와 구조화된 출력(structured outputs)을 사용해서, 다른 한 번은 고려 중인 프레임워크를 사용해서 만드는 겁니다. 도구(tools), 검색(retrieval), 평가 데이터셋(eval set)은 동일하게 사용하세요. 네 가지 검사 질문(inspection questions)을 두 경로 모두에 대해 실행해 보세요. 저장된 구현 시간(saved implementation time)이 오직 추적 가능성(inspectability), 재개 가능한 동작(resume behavior), 또는 일반 코드로는 명확히 유지할 수 없었던 조정(coordination)을 얻는 경우에만 의존성을 정당화하도록 하세요.
단지 에이전트 루프가 추상적으로 개선되었다고 해서 프레임워크를 채택하지 마세요. 여러분의 코드베이스 자체가 그 프레임워크가 되려고 노력하고 있을 때 채택하세요.
체크리스트
- 오케스트레이션 의존성(orchestration dependencies)을 추가하기 전에, 함수, 명시적 제어 흐름(explicit control flow), 스키마에 바인딩된 모델 출력(schema-bound model outputs)으로 시작하세요.
- 에이전트를 복합 파이프라인(compound pipeline)으로 취급하세요. 모델 단계, 검색, 도구, 검증, 그리고 접착 코드(glue code)가 품질의 소유권을 공유합니다.
- 현재 구조가 허용하는 것보다 더 추적 가능한 실패(inspectable failures), 재개 가능한 실행(resumable runs), 무거운 분기 처리(heavy branching), 또는 빠른 검색 실험이 필요할 때 프레임워크를 찾으세요.
- 각 프레임워크 기능은 랜딩 페이지의 기능 매트릭스에 연결하는 것이 아니라, 오늘날 유지 관리하고 있는 코드와 연결하세요.
- 커밋하기 전에 동일한 워크플로우와 동일한 평가 데이터로 직접 구현(direct implementations)과 프레임워크 구현을 비교해 보세요。
더 긴 설명은 에피소드 클립과 함께 Chain of Thought에서 확인할 수 있습니다. 이 글은 이 에피소드를 기반으로 작성되었습니다.
에피소드 스크립트에서 AI의 도움을 받아 초안 작성됨.