#2 - ChatGPT에게도 소스를 보여주면 해결될 줄 알았다

지난 글의 마지막에는 한 가지 질문을 남겼다.

ChatGPT도 소스를 보면 되는 것 아닐까?

생각만 하면 가장 단순한 해결 방법이었다. MyStock의 실제 Repository를 가장 잘 아는 것은 Codex였다. 반대로 나는 오랫동안 ChatGPT와 프로젝트의 목적과 방향을 이야기해 왔지만, ChatGPT는 현재 소스를 직접 보고 있지 않았다. 그렇다면 ChatGPT에게도 Repository를 보여주면 둘 사이의 정보 차이가 사라질 것처럼 보였다. 그런데 이 방법을 생각할수록 조금 이상했다.

내가 필요했던 것은 소스를 볼 수 있는 새로운 AI가 아니었다

MyStock을 개발하면서 ChatGPT와 나눈 이야기는 단순히 기능 요구사항만이 아니었다. 왜 이 프로그램을 만들기 시작했는지, 내가 Python 소스를 직접 작성하거나 세세하게 읽지 않는 실험을 왜 하고 있는지, 어떤 구조는 받아들일 수 있고 어떤 구조는 싫어하는지, 어디까지 AI에게 위임하고 어디에서 내가 판단할 것인지 같은 기준이 긴 대화 속에 계속 쌓였다.

 

그 과정이 항상 매끄러웠던 것도 아니다. 내가 원하는 방향을 제대로 이해하지 못하면 다시 설명했고, 엉뚱한 방향으로 해석하면 수정했고, 같은 실수가 반복되면 왜 그 판단이 잘못됐는지를 다시 이야기했다. 말 그대로 프로젝트의 목적과 정의, 방향성을 계속 대화를 통해 맞춰온 셈이다. 그런데 Repository를 직접 볼 수 있다는 이유만으로 다른 작업 환경이나 다른 AI를 사용한다면 문제가 하나 생긴다.

그동안 쌓아온 이 맥락을 또 처음부터 설명해야 하는 것 아닐까?

같은 OpenAI 계열의 AI라고 해도 내가 실제로 대화하는 ChatGPT 환경과 Codex의 작업 환경은 동일한 상대처럼 느껴지지 않았고, 어떤 모델을 사용하느냐만의 문제가 아니었다. 접근할 수 있는 정보가 다르고, 누적된 대화 맥락이 다르면 실제 판단에 사용할 수 있는 정보도 달라진다. 나는 소스를 볼 수 있는 새로운 AI가 필요했던 것이 아니다.

지금까지 MyStock을 이해시킨 ChatGPT에게 현재 프로젝트를 판단하는 데 필요한 만큼의 정보만 보충하고 싶었다.

그렇다고 ChatGPT에게 Repository 전체를 다시 읽히는 것도 이상했다

다음으로 생각한 방법은 현재 대화의 ChatGPT에게 Repository 전체를 분석하게 하는 것이었다. 이 방법도 가능은 하다. 실제 소스를 읽으면 현재 구조를 훨씬 정확하게 알 수 있다. 하지만 그러면 Codex가 이미 하고 있는 일을 ChatGPT가 다시 하게 된다.

                 Repository
                  ↙      ↘
             ChatGPT     Codex
                ↓          ↓
             코드 분석   코드 분석
                ↓          ↓
                  나

Codex는 구현 작업을 위해 Repository를 직접 분석한다. 관련 파일을 찾고, 의존 관계를 확인하고, 변경한 뒤 테스트까지 수행한다.

ChatGPT까지 매번 같은 Repository를 처음부터 분석한다면 프로젝트가 커질수록 두 AI가 같은 정보를 각자 다시 읽는 일이 늘어난다. Context와 Token을 더 사용하는 문제도 있지만, 그보다 역할 자체가 겹친다는 점이 마음에 들지 않았다.

ChatGPT를 두 번째 Codex로 만들고 싶지는 않았다.

내가 ChatGPT에게 기대하는 역할은 Python 구현을 대신 검증하는 것이 아니었다. 현재 상황을 놓고 나와 문제를 정리하고, 선택지를 비교하고, 다음에 Codex에게 무엇을 요구할지 함께 판단하는 쪽에 가까웠다. 그렇다면 Codex와 똑같은 코드 해상도가 정말 필요한가? 이 질문에서 방향이 조금 바뀌었다.

