가까이 붙여 검증하고, 멀리 연결해 확장하라: 도구의 한계를 설계하는 법

min dulle

Hatched by min dulle

Aug 28, 2026

8 min read

78%

0

AI와 소프트웨어 도구를 잘 쓰는 사람은 기능이 많은 도구를 고르는 사람이 아니다. 오히려 무엇을 할 수 없는지 빨리 확인하고, 할 수 있는 부분은 가장 가까운 곳에서 검증하는 사람이다.

이 말은 서로 무관해 보이는 두 장면에서 선명하게 드러난다. 하나는 구현 코드와 같은 파일에 테스트를 두는 방식이다. 다른 하나는 로컬 언어 모델을 실행하는 도구가 텍스트는 다루지만 아직 이미지를 직접 생성하지 못하는 상황이다. 하나는 테스트의 위치에 관한 문제이고, 다른 하나는 모델의 기능 범위에 관한 문제처럼 보인다. 그러나 두 문제의 중심에는 같은 질문이 있다.

도구의 경계를 어디에 그어야, 실패를 가장 싸고 정확하게 발견할 수 있는가?

이 질문에 답하면 테스트 구조뿐 아니라 AI 워크플로, 제품 설계, 자동화의 신뢰성까지 새롭게 보인다.

기능보다 중요한 것은 경계의 선명함이다

개발자는 흔히 도구를 기능 목록으로 평가한다. 어떤 언어를 지원하는가, 어떤 모델을 실행하는가, 이미지도 만들 수 있는가, 플러그인이 있는가를 묻는다. 하지만 실제 생산성은 기능의 개수보다 기능 사이의 경계가 얼마나 명확한가에 더 크게 좌우된다.

예를 들어 텍스트 모델을 실행하는 도구가 있다고 하자. 사용자는 자연스럽게 다음과 같은 요청을 입력할 수 있다.

고양이가 우주선을 조종하는 이미지를 만들어 줘.

모델이 그럴듯한 문장으로 프롬프트를 만들어 줄 수는 있다. 그러나 그것은 이미지를 생성하는 일과 다르다. 텍스트를 생성하는 능력, 이미지 생성 모델을 호출하는 능력, 결과 파일을 저장하는 능력은 서로 다른 기능이다. 이 차이를 모르면 사용자는 모델이 부족하다고 느끼거나, 반대로 존재하지 않는 기능을 억지로 기대하게 된다.

소프트웨어 테스트에서도 비슷한 착시가 발생한다. 테스트가 구현 파일에서 멀리 떨어져 있으면 개발자는 테스트를 별도의 의식처럼 다루기 쉽다. 구현을 수정하고, 다른 폴더로 이동하고, 테스트 파일을 찾고, 실행하고, 실패 원인을 다시 구현으로 추적해야 한다. 테스트가 틀린 것이 아니라 검증의 경계가 실제 변경 지점과 분리되어 있기 때문에 피드백 비용이 커진 것이다.

구현과 테스트를 같은 파일에 두는 인 소스 테스트는 이 거리를 줄인다. 코드를 수정하는 순간 어떤 가정이 검증되는지 바로 보인다. 테스트는 사후 점검 문서가 아니라 구현 옆에 붙어 있는 실행 가능한 설명이 된다.

두 사례는 모두 같은 원리를 보여 준다.

신뢰성은 도구가 모든 일을 해낼 때 생기는 것이 아니라, 도구가 맡은 일과 맡지 않은 일이 분명할 때 생긴다.

가까운 검증과 먼 확장은 서로 다른 문제다

여기서 중요한 구분이 하나 있다. 시스템을 안정적으로 만드는 방법에는 크게 두 가지가 있다. 하나는 가까운 검증이고, 다른 하나는 먼 확장이다.

가까운 검증은 어떤 기능의 바로 옆에서 그 기능의 결과를 확인하는 방식이다. 함수 바로 옆에 테스트를 둔다거나, 이미지 생성 요청을 보내기 전에 현재 사용 중인 모델이 이미지 출력을 지원하는지 확인하는 일이 여기에 해당한다. 이 방식의 장점은 원인과 결과 사이의 거리가 짧다는 것이다.

먼 확장은 한 도구의 부족한 기능을 다른 도구와 연결해 전체 시스템의 능력을 넓히는 방식이다. 텍스트 모델이 이미지를 직접 만들지 못한다면, 텍스트 모델은 프롬프트를 작성하고 이미지 생성기는 실제 이미지를 만들도록 연결할 수 있다. Mac 환경에서는 별도의 확산 모델 실행 도구를 사용할 수 있다. 이때 텍스트 모델과 이미지 생성기는 하나의 도구가 아니라 서로 다른 능력을 가진 두 구성 요소로 이해해야 한다.

