· engineering · 6분 읽기

하네스 엔지니어링 — AI 에이전트에 고삐를 채우는 기술

AI 에이전트를 실무에 투입해본 사람이라면, 한 번쯤은 이런 경험을 했을 거다.

  • 어제까지 잘 되던 에이전트가 오늘은 엉뚱한 답을 한다
  • 컨텍스트를 잔뜩 넣었더니 오히려 핵심을 놓친다
  • Claude로 만든 워크플로우를 GPT로 바꾸려니 처음부터 다시 해야 한다
  • 에이전트가 여러 개인데, 각각 다른 스타일로 답변해서 일관성이 없다

이건 AI가 부족해서가 아니다. 에이전트를 다루는 구조가 없어서 생기는 문제다.

문제: 무질서한 AI 활용

컨텍스트 비대화

에이전트에게 “이것도 알아야 하고, 저것도 참고해”라며 정보를 계속 쌓다 보면, 어느 순간 컨텍스트 윈도우가 포화된다. LLM은 컨텍스트가 길어질수록 중간 부분의 정보를 잘 활용하지 못한다(이른바 “lost in the middle” 현상). 더 많은 정보를 줬는데 오히려 성능이 떨어지는 역설적인 상황이 벌어진다.

LLM 종속성

특정 모델의 시스템 프롬프트 형식, 함수 호출 방식, 응답 패턴에 맞춰서 워크플로우를 짜면, 모델을 교체하는 순간 전부 깨진다. OpenAI의 function calling 형식으로 짠 걸 Anthropic의 tool use로 바꾸려면? 프롬프트부터 파싱 로직까지 전부 손봐야 한다.

이건 마치 특정 데이터베이스의 전용 SQL 문법에 의존해서 코드를 짜는 것과 같다. 처음엔 편하지만, 나중에 발목을 잡는다.

느슨한 규칙

“친절하게 답변해줘”, “코드를 잘 짜줘” 같은 모호한 지시로는 일관된 결과를 기대할 수 없다. 사람에게 업무를 맡길 때도 “알아서 잘 해줘”라고 하면 결과가 들쭉날쭉한데, AI라고 다를 게 없다.

하네스 엔지니어링이란

말을 다룰 때 고삐(harness)가 필요하듯, AI 에이전트에게도 구조화된 제어 체계가 필요하다. 이걸 하네스 엔지니어링이라고 부른다.

핵심은 간단하다. 에이전트의 정체성, 도구, 규칙, 메모리, 컨텍스트를 코드처럼 선언적으로 관리하는 것.

1. 정체성 정의 (Identity)

에이전트에게 “넌 누구고, 뭘 잘하고, 어떻게 행동해야 하는지”를 명시적으로 정의한다. 객체지향의 캡슐화와 같은 원리다. 클래스가 자기 상태와 행동을 가지듯, 에이전트도 자기 정체성과 행동 규칙을 갖는다.

name: reviewer
role: 코드 리뷰어
expertise: 보안 점검, 성능 분석, OWASP Top 10
tone: 직설적, 근거 기반

이렇게 하면 에이전트가 자기 역할 범위를 벗어나는 답변을 하는 빈도가 눈에 띄게 줄어든다. 객체가 public 인터페이스만 노출하듯, 에이전트도 자기 전문 영역에서만 동작하도록 경계를 만드는 거다.

2. 도구 권한 관리 (Tool Policy)

에이전트가 사용할 수 있는 도구를 명시적으로 제한한다. 모든 에이전트에게 파일 쓰기, 외부 API 호출, 메시지 전송 권한을 다 주면? 사고가 난다.

리서치 에이전트는 웹 검색과 문서 읽기만. 개발 에이전트는 파일 읽기/쓰기와 실행만. 이렇게 최소 권한 원칙을 적용하면, 에이전트가 의도치 않은 행동을 할 여지가 줄어든다.

3. 컨텍스트 설계 (Context Architecture)

여기가 가장 중요하고, 가장 많이 실수하는 부분이다.

컨텍스트를 “필요할 것 같으니까 다 넣자” 식으로 관리하면 실패한다. 대신 계층을 나눠야 한다.

  • 항상 로드되는 컨텍스트: 에이전트 정체성, 핵심 규칙, 도구 목록
  • 조건부 컨텍스트: 특정 작업을 할 때만 로드되는 도메인 지식
  • 휘발성 컨텍스트: 현재 대화에서만 유효한 정보

