Skip to content

다 만들고 나니 이미 있는 것들이 보였다 ​

여기까지 만들고 나서 가장 먼저 든 생각은 조금 허무한 쪽이었다.

"이거 이미 다 있는 거 아닌가?"

세션도 있고, 메모리도 있고, 도구 호출도 있고, 체크포인트도 있고, 재개도 있고, 사람 승인도 있고, 관측 기능도 있는 프레임워크가 이미 많았다.

나는 그것들을 몰라서 새로 만든 걸까.

한동안 이 질문을 계속 했다.

기능 목록만 보면 새로울 게 없었다 ​

내가 필요해서 하나씩 붙인 것을 적어보면 대략 이렇다.

text
Session
Persistence
Memory
Search
Context Compression
Tool Loop
Streaming
Cancellation
Idempotency
Resume
Telemetry
Dataset

검색해 보면 각각을 지원하는 라이브러리와 프레임워크가 나온다.

어떤 것은 이 목록보다 훨씬 많은 기능을 가지고 있다.

그래서 기능 개수만 비교하면 직접 만든 이유가 약해 보였다.

처음부터 잘 찾아봤다면 프레임워크 하나 가져와서 끝낼 수도 있었던 것 아닐까 싶었다.

그런데 과정을 다시 생각해 보니 출발점이 조금 달랐다.

나는 에이전트 프레임워크를 만들려고 시작하지 않았다 ​

처음 질문은 이것이었다.

text
잘 돌아가는 코딩 에이전트에서
코딩에 해당하는 부분을 걷어내면
일반 업무에도 쓸 수 있지 않을까?

그래서 기능 목록을 먼저 설계하지 않았다.

이미 잘 돌아가던 실행 방식을 보고 필요한 부분을 남겼다.

코딩 에이전트 안에는 생각보다 많은 범용 런타임 기능이 섞여 있었다.

text
Coding Agent
  ├─ model loop
  ├─ context management
  ├─ session
  ├─ tool execution
  ├─ streaming
  ├─ cancellation
  ├─ permission
  ├─ persistence
  ├─ skills
  ├─ sub agents
  ├─ filesystem        ← coding specific
  ├─ patch             ← coding specific
  └─ shell             ← coding specific

아래쪽 세 개만 코딩 기능인 것은 아니지만, 적어도 생각보다 많은 부분이 코딩이라는 도메인과 무관했다.

나는 그 경계를 직접 뜯어보면서 알게 됐다.

처음부터 에이전트 프레임워크 문서를 읽었다면 아마 Session, Tool, Memory 같은 기능 이름부터 배웠을 것이다.

이번에는 반대였다.

문제를 먼저 겪고 나서 이름을 알게 됐다.

같은 기능인데 이제 설명이 다르게 보였다 ​

예전에는 프레임워크 문서에서 이런 말을 보면 비슷하게 느껴졌다.

text
Persistent Session
Durable Execution
Checkpoint
Human-in-the-loop
Context Management

좋은 기능이 많다는 정도였다.

직접 구현해 본 뒤에는 질문이 달라졌다.

Persistent Session이라고 하면 저장소가 있다는 것보다 먼저 이런 게 궁금해졌다.

text
동시 write는 어떻게 막는가?
revision이 있는가?
중간 중단 상태도 commit되는가?
재시도 때 같은 tool effect를 다시 내는가?

Durable Execution이라고 하면 이것부터 보게 됐다.

text
어디까지 durable한가?
모델 호출도 replay되는가?
외부 tool side effect는 어떻게 다루는가?
resume 시 입력은 어디부터 다시 구성되는가?

Context Management라고 하면 이것이 궁금해졌다.

text
단순 truncate인가?
요약인가?
중요 상태를 별도로 보존하는가?
압축 사실을 관측할 수 있는가?

기능 이름이 아니라 semantics를 보게 됐다.

이 차이가 생각보다 컸다.

직접 만들었다는 이유만으로 유지할 필요는 없다 ​

여기서 또 조심해야 할 게 생겼다.

고생해서 만들었으니 계속 써야 한다는 생각이다.

이건 별로 좋은 이유가 아니다.

이미 있는 프레임워크가 더 안정적이고, 유지보수도 잘 되고, 내가 필요한 실행 의미까지 만족한다면 바꾸는 게 맞다.

