AI 에이전트용 API를 설계하며 알게 된 '자유롭게 두기 위한 제약'
요약
본 글은 AI 에이전트가 소프트웨어를 조작하는 API 설계에 대한 통찰을 제공합니다. 개발자가 만든 디지털 사이니지 'Glypha'의 경험을 바탕으로, 기능을 많이 추가하기보다 시스템 경계에서 입력 데이터를 엄격하게 검증하고 제약하는 것이 중요함을 강조합니다. AI 에이전트에게는 자유도를 부여하되, 최종 결과물은 명확한 구조와 규칙을 지키도록 설계해야 합니다.
핵심 포인트
- AI 에이전트 API 설계 시 기능 추가보다 입력 데이터의 '수용 조건' 정의가 핵심이다.
- 시스템 경계에서 들어오는 결과물은 반드시 엄격하게 검증하고, 부적합하면 명확히 거부해야 한다.
- 실패를 숨기고 그럴싸하게 작동하는 것보다, 실패했다는 사실이 명확한 것이 AI 에이전트의 안정적인 동작에 더 가치 있다.
AI 에이전트가 소프트웨어를 조작하게 할 때, 어느 정도까지 전용 기능을 준비해야 할까요?
자연어 기반의 조작 화면, AI 전용 API, MCP 서버, 용도별 툴 등 여러 가지 방법이 생각해 볼 수 있습니다.
한편, 제가 개발하고 있는 디지털 사이니지 'Glypha'에는 AI 에이전트 전용 인터페이스를 준비하지 않았습니다. 존재하는 것은 인간도 이용할 수 있는 HTTP API뿐입니다.
Human
│ 목적을 전달한다
▼
...
이 단순한 구조로 실험해 보니, AI 에이전트용 소프트웨어에서는 기능을 늘리는 것보다 '무엇을 받아들일지'를 설계하는 것이 중요하다는 것을 알게 되었습니다.
본문에서는 Glypha의 실험에서 얻은 API 설계상의 깨달음을 정리합니다.
Glypha는 텍스트와 이미지를 표시하는 디지털 사이니지입니다.
관리 화면, 템플릿 선택, 레이아웃 편집 같은 일반적인 기능은 없습니다. 테두리나 사각형을 그리는 전용 기능도 없습니다.
콘텐츠는 HTTP API로 전송합니다. 전용 CLI가 없고, 예를 들어 curl로부터 다음과 같이 조작할 수 있습니다.
curl --fail-with-body -X PUT http://localhost:8080/content \
-F '[email protected];type=application/json' \
-F '[email protected]'
이 예시에서는 표시 내용을 기술한 content.json과, 표시하는 데 사용되는 logo.png를 multipart/form-data로 전송하고 있습니다.
다만, 받아들인 데이터를 그대로 표시하는 것은 아닙니다.
Glypha는 메시지의 구조와 제약을 검증하여, 묘사 가능한지 여부를 판정합니다. 적합한 메시지만을 묘사하고, 부적합하면 거부합니다.
Glypha의 기능은 적은 편이지만, 받아들이는 조건은 모호하지 않습니다.
'AI 에이전트에게 자유롭게 만들게 한다'고 하면, 입력도 유연하게 받아들이는 설계를 상상할 수 있습니다.
하지만 실제는 그 반대였습니다.
AI 에이전트는 정보 수집, 문서 작성, 이미지 가공, 프로그램 작성 등 Glypha 외부에서는 자유롭게 수단을 선택할 수 있습니다. 한편, Glypha에 전달하는 최종 결과물은 정해진 구조와 제약을 충족해야 합니다.
자유롭게 맡기는 영역
├─ 정보를 어디서 얻을지
├─ 문서를 어떻게 만들지
...
AI의 중간 과정을 세밀하게 제어하는 것이 아니라, 시스템과의 경계에서 결과물을 검증하는 구조입니다.
외부 방식을 고정하지 않기 때문에, AI 에이전트는 상황에 따라 독창적으로 할 수 있습니다. 내부 조건을 고정하기 때문에, Glypha가 보장해야 하는 범위는 변하지 않습니다.
AI의 자유도와 시스템의 엄격함은 대립하지 않습니다. 엄격한 경계가 있기 때문에, 그 바깥쪽을 자유롭게 할 수 있습니다.
AI 에이전트용 API에서는 성공하는 요청의 만들기 쉬움에 초점이 맞춰지기 쉽습니다.
물론, 단순한 HTTP API나 명확한 사양은 중요합니다. 하지만 그것만큼 중요한 것이 받아들일 수 없는 입력을 모호하게 처리하지 않는 것입니다.
예를 들어, 부정확한 메시지를 가능한 범위에서 묘사해 버리면, AI 에이전트가 본 결과는 불안정해집니다.
- 일부만 무시된 것인지
- 값이 자동 보정된 것인지
- 묘사 엔진의 사정으로 보이지 않는 것인지
- 요청 자체가 잘못되었는지
이러한 것들을 외부에서 구분하기 어려워지기 때문입니다.
Glypha는 계약을 충족하지 못하는 메시지는 거부합니다. curl 예시에 --fail-with-body를 붙인 것도, HTTP 에러를 성공으로 취급하지 않고 응답 본문을 확인할 수 있도록 하기 위함입니다.
AI 에이전트가 시도하고 오류를 수정하는 전제라면, 실패를 숨기고 '그럴싸하게 작동'하는 것보다, 실패했다는 사실이 명확한 것에 가치가 있습니다.
설계할 때는 적어도 다음 점들을 명확히 해 두어야 합니다.
- 무엇을 필수로 할지
- 어떤 값을 허용할지
- 여러 요소의 조합에 어떤 제약이 있는지
- 어떤 조건일 때 묘사 가능하다고 판단할지
- 부적합할 때 어떻게 실패를 반환할지
Glypha를 Claude Code에 조작하게 했더니, 예상하지 못했던 방식으로 콘텐츠를 만들기 시작했습니다.
Glypha에는 테두리를 그리는 기능이 없습니다.
Claude Code는, 테두리를 포함한 이미지를 만들고, 그 이미지를 표시 요소로 사용했습니다. Glypha에 새로운 묘사 기능을 추가하는 것이 아니라, 기존의 '이미지 표시'라는 능력으로 변환시킨 것입니다.
소재 이미지를 Glypha의 사양에 맞춰 가공해야 했지만, 적절한 이미지 편집 수단이 없는 상황이 있었습니다.
그때 Claude Code는 Go 언어로 이미지 가공 프로그램을 만들고, 그것을 실행하여 이미지를 준비했습니다.
Glypha에는 이미지 편집 기능이 없습니다. Go로 프로그램을 작성하라고 지시한 것도 아닙니다. AI 에이전트가 결과물을 계약에 적합하게 만들기 위한 도구를 외부에서 만든 것입니다.
웹페이지 URL을 전달하며 콘텐츠 제작을 의뢰하자, Claude Code는 페이지에서 정보를 가져와 내용을 정리하고, Glypha가 수용할 수 있는 형태로 변환했습니다.
Glypha에는 웹페이지를 가져오는 기능도, URL로부터 콘텐츠를 생성하는 기능도 없습니다.
그럼에도 불구하고, AI 에이전트가 외부에서 처리를 수행함으로써 새로운 용도를 실현할 수 있었습니다.
이 3가지 사례에 공통적인 것은 목적을 달성하기 위해 Glypha의 기능을 늘리지 않았다는 점입니다.
구분선(罫線)이 필요
→ 구분선 그리기 API를 추가하는 대신, 이미지로 변환
이미지 가공이 필요
...
소프트웨어가 가진 기능과, 그 소프트웨어를 사용해서 실현할 수 있는 것은 일치하지 않는다는 것입니다.
AI 에이전트가 외부에서 활용할 수 있는 능력을 조합하면, 시스템 본체의 책임 범위를 넓히지 않으면서 용도만 늘릴 수 있는 경우가 있습니다.
기존의 API 설계에서는 이용자의 유스케이스를 나열하고, 각각에 필요한 조작을 추가해 가는 경우가 있습니다.
AI 에이전트가 활용할 경우에도, 용도별로 API를 만드는 방법은 있습니다. 하지만, 용도를 미리 예측하여 기능을 계속 늘려야 하는지에 대해서는 재고의 여지가 있습니다.
Glypha에서는 용도가 아니라, 사이니지로서 최소한 보장하는 능력을 API의 경계에 두었습니다.
- 텍스트와 이미지를 받는다
- 메시지가 제약을 충족하는지 검증한다
- 그려질 수 있는 것만 그린다
- 부적합한 것은 거부한다
관광 안내, 호텔 안내, 이벤트 공지 같은 용도는 Glypha의 API에는 나타나지 않습니다. 그것들은 AI 에이전트가 만드는 콘텐츠 측면의 관심사입니다.
이러한 분리에는 다음의 이점이 있습니다.
URL 가져오기나 이미지 편집 등을 본체에 추가하게 되면, 대응 형식, 보안, 장애 처리, 의존 라이브러리 등 유지보수해야 할 범위도 늘어납니다.
외부 AI 에이전트에게 맡길 수 있는 처리를 분리하면, Glypha는 표시와 검증에 집중할 수 있습니다.
Glypha는 Claude 전용의 처리를 가지고 있지 않습니다. HTTP API 계약을 충족할 수만 있다면, 다른 AI 에이전트나 사람이 만든 클라이언트도 이용할 수 있습니다.
새로운 용도가 기존 텍스트와 이미지로 표현 가능하다면, Glypha를 변경하지 않고 시도해 볼 수 있습니다.
Glypha 개발에서는 Alloy를 사용해서 구조와 제약을 모델링했습니다. AI에게 구현을 맡길 때도 이 모델을 이용했고, 생성된 테스트 코드에는 모델로 정의한 조건이 반영되어 있었습니다.
여기서도 Glypha를 이용할 때와 같은 구조가 나타났습니다.
사람이 결정한다
└─ 지켜야 할 속성, 구조, 제약
AI에게 맡긴다
...
AI에게 세세한 절차를 모두 지시하는 대신, 변경해서는 안 될 조건을 명확히 하는 방법입니다.
AI 에이전트가 무엇을 할지 완전히 예측하기는 어렵습니다. 그렇기 때문에, 중간의 모든 행동을 나열하여 제어하려 하기보다는, 시스템에 들어올 때 충족해야 할 계약을 설계하는 것이 더 다루기 쉬울 때가 있습니다.
Glypha의 실험을 일반화하면, AI 에이전트가 이용할 API를 설계할 때 다음 사항들을 고려해 볼 수 있을 것 같습니다.
기존 HTTP API가 단순하고 사양이 명확하다면, 그대로 이용할 가능성이 있습니다. AI 전용 레이어를 추가하기 전에, 기존 인터페이스에서 부족한 정보가 무엇인지 확인합니다.
용도를 나열하는 것이 아니라, 시스템이 책임질 범위를 정합니다.
구조뿐만 아니라, 요소 간의 제약이나 실제로 처리가 가능한지 여부도 판정 대상이 됩니다.
암묵적인 보정이나 부분적인 성공은 AI 에이전트의 시행착오를 어렵게 할 수 있습니다.
이미지 가공, 데이터 가져오기, 형식 변환 등은 AI 에이전트가 외부에서 수행하고, 결과만 기존 계약에 맞출 수 있습니다.
AI 에이전트에 의존하는 것이 아니라, 계약에 의존하는 설계로 만들어 놓으면, 이용하는 모델이나 툴이 바뀌어도 시스템 본체를 유지하기 쉽습니다.
Glypha의 실험을 통해 얻은 가장 큰 깨달음은, AI 에이전트에게 자유롭게 일을 시키는 것과, 시스템의 제약을 약하게 하는 것은 별개라는 것입니다.
외부에서는 AI 에이전트가 정보를 모으고, 이미지를 가공하고, 때로는 필요한 프로그램까지 만듭니다.
내부적으로는 시스템이 메시지를 엄격하게 검증하여, 계약에 맞는 것만 수락합니다.
이러한 책임 경계가 있다면, 시스템 본체를 작게 유지하면서도 AI 에이전트의 능력으로 사용처를 넓힐 수 있습니다.
AI 에이전트를 위한 소프트웨어를 설계할 때 가장 먼저 고려해야 할 것은 풍부한 기능 목록이 아니라, 작고 명확하며 실패까지 예측 가능한 계약일지도 모릅니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기