Article - 깊게 탐구하기/Harness Engineering

[OOP 하네스 엔지니어링] 1편: 평가 방식 도입

조금씩 차근차근 2026. 4. 11. 22:00

서론

하네스 엔지니어링은 AI를 단순 "입력으로 랜덤한 출력을 받는 도구"가 아닌, 관리할 수 있는 도구로의 변화를 이끌고 있다.

 

프롬프트에서 하네스까지 — AI 에이전틱 패턴 4년의 기록

엔지니어링의 엄밀함은 사라지지 않는다 — 이동할 뿐이다. AI 에이전틱 패턴 4년의 기록

bits-bytes-nn.github.io

하지만, 이미 돌아가고 있는 기존 서비스에 하네스를 적용하기 위해선, 기존 코드에 하네스 관련 도구가 준비되어 있어야 한다.

당연히 현재는 그렇지 않기 때문에, 하네스 엔지니어링이 실무자에게 적극적으로 선택되지는 않는다.

 

하지만, 분명히 하네스 엔지니어링은 개발 패러다임의 전환을 이끌고 있다.

코드 레벨까지 뜯어보며 리뷰하는 것에서 벗어나, 점차 리뷰 수준을 LLD→HLD→SRS(PRD) 수준까지 단순화할 수 있다는 것은 분명 큰 변화이다.

 

따라서 기존에 잘 돌아가던 각 서비스에 Harness 환경을 구축해야 하는데, 이를 사람이 직접 하기에는 공수가 매우 많이 든다.

그렇다고 이를 LLM에게 전적으로 맡기는 것은 "객관적인 근거"를 제시하지 못한다.

이를 객관적으로 평가하기 위해선, Observability 관점의 도입이 시급한 상황이다.

 

이러한 Observability를 확보하기 위해선 크게 다음 두 가지 관점을 고려할 수 있다.

  • 들어오는 트래픽을 완전히 Shadowing 하여, Harness로 구현한 산출물이 실제 동작하고 있는 구현체와 완전히 동일하게 동작하는지 검증한다.
  • 간단한 테스트 케이스로 복잡한 코드를 Harness 를 위한 문서로 바꾸는 도구를 만들어, 원본 문서에 최대한 가깝게 생성할 수 있는지 검증한다.

둘 중 어느쪽이든, 하나라도 가능해진다면 현재 서비스에 Harness에 접목시킬 수 있게 된다.

 

DoD(Definition Of Done)

  • 논리적 아키텍처와 기능 요구사항에 집중하여 검증한다.
  • 물리적 아키텍처와 비기능 요구사항은 주요 지표로 두지 않는다.
  • 원본 문서와, 하네스 엔지니어링으로 생산한 산출물에서 역산한 문서 간의 일치율을 평가하기 위한 기준을 수립한다.
  • 원본 문서와 역산한 문서 간의 일치율을 최적화하는 것은 이번 글에서 포함하지 않는다.

풀 문제의 정의

보통 Software Design에서 HLD와 LLD를 먼저 작성하고, 그래서 이대로 하네스를 제어하길 원한다.

하지만, HLD/LLD는 프로젝트 진행 순서의 영역이라고 생각한다.

  • HLD에서 소프트웨어 계약 수준(DB 스키마, API, etc.)의 결정을 수행하고
  • LLD에서 해당 계약을 구현할 방법을 결정한다.

그래서 정확히 누락 없이 작성되었는가?는 HLD/LLD의 영역이 아니라고 생각한다.

이를 파악하기 위해선 소위 짬(경험)이 있어야 리스트업 및 검증이 가능하다.

 

여기에 있어서, 완전한 하네스로 넘어가는 건 아직 내 실력으로는 부족하다.

결국 문제를 조기에 발견하는 피드백 루프가 하네스의 정교함을 만든다고 생각한다.

따라서 문서가 어느정도 리뷰하기 쉽게 작성되어야, 빠른 리뷰를 수행해 하네스를 제어할 수 있다고 생각한다.

 

이에 있어서, OOP(Object Oriented Paradigm)는 AI모델도 잘 알고 있고 익숙한, 비교적 엄격하고 명확한 문서화 방법 중 하나이다.

그래서, 이번 프로젝트에선 우선 OOP을 집중적으로 다룰 예정이다.

 