예전에 만든 devlog가 엉뚱한 곳에서 다시 필요해졌다

MyStock에는 devlog라는 개발 기록이 있다. 처음 이 기록을 만들 때의 목적은 지금과 달랐다. 다른 AI가 프로젝트를 이어서 분석해야 할 때, 이전 개발 과정과 판단을 전달하면 분석 품질이 얼마나 달라지는지 확인해보려는 실험에 가까웠다. 당시에는 이것을 현재 ChatGPT를 위한 문서라고 생각하지 않았다.

 

그런데 이번 문제를 놓고 다시 보니 상황이 묘하게 같았다. ChatGPT는 MyStock의 긴 프로젝트 역사와 내가 했던 판단을 많이 알고 있었지만 현재 소스를 직접 보고 있지 않았다. 소스 기준으로 보면 ChatGPT 역시 프로젝트의 현재 상태를 인수인계받아야 하는 또 다른 AI였다. 심지어 대화방이 바뀌면 같은 ChatGPT를 사용하더라도 프로젝트 맥락의 해상도가 항상 같다고 기대하기 어려웠다. 원래 다른 AI의 인수인계를 위해 만들어둔 기록이 정작 내가 계속 대화하던 ChatGPT의 Context를 복원하는 데 필요해진 셈이었다.

소스를 전부 읽는 대신 프로젝트의 지도를 보기로 했다

그래서 Repository 전체 소스를 읽히기 전에 다른 방법을 시험해봤다. GitHub를 Read-only로 연결하고, 먼저 devlog를 확인했다. 그리고 소스 본문이 아니라 Repository의 디렉터리와 파일 구조를 확인했다. 필요하다면 최근 PR에서 어떤 파일이 변경됐는지 정도까지 확인하는 방식이다.

Repository Topology
"어디에 무엇이 있는가"

        +

devlog
"왜 그렇게 되었는가"

        ↓

ChatGPT
"현재 프로젝트 구조 복원"

두 정보의 역할은 달랐다. Repository의 구조는 지금 어디에 어떤 책임이 놓여 있는지를 보여준다. devlog는 왜 그 책임이 그곳으로 이동했고, 어떤 판단을 거쳐 현재 구조가 되었는지를 설명한다.

어디에 무엇이 있는가 + 왜 그렇게 되었는가.

이 두 가지를 합치면 Python 구현을 한 줄씩 읽지 않아도 현재 프로젝트를 논의하기 위한 구조적 맥락을 상당 부분 복원할 수 있었다. 목표는 Codex와 동일한 수준으로 코드를 이해하는 것이 아니었다.

다음 판단을 잘못하지 않을 정도의 구조적 해상도만 복원하면 됐다.

1편에서 틀렸던 features 해석도 소스를 읽지 않고 바로 교정됐다

이 방식이 의미가 있는지는 이전에 실제로 발생했던 오해에서 확인할 수 있었고, 리팩토링 과정에서 features/account가 gui/dashboard_model을 참조하는 역의존을 제거하는 작업이 있었다. 당시 ChatGPT는 Codex의 결과 설명만 보고 features를 데이터나 도메인에 가까운 계층처럼 해석했다. 설명 자체만 보면 그럴듯했지만 실제 Repository 구조를 확인하지 않은 추론이었다.

 

Repository의 topology를 확인하자 features 아래에는 account, analysis, etf, market, quote, refresh, trades처럼 MyStock의 기능 책임 단위가 배치되어 있었다.

features/
├─ account
├─ analysis
├─ etf
├─ market
├─ quote
├─ refresh
└─ trades

이 정도만 확인해도 features를 특정 데이터 계층으로 단정하는 것보다 기능 책임 단위로 보는 것이 실제 구조에 가깝다는 것을 알 수 있었다. 중요한 점은 이 판단을 교정하기 위해 Python 구현을 읽을 필요가 없었다는 것이고,  1편에서는 이 사건을 AI가 부족한 정보 위에서 그럴듯한 설명을 만들 수 있는 사례로 봤다. 이번에는 반대로, 그 부족한 정보 중 무엇을 보충하면 되는지를 확인한 셈이었다.

devlog만으로도 생각보다 많은 것이 복원됐다

