AI-Assisted Engineering Talk #1/27

프레임워크에 의지하지 않는, 신뢰할 수 있는 LLM 에이전트를 만드는 12가지 원칙

100여 SaaS 빌더와 대화한 끝에 내린 결론 하나. “좋은 에이전트는 프롬프트+도구+루프가 아니다. 결정론적 소프트웨어에 LLM 단계를 정확한 지점에 끼워 넣은 시스템이다.”

핵심 주장

1. 프레임워크에는 70~80%의 벽이 있다

LangChain, CrewAI 같은 에이전트 프레임워크로 빠르게 출발하면 80%까지는 도달하지만, 그 이상은 프레임워크를 역공학해서 다시 짜야 하는 일이 반복됩니다. 처음의 속도보다 깊은 통제권을 우선해야 한다는 것이 Dex의 첫 번째 교훈이옵니다.

2. 에이전트의 본질은 결정론적 소프트웨어 + LLM 모듈

프로덕션에서 동작하는 에이전트는 사실 대부분 결정론적 코드입니다. LLM은 자연어를 구조화된 도구 호출로 변환하는 특정 지점에서만 사용되고, 나머지는 평범한 소프트웨어가 처리합니다.

3. 프롬프트, 컨텍스트, 제어 흐름을 직접 소유하라

프레임워크가 추상화한 프롬프트 빌더, 컨텍스트 관리, while-loop에 의존하면 병목이 됩니다. 모든 토큰을 직접 작성하고, 컨텍스트 윈도우의 정보 밀도를 통제하고, 루프의 매 분기를 소유해야 합니다.

4. 에이전트는 무상태 fold 함수다

(이전 이벤트 누적 + 새 이벤트) → 다음 단계. 함수형 프로그래밍의 reducer 패턴 그 자체입니다. 상태는 외부에, 결정 로직은 순수 함수로 분리하면 재현, 재개, 시간 여행 디버깅까지 자연스럽게 열립니다.

5. 인간도 도구 호출과 같은 인터페이스로

사람에게 묻거나 승인을 받는 행위를 별도 워크플로우 엔진이 아닌 도구 호출로 모델링합니다. 거버넌스가 인프라 문제에서 라이브러리 수준의 문제로 내려앉는 것이지요.

12가지 원칙

  • 1. 자연어를 도구 호출로 — LLM이 자연어를 구조화된 JSON 함수 호출로 변환한다. 그 뒤는 결정론적 코드가 처리한다.
  • 2. 프롬프트를 직접 소유하라 — 프레임워크의 프롬프트 빌더에 의존하지 말고, 모든 토큰을 직접 작성하고 통제한다.
  • 3. 컨텍스트 윈도우를 직접 소유 — 표준 messages 포맷에 갇히지 마라. 정보 밀도, 에러 표시, 민감정보 필터링을 직접 통제한다.
  • 4. 도구는 구조화된 출력일 뿐 — 도구 호출은 LLM이 뱉은 JSON일 뿐. 함수 시그니처와 스키마로 충분히 정의된다.
  • 5. 실행 상태와 비즈니스 상태 통합 — 에이전트의 실행 상태와 비즈니스 상태를 하나의 영구 저장소에 통합하여 재개와 롤백을 일관되게.
  • 6. 단순 API로 launch/pause/resume — 인메모리 while-sleep 대신 HTTP/큐 API로 시작, 일시정지, 재개할 수 있어야 한다.
  • 7. 사람과의 소통도 도구 호출 — 인간 승인을 별도 시스템이 아닌 도구 호출로 모델링한다. 인간이 워크플로우의 1급 시민.
  • 8. 제어 흐름을 직접 소유 — 루프를 프레임워크에 맡기지 말고 직접 소유하여 재시도, 속도 제한, 사전 검토를 끼워 넣는다.
  • 9. 에러를 컨텍스트에 압축 — 에러를 그대로 흘리지 말고 LLM이 회복할 수 있는 형태로 요약하여 컨텍스트에 삽입한다.
  • 10. 작고 집중된 에이전트 — 3~10단계로 끝나는 작은 에이전트들로 분해한다. 컨텍스트가 커질수록 LLM은 길을 잃는다.
  • 11. 어디서든 트리거하라 — 진입점을 채팅창에 가두지 말고 슬랙, 이메일, 웹훅, 크론 어디서든 트리거할 수 있게.
  • 12. 에이전트는 무상태 reducer — (이전 이벤트 + 새 이벤트) → 다음 단계를 결정하는 무상태 함수. 함수형 fold 패턴 그 자체.

검증된 인사이트

💡 [Insight] 에이전트는 결국 fold 함수다

Factor 3(컨텍스트 = 이벤트 스트림)과 Factor 12(무상태 reducer)를 합치면, 에이전트는 (history, event) → next_step의 fold 함수가 됩니다. 상태 영속성은 외부 저장소에, 결정 로직은 순수 함수에 분리되어 재현, 재개, 시간 여행 디버깅이 자연스럽게 가능해집니다. 기존 이벤트 소싱, CQRS 인프라와 그대로 호환된다는 점에서 실무적 함의가 큽니다.

functional architecture event-sourcing

💡 [Insight] 인간 승인은 도구 호출과 같은 추상화

Factor 7과 Factor 8을 합치면, 인간 승인이 별도 워크플로우 엔진의 책임이 아니라 도구 디스패처의 한 분기로 흡수됩니다. 도구 호출과 인간 호출이 같은 인터페이스(intent + 비동기 응답)를 공유하므로, 새로운 인간 검토 단계를 추가하는 비용이 새 도구를 추가하는 비용과 동일해집니다.

human-in-the-loop governance abstraction ## 다른 영상과의 교차점

  • Factor 3의 “컨텍스트 윈도우를 직접 소유"는 Factory의 “에이전트는 컨텍스트에 매우 반응적이다” 명제와 같은 뿌리를 공유합니다. 외부화된 상태로 컨텍스트 폭주를 막는다는 전략 역시 동일한 구조입니다.
  • Factor 10(작고 집중된 에이전트)은 Augment의 Chat / Agent / Remote 모드 분화와 맞닿아 있으며, Factor 9(에러 압축)는 “막히면 시도 후 우회하는 자가 복구” 패턴에서 실제 구현을 확인할 수 있습니다.
  • “워크플로우에 사는 작은 에이전트들” 비전은 Factor 10과 정확히 정렬됩니다. “doable 문제의 단위 = 자동 검증이 가능한 단위"라는 기준도 작은 에이전트 설계의 실무 가이드라인이 됩니다.
  • Factor 2(프롬프트 소유)와 Factor 3(컨텍스트 소유)는 copilot-instructions.md, .instructions 파일 체계와 같은 맥락입니다. “컨텍스트에 last-writer-wins이 없다"는 발견은 Factor 3의 실무 주의사항을 보강합니다.
  • “컨텍스트가 AI 코드 생성의 1순위"라는 Chris의 선언은 Factor 3의 동일 명제를 실무에서 확인한 것이며, rules 파일 + plan markdown의 Create-Refine 루프는 Factor 2의 구체적 실천법입니다.

한 줄 소감

12-Factor App이 클라우드 네이티브의 공통어가 된 것처럼, 이 12가지 원칙은 LLM 에이전트 시스템 설계의 공통어가 될 수 있겠다는 생각이 들었습니다. 특히 “에이전트는 fold 함수"라는 통찰은, 새로운 패러다임처럼 보이는 에이전트가 사실 함수형 프로그래밍이 이미 풀어낸 문제라는 점을 명쾌하게 드러냅니다.