이에 대한 특징은 다음과 같다.

OOP의 특징

  • 물리적 아키텍처는 다루지 않고, 논리적 아키텍처만을 다룬다.
  • 코드 레벨에 존재하는 기능을 이해하고, 기능 요구사항을 역추적하기 용이하다.

OOP의 한계

  • 물리적 아키텍처를 다루지 않기 때문에, 비기능 요구사항에 대한 처리가 어렵다.
  • OOP는 Kafka/Redis/AWS를 쓰는지를 다루지 않고, 따라서 각각의 SLO/SLA에 따른 우리 서비스의 비기능 요구사항 추적을 어렵게 만든다.

 

그렇다면 OOP 방식을 사용하지 않고, 기능 요구사항과 비기능 요구사항을 모두 다루는 HLD와 LLD를 사용하면 되는 것 아닌가? 라는 질문도 있을 수 있다.

하지만 이는 현재 DoD에 의해 지금 풀 문제를 넘어서는 영역이라 포기했다.

  • 코드 레벨에서 LLD, HLD 를 유추하는 것이 가능한가?
  • 가능하려면 "물리적 아키텍처"에 대한 정보가 코드에 담겨있어야 한다.
  • 이는 컨텍스트를 관리하는 방식을 복잡하게 만들 것이라고 유추했다.

LLM의 컨텍스트 관리 관점에서, 기능 요구사항과 비기능 요구사항은 관리해야 하는 정보가 다르다는 판단이 있어, 지금 당장 역산하기에는 쉽지 않을 것이라 판단했다.

 

작업의 계획

위에서 설명했던 대로, 원본 문서와, 하네스 엔지니어링으로 생산한 산출물에서 역산한 문서 간의 일치율을 평가할 것이다.

즉, 풀 문제와 조합하면 다음과 같이 정리할 수 있다.

 

1. OOA 에서 추출한 PRD와 원본 PRD간의 일치율 평가

2. OOD에서 추출한 OOA와 원본 OOA 간의 일치율 평가

3. OOP에서 추출한 OOD와 원본 OOD간의 일치율 평가

 

그래서 예제로는, 문제 규모를 생각해봤을 때 20개 정도의 Use Case를 원했고, 그리하여 과거 구현했던 OMyPIc을 사용해 볼 것이다.

 

[오마이픽] 나만의 OPIc 선생님, 오마이픽

이번 설의 목표는 오픽이다. 예전에 오픽 시험을 준비하고 싶다면, "오픽노잼" 동영상을 정주행하는 것을 추천받았다. 여기에 AI를 이용해 대화해보면서 오픽 연습을 하고 싶었는데, 시중에 존재

dev.go-gradually.me

 

 

사용한 플러그인은 다음과 같다.

https://github.com/GoGradually/usecase-driven-design-skills

 

GitHub - GoGradually/usecase-driven-design-skills

Contribute to GoGradually/usecase-driven-design-skills development by creating an account on GitHub.

github.com

 


1. OOA 에서 추출한 PRD와 원본 PRD간의 일치율 평가

우선 두 PRD가 어떻게 다른지를 판단하는 기준이 필요하다.

그 기준은 다음과 같이 세웠다.

 

  • Layer 1 - PRD 레벨 (거시): 제품 전략·범위·가치
  • Layer 2 - UseCase 레벨 (사용자 사용 관점): 사용자가 제품을 어떻게 사용하는가

또한, 이 PRD가 멋대로 새로운 규칙이나 Use Case 를 생성해서도 안됐다.

그렇게 생성된 규칙이 하네스를 다루는 데 불필요한 복잡도를 올릴 수 있기 때문이다.

 

그래서 다음과 같이 두 리스크를 탐색했다.

  • 누락 리스크: 원본에 존재하던 사용자 시나리오가 사라진 경우
  • 이탈 리스크: 원본에 존재하지 않던 사용자 시나리오가 임의로 추가된 경우

 

 

해당 기준은 다음 링크에서 확인할 수 있다.

 

harness-observability/compare-result/prd-comparison-checklist.md at master · GoGradually/harness-observability

Contribute to GoGradually/harness-observability development by creating an account on GitHub.

github.com

 