이걸 코드로 비유하면, 전역 변수를 최소화하고 스코프를 좁히는 것과 같은 원리다. 모든 정보를 전역에 놓으면 충돌이 나고, 필요한 스코프에서만 참조하면 깔끔하다.

4. 메모리 구조화 (Memory)

LLM은 기본적으로 세션이 끝나면 모든 걸 잊는다. 장기 기억이 필요하면 직접 설계해야 한다.

단순히 대화 로그를 저장하는 게 아니라, 무엇을 기억하고 무엇을 잊을지를 구조적으로 결정해야 한다. 사용자 선호도, 프로젝트 컨텍스트, 과거 의사결정 — 이런 것들은 기억할 가치가 있다. 반면 특정 세션의 디버깅 과정이나 임시 파일 내용은 기억할 필요가 없다.

기억의 종류도 나눠야 한다. 사용자에 대한 이해, 작업 피드백, 프로젝트 상태, 외부 참조 — 각각 저장 시점과 활용 방식이 다르다.

5. 멀티 에이전트 오케스트레이션

혼자서 모든 걸 잘하는 에이전트는 없다. 사람도 그렇듯이.

개발은 개발 에이전트에게, 리서치는 리서치 에이전트에게, 리뷰는 리뷰 에이전트에게. 각자 전문성에 맞는 정체성과 도구를 갖추고, 태스크 보드를 통해 협업하는 구조다.

여기서 핵심은 리더 에이전트의 역할이다. 사용자의 요청을 분석하고, 적절한 멤버에게 위임하고, 결과를 종합해서 전달한다. 사람 조직의 테크리드와 비슷한 역할이다.

6. 모듈화 — 바꿀 수 있는 구조

하네스 엔지니어링의 근본 원칙은 모듈화다. 정체성, 도구, 규칙, 메모리 — 각각이 독립된 모듈이고, 필요에 따라 교체하거나 확장할 수 있다.

에이전트 A의 메모리 구조를 바꿔도 에이전트 B는 영향받지 않는다. 도구 권한을 조정해도 정체성은 그대로다. 이건 소프트웨어에서 모듈 간 느슨한 결합(loose coupling)을 추구하는 것과 똑같은 이야기다.

LLM 종속성 탈피

하네스의 또 다른 장점은 LLM 교체가 수월해진다는 것이다.

에이전트의 행동 규칙이 특정 모델의 프롬프트 형식이 아니라 선언적 설정 파일에 정의되어 있으면, LLM을 바꿔도 설정은 그대로 유지된다. 번역 레이어만 바꾸면 되는 셈이다.

이건 웹 개발에서 ORM을 쓰는 이유와 같다. 비즈니스 로직을 특정 DB 문법에서 분리하듯, 에이전트 로직을 특정 LLM에서 분리하는 거다.

실제로 달라지는 것

하네스 없이 에이전트를 운영하면:

  • 프롬프트가 점점 길어지고 복잡해진다
  • 동일한 질문에 대한 답변 품질이 매번 다르다
  • 모델 업데이트 한 번에 기존 워크플로우가 깨진다
  • “이건 왜 이렇게 답했지?” 추적이 안 된다

하네스를 도입하면:

  • 에이전트의 행동이 예측 가능해진다
  • 새 멤버(사람이든 에이전트든) 온보딩이 설정 파일 공유로 끝난다
  • 문제가 생기면 어떤 규칙이 원인인지 추적할 수 있다
  • LLM을 교체해도 에이전트의 성격과 규칙은 유지된다

마무리

AI 에이전트를 “잘 쓰는 것”과 “그냥 쓰는 것”의 차이는, 결국 구조의 유무다.

프로그래밍에서 코드를 그냥 쓰는 것과 아키텍처를 설계하고 쓰는 것이 다르듯, AI 에이전트도 마찬가지다. 하네스 엔지니어링은 거창한 개념이 아니다. 에이전트를 소프트웨어처럼 — 선언적으로, 버전 관리 가능하게, 테스트 가능하게 — 다루자는 것이다.

AI가 더 강력해질수록, 그걸 제어하는 구조도 함께 정교해져야 한다. 고삐 없는 말은 아무리 빨라도 쓸모가 없다.