직접 구현한 코드에 애착을 가지기 시작하면 금방 목적이 바뀐다.

원래 목적은 런타임을 만드는 것이 아니라 실제 업무를 AI로 바꾸는 것이었다.

그래서 앞으로는 오히려 같은 요구사항을 기존 프레임워크에도 붙여볼 생각이다.

text
같은 Consumer
      │
      ├─ 직접 만든 Runtime
      ├─ 기존 Agent Framework A
      └─ 기존 Agent Framework B

비교 기준도 기능 개수가 아니라 실제 운영 요구사항으로 잡는 게 맞아 보인다.

text
multi-turn session
restart recovery
context compression
memory
search
dynamic tools
streaming
cancellation
idempotency
concurrent session update
resume
observability
provider independence

직접 만든 쪽이 별 장점이 없다면 줄이면 된다.

필요한 일부만 남기고 나머지는 기존 생태계에 맡겨도 된다.

반대로 프레임워크가 특정 Agent 객체나 Graph 구조를 강하게 요구해서 제품마다 그 구조에 맞춰야 한다면, 직접 가진 작은 실행 계층이 더 편할 수도 있다.

이건 아직 검증할 부분이다.

그래도 삽질이 낭비였다고 생각하지 않는다 ​

만약 처음부터 프레임워크 하나를 골랐다면 훨씬 빨리 제품 하나를 만들었을 가능성이 높다.

반대로 지금처럼 내부 문제를 이해하지 못했을 수도 있다.

예를 들어 예전의 나는 retry가 있으면 안정성이 올라간다고 단순하게 생각했다.

지금은 retry를 보면 먼저 idempotency와 side effect를 본다.

예전에는 context window가 커지면 좋다고 생각했다.

지금은 긴 세션에서 어떤 상태를 남기고 어떤 데이터를 다시 검색할 수 있게 할지 먼저 본다.

예전에는 tool calling이 되면 agent가 된다고 생각했다.

지금은 tool 실행 전후의 상태와 실패 복구가 더 눈에 들어온다.

text
기능을 배운 것
        ↓
왜 필요한지 이해한 것
        ↓
어디서 깨지는지 경험한 것

세 단계는 꽤 달랐다.

이번에는 마지막 단계까지 직접 밟아본 셈이다.

오히려 제품을 하나 올려봐야 결론이 날 것 같다 ​

런타임 자체만 계속 보고 있으면 끝이 없다.

Session을 더 잘 만들 수 있고, Memory를 더 잘 만들 수 있고, Event를 더 잘 남길 수 있다.

그런데 실제 제품이 없으면 무엇이 과한 설계인지 판단하기 어렵다.

그래서 다음 단계는 런타임 기능을 더 늘리는 것이 아니라 실제 제품 하나를 끝까지 올리는 쪽이 맞다고 생각한다.

text
실제 사용자 입력
  ↓
상태가 여러 턴 이어짐
  ↓
검색과 외부 도구 사용
  ↓
실패와 재시도
  ↓
서버 재시작
  ↓
다음날 다시 이어서 사용

이걸 실제 URL로 운영해 보면 지금 만든 것 중 절반은 쓸모없을 수도 있다.

반대로 지금 빠진 핵심이 바로 드러날 수도 있다.

그때 기존 프레임워크와 비교하면 더 제대로 판단할 수 있을 것 같다.

지금의 결론 ​

새로운 에이전트 프레임워크를 하나 만들었다고 생각하지 않는다.

그보다는 코딩 에이전트를 일반 업무에 가져오려고 뜯어보다가, AI가 실제 일을 지속적으로 수행하려면 어떤 바닥이 필요한지 직접 확인한 과정에 가깝다.

그리고 그 바닥은 생각보다 평범했다.

상태를 저장하고,

중복을 막고,

문맥을 관리하고,

도구를 실행하고,

취소하고,

실패를 기록하고,

다시 이어가는 것.

평범한데 하나라도 빠지면 금방 데모로 돌아갔다.

그래서 지금은 "내 런타임이 특별한가"보다 다른 질문이 더 중요해졌다.

어떤 부분까지 직접 소유해야 실제 AX 제품을 가장 단순하게 만들 수 있을까.

그 답은 아마 다음 제품을 실제로 운영해 본 뒤에야 나올 것 같다.

마지막 수정:

Boundary · Execution · Verification · Operation