많은 실패는 이 둘을 혼동할 때 생긴다. 가까운 검증 없이 먼 확장을 시작하면 시스템 전체가 불투명해진다. 반대로 모든 일을 한 도구 안에 넣으려 하면 도구의 한계를 감추기 위해 복잡한 우회로를 만들게 된다.

간단한 예를 생각해 보자. 웹 서비스의 날짜 계산 함수를 수정하면서 테스트를 같은 파일에 두면, 개발자는 함수의 입력과 출력 규칙을 즉시 확인할 수 있다. 이것은 가까운 검증이다. 그런데 날짜 계산 함수가 외부 결제 시스템의 영수증 이미지까지 만들어야 한다고 요구하면 문제가 달라진다. 함수 안에 이미지 생성 기능을 억지로 넣는 대신, 날짜 계산과 영수증 생성이라는 서로 다른 책임을 분리하고 명시적인 연결부를 만들어야 한다. 이것이 먼 확장이다.

가까운 곳에서는 결합하고, 먼 곳에서는 계약을 만든다. 이 한 문장이 두 원칙을 동시에 설명한다.

테스트 위치와 AI 파이프라인은 같은 설계 문제를 공유한다

인 소스 테스트의 가치는 단순히 파일을 덜 열어도 된다는 데 있지 않다. 핵심은 변경과 검증의 단위를 일치시키는 것이다. 작은 함수의 동작을 바꾸면서 그 함수의 규칙을 바로 옆에서 확인할 수 있다면, 개발자는 추상적인 전체 시스템보다 현재 수정한 경계에 집중할 수 있다.

AI 파이프라인도 마찬가지다. 텍스트 생성, 이미지 생성, 파일 저장, 사용자 인터페이스 표시를 하나의 마법 같은 기능으로 취급하면 어디서 문제가 발생했는지 알기 어렵다. 반면 다음처럼 나누면 각 단계의 책임이 보인다.

  1. 언어 모델이 이미지 설명을 생성한다.
  2. 생성된 설명이 이미지 모델의 입력 형식에 맞는지 검사한다.
  3. 이미지 생성기가 설명을 바탕으로 결과를 만든다.
  4. 결과 파일이 올바른 경로에 저장되었는지 확인한다.
  5. 사용자 인터페이스가 파일을 읽고 표시한다.

이 구조에서 언어 모델이 이미지를 직접 만들지 않는다는 사실은 결함이 아니다. 그것은 능력의 분업이다. 결함은 분업을 해 놓고도 사용자에게 하나의 기능처럼 설명하거나, 단계 사이의 계약을 검사하지 않는 데서 발생한다.

각 단계에 작은 검증을 붙이면 실패는 훨씬 값싸진다. 언어 모델이 빈 프롬프트를 출력했는지, 이미지 모델이 지원하지 않는 형식을 받았는지, 파일 저장 권한이 없는지, 표시 단계에서 경로가 틀렸는지를 각각 확인할 수 있다. 거대한 통합 테스트 하나보다 작은 경계 테스트 여러 개가 원인을 더 빨리 알려 준다.

이것은 소프트웨어 테스트의 오래된 통찰과도 맞닿아 있다. 실패를 늦게 발견할수록 실패는 비싸진다. 함수 내부의 오류를 배포 후에 발견하면 수정 범위가 커진다. 모델의 기능 부재를 복잡한 자동화 파이프라인을 만든 뒤에 발견해도 마찬가지다.

따라서 설계할 때 다음 비용을 생각해야 한다.

실패 비용 = 발견까지의 거리 × 영향을 받은 경계의 수

발견까지의 거리가 짧고 영향을 받은 경계가 적으면 실패는 학습이 된다. 발견이 늦고 여러 구성 요소가 얽혀 있으면 실패는 추적 불가능한 장애가 된다.

도구를 고르는 대신 능력 지도를 그려라

새로운 도구를 사용할 때 가장 먼저 해야 할 일은 설치가 아니다. **능력 지도(capability map)**를 그리는 일이다. 능력 지도는 도구의 이름이나 브랜드가 아니라, 입력과 출력의 조합으로 도구를 바라보게 한다.

예를 들어 어떤 로컬 AI 환경을 다음처럼 기록할 수 있다.