리팩토링 과정에서 작성된 devlog를 몇 개 확인해보니 예상보다 많은 정보를 다시 구성할 수 있었다. MainWindow의 책임이 어떤 방향으로 줄어들었는지, Controller와 Store가 왜 분리됐는지, ETF와 Trade 관련 lifecycle이 왜 별도 Controller로 이동했는지, 비슷해 보이는 Controller들을 왜 무리하게 하나의 공통 구조로 합치지 않았는지 같은 판단 흐름을 다시 따라갈 수 있었다.

 

QThread 관련 종료 문제를 어떤 기준으로 분석했고, 어느 시점을 리팩토링의 기준점으로 잡았는지도 개발 기록을 통해 확인할 수 있었다.

반면 실제 Python 구현의 세부 내용은 여전히 거의 알지 못했다. 그런데 이번에는 그것이 문제가 아니었다.

 

나는 ChatGPT가 Codex 대신 코드를 리뷰하기를 원한 것이 아니었다. 앞으로 어떤 구조를 허용할지, 다음 작업에서 무엇을 요구할지, 지금 제안이 기존 판단과 충돌하지 않는지를 나와 이야기할 수 있을 정도면 됐다.

그런데 devlog에도 빈칸은 있었다

여기까지 오니 devlog의 장점과 한계도 조금 다르게 보였기 때문에 개발 기록은 어떤 문제가 있었고, 왜 구조를 바꿨고, 어떤 판단을 했는지를 남기는 데 강했다. 즉 devlog는 이런 질문에 잘 답했다.

어떻게 여기까지 왔는가?

하지만 여러 단계의 리팩토링이 계속 쌓이면 다른 질문이 생긴다.

그래서 지금 프로젝트 전체는 어떤 상태인가?

이 질문에 답하려면 여러 devlog와 현재 Repository 구조를 다시 조합해야 했다. 과거의 변화 과정을 기록하는 문서와 현재 위치를 보여주는 프로젝트 지도는 역할이 조금 다르다는 것을 알게 됐다. 이 문제는 아직 끝난 것이 아니며, devlog와 Repository topology를 이용해서 현재 프로젝트 상태를 더 짧고 안정적으로 전달할 수 있는 방법이 필요한지 계속 확인해볼 생각이다.

블로그에서 설명해야 할 것도 달라졌다

이 실험을 계속하면서 MyStock 개발기를 쓰는 방식도 조금 바뀌게 될 것이다. 리팩토링 과정 진행하면서 일부 반영되었지만,  내가 실제로 읽지도 않은 Python 구현을 마치 이해한 것처럼 자세하게 설명하는 것은 이 프로젝트의 기록 방식과 맞지 않았다.

 

내가 실제로 참여한 것은 다른 부분이었다. 어떤 문제가 이상하다고 느꼈는지, 왜 기존 방향을 유지하면 안 된다고 판단했는지, 어떤 선택지를 ChatGPT와 검토했는지, Codex에게 어떤 범위와 제약을 전달했는지, 결과를 실행해보고 무엇을 다시 바꿨는지 같은 과정이었다. 그래서 앞으로의 기록은 조금 더 이쪽으로 이동할 것 같다.

코드 중심 → 구조 중심 → 판단 중심.

코드를 이해하는 척하지 않는다. 대신 내가 실제로 한 판단을 기록한다.

그런데 여기까지 정리하고 나니 이상하게 익숙했다

ChatGPT와 Codex의 역할을 나누고, devlog를 만들고, GitHub를 통해 필요한 정보만 전달하고, Prompt 규칙을 계속 손보는 과정을 돌아보다가 갑자기 익숙한 느낌이 들었다. 새로운 도구를 먼저 분석하고, 기본 환경이 내 작업 방식과 맞지 않으면 필요한 부분을 감싸고, 내가 익숙하게 개발할 수 있는 환경으로 다시 정리한다.

 

생각해보니 나는 새로운 칩셋과 Vendor SDK를 받을 때마다 비슷한 일을 해왔다. 그때는 SDK를 분석하고 내가 개발하기 편하도록 Makefile이나 CMake로 빌드 시스템을 다시 구성했다. 이번에는 대상이 AI로 바뀌었을 뿐이었다.

 

이번에는 Makefile이나 CMake가 아니라 Prompt와 Markdown을 만들고 있었다. 그리고 이 이야기는 다음 글에서 이어가려고 한다.