AI 개발 과정에서 '설계 의도'를 출력하도록 변경한 방법
요약
AI 기반 개발 과정의 한계를 극복하기 위해, 요구사항과 설계 단계 사이에 '설계 의도'를 명시적으로 출력하는 단계를 추가했습니다. 이는 AI가 어떤 관점과 전제하에 설계를 했는지 사용자가 파악하고 검증할 수 있게 하여, 인간의 오너십을 확보하는 데 도움을 줍니다.
핵심 포인트
- AI 개발 과정에 '설계 의도' 추출 단계 도입
- A(사전 의도 제한)와 B(결과물 추측) 방식 비교
- 의도를 명시적으로 확인하여 AI 이해와 인간 이해의 괴리 해소
- RAG 질문 생성 시, 무작위성 확보를 위해 의도 파악 활용
AI에게 개발을 맡길 때, 이전에는 다음과 같은 흐름으로 진행했습니다.
요구사항 → 설계 → 구현
설계 내용에 문제가 없다면 구현 단계로 넘어가는 방식이었습니다.
하지만 개발이 복잡해지고 여러 작업을 동시에 처리하게 되자 다음 두 가지가 눈에 띄게 되었습니다.
- AI의 설계서는 정성껏 작성되지만, 분량만으로는 '어디가 중요하고 어디가 중요하지 않은지' 파악하기 어려움
- 본인의 이해와 AI의 이해가 어긋나서 엉뚱한 구현을 하게 됨
인간으로서 개발의 오너십(ownership)을 가지려면, 단순히 'AI가 구현하게 했다'는 것만으로는 충분하지 않습니다. 어떤 의도로 이 설계를 했는지를 본인이 파악하고 있어야 합니다.
설계 전후에 한 단계를 추가했습니다. 다음 중 하나입니다.
A. 요구사항 → 요구사항/설계 의도 → 설계 → 구현
B. 요구사항 → 설계 → 설계 의도(요구사항 해석) 출력 → 확인 → 구현
요구사항에서 바로 설계를 도출하게 하는 것이 아니라, '이러한 의도로 개발을 진행하면 좋다'는 요구사항 정의에 가까운 것을 한 번 출력하도록 했습니다.
실제로 사용한 프롬프트(지시어)는 다음과 같은 짧은 질문들이었습니다. A는 A의 전 단계에서, B는 생성된 결과물에 대해 사용했습니다.
# 요구사항에서 설계/구현으로 진행할 경우(A)
제 요구사항으로부터 어떤 의도를 추출하셨나요?
# 생성된 결과물에 대해(B)
...
특별한 방식으로 작성하지 않아도 충분히 설계 의도가 출력되었습니다.
A와 B에서는 출력되는 의도의 성질이 크게 다릅니다.
- A: 설계 전에 의도를 출력하게 하고, 그 의도를 전제로 설계를 하게 합니다. 의도로 AI를 제한(bind)한 상태에서 출력을 받기 때문에 제어할 수 있는 상태가 됩니다.
- B: 이미 존재하는 것에서 의도를 추측합니다. 사람이 작성한 코드든, AI가 작성한 코드든, 설계서든, 코드 내 주석이든 동일하며, 나오는 의도는 단지 추측에 불과합니다.
이후의 두 가지 예시는 둘 다 AI가 무엇을 근거로 만들려고 했는지 보기 위해 사용했습니다. B의 의도는 추측임을 전제로 하여 본인의 요구사항과 대조하며 확인하고 있습니다.
등장인물은 다음과 같습니다.
- 고객: RAG를 평가하는 사람이며, 실제로 질문을 하는 사용자이기도 합니다. 각 산업 분야의 도메인 지식은 가지고 있지만, 이번 문서의 폴더 구조는 모릅니다.
- 우리 개발팀: 답변 예시를 작성하는 사람입니다. 도메인 지식은 없지만, 폴더 계층구조(folder hierarchy)는 대략적으로 파악하고 있습니다.
- 질문 생성 AI: 우리 개발팀이 개발에 사용하는 AI입니다. RAG 내에서 실제로 답변하는 AI와는 별개의 AI입니다.
RAG 평가에서는 실제 사용자로부터의 질문이 특정 주제에 치우치기 쉽다는 문제가 있었습니다. 그래서 이번에는, 개발팀 측에서 사전에 질문과 답변 예시를 Excel로 정리하고 '이 질문에 대해 실제로 잘 답변하고 있는지'를 확인하는 방침으로 했습니다.
질문을 만드는 단계에서 오류가 발생했습니다.
- AI는 참조 문서의 내용으로부터 질문을 만들었습니다.
- RAG는 문서를 참조하면 답할 수 있도록 만들어졌습니다. 문서로부터 만든 질문은 당연히 답변될 것이 됩니다.
- 평가로서 의미 있는 질문을 만들기 위해서는, 문서 내용에 끌려가지 않는 어느 정도의 무작위성(randomness)이 필요했습니다.
이 의도가 AI에게 전달되지 않았습니다. 그래서 '지금 질문 생성의 설계 의도는 무엇인지'를 출력하게 했더니, 인식 차이가 명확해졌습니다.
그 후, 다음 방침으로 재정리했습니다.
- 우리 개발팀은 대상 분야의 도메인 지식이 없습니다.
- 하지만 문서를 모은 폴더의 계층(폴더 트리)을 보면 어느 정도 어떤 분야의 자료인지 파악할 수 있습니다.
- 고객은 도메인 지식은 가지고 있지만, 폴더 구조는 모릅니다. 이 '고객은 구조를 모른다'는 차이가 개발팀이 폴더 계층에서 분야를 추측하여 질문을 만드는 의미가 됩니다.
- 즉, 질문은 문서의 본문이 아니라, 폴더 계층에서 읽어낼 수 있는 분야 정보를 바탕으로 만들어야 합니다.
설계서를 그대로 읽었다면 아마 알아차리지 못했을 차이입니다. 설계 의도를 별도로 출력하게 함으로써 '무엇을 근거로 질문을 만들려고 하는지'를 한눈에 확인할 수 있었습니다.
개인적으로 YouTube나 X의 동영상을 다운로드할 수 있는 앱을 만들고 있습니다. X 같은 경우 로그인을 하고 연동하지 않으면 다운로드가 거부되어 에러가 나기 때문에, 로그인 기능이 필요했습니다.
- 제 의도: 이미 로그인된, 열려있는 브라우저로부터 로그인 세션 정보를 가져오는 것
- 실제로 구현된 것: '로그인' 버튼을 누르면, 로그인이 안 된 새로운 브라우저가 열리고, 거기서 다시 로그인 작업을 해야 하는 구현
의도(意図)와 다른 구현이 되어 있었기 때문에, 수정하기 전에 '현재 설계 의도는 어떻게 되나요?'라고 출력하게 하여 AI의 해석과 저의 의도가 어긋남을 확인한 후에 수정을 진행했다.
신규 기능 개발 시에는 설계 전후에 반드시 설계 의도를 확인하는 것을 (저의 운영 규칙으로) 삼고 있다.
설계 의도 출력을 거치니 품질이 올라간다고 느끼지만, 이는 이번 환경에서의 체감일 뿐 비교 검증을 거친 결과는 아니다.
AI 코딩에서는 기존 기술 부채에 더해 새로운 부채가 언급되고 있다.
기술 부채: 설계의 타협이나 저품질 코드 때문에 미래 수정 비용이 늘어나는 상태(@IT, Zenn) -
이해 부채: 코드는 작동하지만, 왜 그렇게 작동하는지 사람이 설명할 수 없는 상태. AI 생성 코드를 충분히 이해하지 못한 채 도입하면 유지보수나 수정 비용이 축적된다(Zenn, @IT) -
인지 부채: AI에게 사고를 너무 위임하여 시스템 전체 설계를 파악하는 능력이 떨어지는 상태(@IT). SO Technologies의 기사에서는 개인이나 팀이 가지고 있던 코드에 대한 이해가 사라져 가는 것으로 설명하고 있다. -
의도 부채(意図的負債): 시스템을 어떻게 발전시킬지에 대한 근거, 목표, 제약이 사라져 가는 상태. AI는 '무엇을 만들지'는 출력하지만 '왜 그렇게 만들었는지'는 출력하지 않기 때문에, 코드 생성량에 비례하여 쌓인다고 한다. 완화책으로는 중요한 아키텍처상의 결정을 기록하는 ADR이나 목적을 파악하는 BDD가 언급되고 있다(SO Technologies)
Addy Osmani는 이해 부채를 시스템 내에 존재하는 코드의 양과 사람이 실제로 이해하고 있는 양 사이의 벌어지는 차이로 설명한다. 코드는 깨끗해 보이고 테스트도 통과하며 개발 속도의 지표도 좋아 보여서, 기술 부채와 달리 알아차리기 어렵다는 점이 특징으로 꼽힌다.
- 설계서를 끝까지 읽을 수 없는 상태는 이해 부채가 쌓이기 시작하는 입구라고 판단했다.
- 설계 의도 출력은 구현 전에 사람이 의도를 확인하는 수단이며, 이해 부채 및 의도 부채에 대한 예방책으로 위치 지어졌다.
- 설계 의도를 ADR에 남기는 것은 의도 부채 대책으로 제시된 수단과 겹친다.
위의 연결고리는 저 자신의 해석이다. 참고 기사가 AI에게 설계 의도를 출력하도록 권장하는 것은 아니다.
구현 후 결과 출력은 아직 실시하지 않았다. 향후 검토 사항이다.
생각하고 있는 것: 설계 의도와 구현 결과를 대조하면, 의도대로 구현되었는지 판단할 수 있다.
검토하고 있는 방법: 구현 후의 결과를 처리 흐름이 파악되는 형태로 HTML로 출력하게 한다. 마크다운보다 슬라이드에 가까운 표현을 할 수 있어 보기 좋게 나올 것이라고 생각한다.
현시점 상태: 가설이며, 미검증
설계 의도와 구현 결과의 차이점을 확인하는 운영이 가능하다면, 이해 부채 및 기술 부채를 남기지 않는 것으로 이어질 것이라 생각한다.
이 글은 저 자신의 인식을 기록하는 메모가 주 목적이지만, 이 장(章)은 마찬가지로 설계 의도를 남기지 않고 진행해버린 사람에게도 조언으로 읽힐 수 있도록 작성했다. 축 1의 출력을 ADR 등에 남겨두었다면, 이런 상황은 일어나기 어려울 것이다.
설계 의도를 출력하지 않은 채 AI와의 대화로 구현을 진행해 버렸다. 나중에 '왜 이 설계를 했는지', '여기는 다른 형태로 하는 것이 좋지 않을까'라고 다시 생각하게 된다.
제가 기억하는 당시의 AI와의 대화-
ADR(아키텍처 디시전 레코드): 저는 당시의 판단과 이유를 ADR에 남기는 경우가 많아서, 나중에 '왜 이 설계를 했는지'를 확인할 수 있다.
이것들을 현재 구현과 비교해 보면, '당시 설계와 실제로는 차이가 있다', '여기에 맞추는 것이 좋겠다' 같은 점을 발견할 수 있고, 리팩토링으로 연결된다.
코드로부터 설계 의도를 역산하는 것도 가능하지만, 거기서 나오는 의도는 추측이다. 당시의 판단 그 자체가 아니라, AI가 나중에 붙인 이유일 수도 있다. ADR이나 기억과 대조하여 사용하는 것이 안전하다.
| 축 1 | 축 2 |
|---|---|
| 상황 | 신규 기능 개발 |
| ... | |
| 축 2는 축 1을 하지 않았던 구현에 대한 구제책이라는 위치 지어졌다. 축 1의 출력을 남겨두면, 축 2의 상황은 줄어들 것이다. |
- 신규 기능 개발 시에는 설계 전후에 설계 의도(요구사항 해석)를 출력하게 한다.
- 출력된 의도를 읽고 자신의 인식과 어긋나지 않는지 확인한다.
- (향후 검토) 구현 후 결과를 출력하게 하여, 설계 의도와의 차이점을 확인한다.
- 판단의 이유는 ADR에 남긴다.
- 설계 의도를 출력하지 않은 과거 구현을 검토할 때는 기억과 ADR을 단서로 삼는다. 역산한 의도는 추측으로 취급한다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기