작업입력출력담당 도구확인 방법
장면 설명 작성자연어 요청텍스트 프롬프트언어 모델출력이 비어 있지 않은가
이미지 생성텍스트 프롬프트이미지 파일이미지 생성기실제 이미지 파일이 생성되는가
파일 보관이미지 파일지정 경로의 파일운영체제 또는 애플리케이션경로와 권한이 올바른가
화면 표시파일 경로사용자 화면인터페이스파일을 정상적으로 읽는가

이 표의 장점은 단순하다. 어떤 도구가 이미지를 만든다고 막연히 생각하는 대신, 이미지 생성이라는 행위의 담당자를 명시할 수 있다. 텍스트 모델이 이미지 관련 요청을 이해할 수 있다는 사실과 이미지를 출력할 수 있다는 사실도 분리된다.

같은 지도를 코드에 적용할 수도 있다. 함수, 테스트, 데이터베이스, 외부 API, 사용자 인터페이스를 각각 입력과 출력으로 기술하는 것이다. 그러면 테스트를 어디에 둘지 판단하기 쉬워진다. 특정 함수의 순수한 계산 규칙을 검사하는 테스트는 구현 옆에 둘 수 있다. 여러 서비스를 가로지르는 흐름은 별도의 통합 경계에서 검사해야 한다.

이 관점은 도구에 대한 과장된 기대를 줄인다. “이 도구가 무엇을 할 수 있나?”라는 질문은 지나치게 넓다. 더 좋은 질문은 다음과 같다.

  1. 어떤 입력을 받는가?
  2. 어떤 출력만 보장하는가?
  3. 출력이 유효하다는 것을 어디서 확인하는가?
  4. 지원하지 않는 입력이 들어오면 어떻게 실패하는가?
  5. 부족한 능력을 다른 구성 요소로 연결할 수 있는가?

이 질문을 사용하면 “지원하지 않는다”는 답도 유용한 정보가 된다. 기능 부재는 막다른 길이 아니라 설계 경계의 좌표다.

한 도구에 모든 것을 요구하지 않는 용기

사용자는 종종 통합된 경험을 원한다. 한 명령으로 텍스트도 만들고 이미지도 만들고 파일도 저장되기를 바란다. 이 욕구는 자연스럽지만, 통합된 경험과 통합된 책임은 같은 것이 아니다.

좋은 제품은 내부적으로 여러 도구를 사용하더라도 사용자에게 단순한 흐름을 제공할 수 있다. 다만 내부 구성 요소의 역할은 분명해야 한다. 언어 모델은 의도 해석과 프롬프트 생성에 강하고, 확산 기반 이미지 생성기는 시각적 결과를 만드는 데 강하다. 운영체제는 파일과 권한을 다루고, 애플리케이션은 이 결과를 사용자에게 전달한다.

문제는 여러 도구를 쓰는 것 자체가 아니다. 문제는 연결부를 숨긴 채 모든 것을 하나의 능력인 것처럼 취급하는 것이다. 연결부가 숨겨지면 관찰 가능성이 사라진다. 실패했을 때 사용자는 어떤 단계에서 문제가 났는지 알 수 없고, 개발자도 모델을 바꿔야 하는지 파일 권한을 고쳐야 하는지 판단하기 어렵다.

여기서 투명한 조합성이라는 설계 원칙을 제안할 수 있다. 조합성은 구성 요소를 많이 붙이는 능력이 아니다. 각 구성 요소가 무엇을 보장하고, 무엇을 보장하지 않는지 알면서 연결하는 능력이다.

투명한 조합성을 가진 시스템에는 세 가지 특징이 있다.

첫째, 각 단계가 작다. 한 단계가 텍스트 생성과 이미지 생성과 저장을 동시에 책임지지 않는다.

둘째, 각 단계의 출력이 관찰 가능하다. 생성된 프롬프트, 호출된 모델, 반환된 파일 경로를 확인할 수 있다.

셋째, 각 단계의 실패가 설명 가능하다. “AI가 안 됐다”가 아니라 “프롬프트는 생성됐지만 현재 이미지 생성기는 해당 형식을 지원하지 않는다”라고 말할 수 있다.

이 원칙은 테스트에도 그대로 적용된다. 테스트가 구현 옆에 있으면 작은 규칙의 실패를 설명하기 쉽다. 통합 테스트는 전체 연결의 실패를 보여 준다. 둘은 경쟁하지 않는다. 가까운 검증과 먼 확장이 서로 다른 종류의 진실을 확인하기 때문이다.