그래서 그 결과, 현재 사용한 UseCase-Driven-Design 플러그인의 역산 시 산출물은 다음과 같다.

Layer 1 일치율 (정규화) 약 89.8% (1.6 사용자 가치 제공 계획은 양쪽 모두 없어 N/A 처리)
Layer 2 일치율 (정규화) 약 67.2%
전체 가중 일치율 약 78%
누락 리스크 (⬅️) 1건 (성공 지표 KPI)
이탈 리스크 (➡️) 17건 (대부분 도출 가능·재형식화, 🟠 Med 4건, 🔴 High 0건)
최종 결론 핵심 의도 보존 — 파생본의 추가 규정 중 🔴 High 이탈 없음. 단, ①거시 KPI 누락, ②내부 상태 모델·엔티티 이름(PracticeTurn, ContextMessage, MistakePattern 등)의 "사용자 언어" 여부는 재검토 필요.

 

 

2. OOD에서 추출한 OOA와 원본 OOA 간의 일치율 평가

OOA 산출물은 어떤 점들 위주로 비교해야 할까?

앞서 설명했던 누락 리스크/이탈 리스크를 포함하여, 주로 Use Case와의 매핑에 집중했다.

 

그래서 현재 사용한 UseCase-Driven-Design 플러그인의 역산 시 산출물은 다음과 같다.

종합 일치율 0.77
게이트 C (needs work)
환각 경보 (외부 UC 범위 내) 없음
특이사항 내부 UC 13개가 사본에만 존재 — 환각이 아닌 OOD 기준의 정당한 세분화

 

크게 문제점은 다음과 같았다.

  • Use Case에 존재하는 사용자의 선택지가 누락
    • OOD 관점에선 사소하다고 판단된 내용들이 OOA의 핵심 사용자 편의 기능인 경우이다.
    • 기능의 중요도와 코드의 난이도는 별개이기에 나타나는 문제로 예상했다.
  • 구체적인 디자인을 알고 있다 보니 나온 구체화된 내용

해당 부분에 대한 명시적인 지시/평가용 에이전트가 필요해보였다.

3. OOP에서 추출한 OOD와 원본 OOD간의 일치율 평가

해당 부분의 경우, 명확한 기준을 찾기 어려워 2편으로 미루게 되었다.

에이전트가 한번에 작업하길 거부했다.
계속해서 초안만을 제출했고, 강제로 서브에이전트를 돌려 전부 분석을 시켜도, 일치율이 너무 낮았다.
또한, 현재 존재하는 OOD가 아닌 다른 영역에 집중하여 산출물을 제출하기도 하는 등, 퀄리티가 심각하게 떨어졌다.

즉, 별도의 워크플로우가 필요한 상황이다.

 

OOP는 결국 작성된 코드이고, 이 코드의 방대함에서 모든 OOD를 추출하는게 유의미한 작업인가 라는 의문에 기인한다.

 

위에서 보았듯, OOD와 같은 코드레벨 디자인으로 넘어가면 아래와 같은 기능들이 많아진다.

  • 코드 레벨 입장에선 if-else 수준으로 간결하다.
  • 하지만 사용자 입장에선 편의성을 위해 반드시 필요한 기능이다

결국, 코드베이스에서 OOD 문서가 아닌 OOA를 즉시 뽑아내는 기법의 필요성을 느끼고 있다.

 

아마 차주 주말까자 꾸준히 생각하고 시도해보다가 결론을 내릴 듯 하다.

(현재는 이번 주 토큰을 다 썼다.)


결론

  • PRD ↔OOA: 90%
  • OOA ↔ OOD: 77%
  • OO? ↔ OOP: XX%

 

우선 구체적인 평가 기준을 갖고, 이 역산 과정에서의 문제점을 파악한 것 만으로도 개인 프로젝트 입장에선 만족스러운 듯 하다.

방향성은 잡혔기 때문에, 퇴근하고 틈틈히 진행하면서 완성도를 끌어올리고, 개발 생산성 향상을 이루고 싶다.

 

현재까지 나온 전체 결과물은 다음 링크에서 확인할 수 있다.

 

GitHub - GoGradually/harness-observability

Contribute to GoGradually/harness-observability development by creating an account on GitHub.

github.com