바로 적용할 수 있는 경계 설계법

새로운 라이브러리, 모델, 자동화 도구를 도입할 때 다음 절차를 사용해 보자. 핵심은 처음부터 완성된 시스템을 만들지 않고, 가장 작은 능력 단위를 확인하는 것이다.

1. 원하는 결과를 동사로 쪼갠다

“이미지를 만들어 달라”는 문장을 “설명을 해석한다”, “프롬프트를 만든다”, “이미지를 생성한다”, “파일을 저장한다”, “화면에 표시한다”로 나눈다. “기능을 추가한다”는 말도 “입력을 읽는다”, “계산한다”, “오류를 반환한다”, “결과를 저장한다”로 분해한다.

2. 각 동사의 담당자를 지정한다

담당자가 불명확한 동사는 나중에 장애가 된다. 현재 도구가 직접 담당하지 못한다면 다른 도구를 연결하거나 요구사항을 바꿔야 한다.

3. 가장 가까운 곳에 작은 검증을 둔다

함수 규칙은 함수 옆에서 테스트하고, 모델의 입력과 출력은 호출 직후 검사한다. 파일 생성은 파일이 생성되는 즉시 확인한다. 검증을 마지막에 몰아넣지 말고 결과를 만든 지점에 붙인다.

4. 경계 사이에 계약을 기록한다

텍스트 출력은 어떤 형식이어야 하는가? 이미지 생성기는 어떤 입력을 받을 수 있는가? 파일은 어느 경로에 저장되는가? 계약이 문서나 코드로 남아 있으면 다른 구성 요소를 교체하기 쉬워진다.

5. 실패 메시지를 능력의 언어로 작성한다

“실행 실패”보다 “현재 실행 환경은 이미지 출력을 제공하지 않음”이 훨씬 낫다. 실패는 사용자에게도 개발자에게도 시스템의 지도를 제공해야 한다.

핵심 정리

  1. 도구의 기능 목록보다 경계의 선명함을 먼저 확인하라. 무엇을 할 수 있는지뿐 아니라 무엇을 할 수 없는지 기록한다.
  2. 변경 지점과 검증 지점을 가깝게 두라. 구현 옆의 테스트와 호출 직후의 출력 검사는 원인 추적 비용을 줄인다.
  3. 가까운 검증과 먼 확장을 구분하라. 작은 규칙은 내부에서 검증하고, 부족한 능력은 명시적인 계약으로 다른 도구와 연결한다.
  4. 통합된 사용자 경험과 분리된 내부 책임을 함께 설계하라. 사용자에게는 단순하게, 시스템 내부에는 투명하게 만든다.
  5. 지원하지 않는 기능을 실패가 아닌 좌표로 받아들여라. 한 도구의 한계는 전체 시스템의 역할 분담을 설계하게 해 준다.

결론: 좋은 시스템은 경계를 감추지 않고 사용한다

우리는 종종 더 강력한 모델, 더 많은 기능, 더 자동화된 도구를 찾는다. 그러나 실제로 신뢰할 수 있는 시스템을 만드는 데 필요한 것은 무한한 능력이 아니다. 각 능력이 어디에서 시작되고 끝나는지 알 수 있는 구조다.

구현 옆에 테스트를 두는 선택은 코드와 검증 사이의 거리를 줄인다. 텍스트 모델과 이미지 생성기를 구분하는 선택은 서로 다른 능력 사이의 경계를 선명하게 만든다. 전자는 가까운 검증의 기술이고, 후자는 먼 확장의 기술이다. 둘을 함께 사용하면 시스템은 작게 확인하면서도 크게 확장할 수 있다.

강력한 도구는 모든 일을 하는 도구가 아니다. 자신의 한계를 드러내면서 다른 도구와 정확히 협력하는 도구다.

결국 설계의 질문은 “이 도구가 무엇을 더 해낼 수 있는가?”에서 끝나지 않는다. 더 중요한 질문은 이것이다. 어디까지를 이 도구에 맡기고, 어느 지점에서 다른 능력을 호출하며, 그 경계를 얼마나 빨리 검증할 것인가? 이 질문을 습관으로 만들면 테스트 구조도, AI 파이프라인도, 우리가 만드는 제품의 신뢰성도 달라진다.

Sources

← Back to Library

Hatch New Ideas with Glasp AI 🐣

Glasp AI allows you to hatch new ideas based on your curated content. Let's curate and create with Glasp AI :)

Start Hatching 🐣