2026-06-26 회고
오늘은 source-to-AST 입력 흐름을 문서화하면서, “소스코드를 실제로 어떻게 LLM 판단까지 넘길 것인가”를 정리했다.
단순히 문서만 쓰는 날은 아니었다. Godot 관련 데이터 수집도 실시간으로 같이 진행 중이라, 문서가 추상적인 설계도로만 남으면 안 됐다. 지금 수집되는 데이터가 실제로 어떤 경로를 타고, 어떤 단위로 쪼개지고, 어떤 요청으로 이어져야 하는지를 확인하는 기준이 필요했다.
왜 이 설계를 먼저 정리하려 했는가
이 설계를 먼저 문서화하려 했던 이유는, 이전 작업에서 AI가 코드를 이상하게 작성하거나 요청 범위를 임의로 바꿀 수 있다는 불안이 있었기 때문이다.
특히 Markdown 전체를 보내야 하는데 앞부분 일부만 보내는 식으로 구현하거나, 내가 원하지 않은 하드코딩을 넣거나, 파일 전체를 봐야 하는데 “핵심 코드”만 골라 보내는 방식으로 흐를 수 있다는 점이 계속 신경 쓰였다.
그래서 바로 코드를 짜기보다, 먼저 “AI에게 어떤 요청을 해야 하는지”, “파일을 어떤 단위로 펼쳐야 하는지”, “AST Parser에는 무엇을 넣고 Retriever에는 무엇을 바로 넣을지”, “LLM 호출에는 어떤 조합이 들어가야 하는지”를 문서로 고정하려 했다.
요즘은 구현 자체보다도, AI에게 지시를 어떻게 해야 의도가 덜 왜곡될지 계속 고민하게 되는 것 같다. 같은 요구라도 범위를 어떻게 고정하고, 어떤 표현을 금지하고, 어떤 증거를 확인하게 만들지에 따라 결과가 크게 달라진다.
이번 문서는 단순한 개발 계획서라기보다, 이후 AI에게 구현을 맡길 때 요청이 흐려지지 않게 하기 위한 기준선에 가깝다. AI가 임의로 입력을 줄이거나, 핵심 코드만 골라 보내거나, 요청하지 않은 파일을 수정하지 않도록 하기 위해 먼저 생각을 정리한 것이다.
오늘 기준
소스코드는 # <상대경로>/<상대경로> 형태의 헤더로 펼치는 방식이 필요하다고 봤다. 이 헤더의 목적은 프롬프트에 장식처럼 넣기 위한 것이 아니라, 파일이 어떤 경로에서 왔고 이후 어떤 조각으로 쪼개져 Retriever까지 넘어가는지 추적하기 위한 것이다.
처음부터 내가 생각한 방향은 GitHub 레포지토리를 경로 순서대로 펼치고, 제외할 파일은 제외하되, 무엇이 제외됐는지 웹 UI나 로그에서 보이게 하는 구조였다. 그 다음 남은 파일을 읽을 수 있는 단위로 쪼개고, 각 조각이 어떤 원본 파일에서 나온 것인지 계속 추적해야 한다고 봤다.
문서화 과정에서 AI가 계속 잘못 해석한 지점은 “전체 파일을 한 번에 보낼 것인가, 핵심 코드만 보낼 것인가” 같은 이분법이었다. 내가 생각한 것은 그게 아니라, 파일을 경로 기준으로 펼친 뒤 조각 단위로 순서 있게 잘라 보내는 흐름이다.
내 기준에서는 .gd 파일이 AST Parser로 들어가는 대상이다. AST Parser는 .gd 안의 a 함수, b 함수, c 함수, d 함수처럼 파싱 가능한 단위를 순서대로 잘라내야 한다. 함수 단위가 애매한 경우에는 코드 조각 단위로 순서대로 잘라 보내면 된다. 핵심은 “핵심 함수만 임의로 고르는 것”이 아니라, 원본 순서와 경로를 유지하면서 조각화하고 그 조각이 Retriever로 넘어가는 과정을 추적하는 것이다.
반대로 .md처럼 이번 소스코드 분석에서 제외하기로 한 파일은 제외 목록으로 빠져야 한다. 중요한 것은 제외된 사실이 사라지면 안 된다는 점이다. 어떤 파일이 어떤 기준으로 제외됐는지 웹 UI나 로그에서 보여줘야 한다. 제외하지 않는 텍스트성 설정 파일이 있다면 AST Parser를 거치지 않고 줄, 문단, key-value, node/resource/connection 같은 단위로 나눠 Retriever로 바로 들어가는 쪽이 자연스럽다.
정리하면 현재 흐름은 다음에 가깝다.
repository path order
-> "# <relative/path>" file expansion for tracking
-> excluded file list visible in UI/log
-> .gd files to AST Parser
-> AST Parser emits ordered function/code chunks
-> excluded files are recorded with reason
-> non-.gd allowed text/config files emit ordered chunks
-> each chunk goes to Retriever with source path metadata
-> prompt + current chunk + retrieved evidence
-> LLM judgment
-> validation
-> accumulated project-level resultAI 해석을 뜯어고친 부분
중간에 AI가 repository_file_manifest 같은 별도 구조를 만들었는데, 이건 내가 생각하던 방향과 달랐다. 필요한 것은 별도 manifest 저장소가 아니라, # <상대경로> 헤더로 펼친 파일 흐름을 기준으로 어떤 파일이 제외됐고, 어떤 파일이 어떤 조각으로 쪼개졌고, 그 조각이 Retriever에 어떤 순서로 들어갔는지 추적하는 것이다.
바이너리나 에셋도 “읽지 않는다”라고 정리하면 이상하다. 핵심은 원본 bytes를 LLM에 넣지 않는다는 것이지, 그 파일이 프로젝트 판단에서 완전히 사라진다는 뜻은 아니다. .tscn, .import, README 같은 텍스트 조각 안에서 에셋 경로가 등장하면, 그 조각을 기준으로 판단하면 된다.
또 하나 필요하다고 느낀 부분은 전송 디버깅이다. AI가 .gd 파일에서 핵심 함수만 골라 보내는 식으로 흐르면 안 된다. # <상대경로>로 펼친 파일이 AST Parser에서 어떤 함수/코드 조각으로 나뉘었고, 그중 어떤 조각이 몇 번째로 Retriever에 넘어갔는지 diff나 sha256 같은 방식으로 확인할 수 있어야 한다.
PR 리뷰를 보며 정리한 점
PR 리뷰를 보면서 llm_judgment_request가 문서 안에서 두 번 다르게 정의된 문제가 드러났다는 생각이 들었다. 한쪽은 chunk_text, chunk_kind, retrieved_evidence 중심이고, 다른 쪽은 chunk_code, surrounding_context, judgment_contract까지 포함하고 있었다.
이런 식으로 같은 요청 객체가 문서 안에서 다르게 정의되면, 나중에 구현할 때도 흔들릴 수밖에 없겠다는 생각이 들었다. 요청 스키마는 하나로 맞춰야 한다. 특히 AST chunk와 direct retrieval chunk를 구분하려면 chunk_kind는 필요하고, LLM 판단을 검증하려면 retrieved_evidence와 judgment_contract도 함께 정리되어야 한다.
Qwen 리뷰에서는 README 링크나 25일 문서 관련 오타, 링크 같은 의견도 나왔다고 확인했다. 하지만 25일 문서나 workflow가 PR diff에 들어간 것은 내가 의도한 작업이 아니었다. AI가 임의로 건드린 변경이 섞였고, 나는 그것을 발견한 뒤 원복을 요구했다.
범위가 섞였던 문제
오늘 PR diff에서 25일 문서와 .github/workflows/qwen-code-pr-review.yml이 들어간 것을 발견했다. 이건 내가 요청한 변경이 아니었다. AI가 임의로 파일을 변경하거나 삭제한 것처럼 보였고, PR 화면에서는 다음 파일들이 변경되거나 삭제된 것처럼 보였다.
.github/workflows/qwen-code-pr-review.ymldocs/observations/2026-06-25-qwen-markdown-classification-observation.mddocs/retrospectives/2026-06-25-source-analysis-scoring.mddocs/roadmaps/2026-06-25-qwen-pr-review-workflow.md
그래서 해당 변경을 원복하라고 요구했다. 이후 해당 파일들은 origin/main 기준으로 원복됐고, PR diff는 README.md와 docs/roadmaps/2026-06-26-source-to-ast-input-flow.md 중심으로 정리됐다.
이 과정을 보면서, AI에게 문서 작업을 맡길 때도 변경 범위를 먼저 강하게 고정해야 한다는 생각을 하게 됐다. 회고나 로드맵 문서를 쓰는 일도 코드 변경처럼 PR 범위를 관리해야 한다.
오늘의 결론
오늘 다시 확인한 핵심은 “경로별로 펼친 파일이 어떤 기준으로 제외되고, 어떤 조각으로 쪼개지고, 그 조각이 어떤 순서로 Retriever와 LLM 판단까지 넘어가는가”였다. 전체 파일을 한 번에 넣는 것도 아니고, 핵심 코드만 임의로 고르는 것도 아니다.
지금 기준은 다음처럼 잡는다.
- 파일은
# <상대경로>헤더로 펼치고, 이 헤더는 원본 경로와 조각 추적용으로 쓴다. - 제외한 파일은 웹 UI나 로그에서 확인할 수 있어야 한다.
.gd는 AST Parser로 보내고, AST Parser가 함수나 코드 조각을 원본 순서대로 만든다..md처럼 제외하기로 한 파일은 제외 목록에 남기고, 웹 UI나 로그에서 확인할 수 있어야 한다.- 제외하지 않는 텍스트성 설정 파일은 AST를 거치지 않고 줄, 문단, 설정 블록 같은 단위로 조각화한다.
- 각 조각은 source path, chunk order 같은 추적 정보를 가지고 Retriever로 넘어간다.
- LLM 호출은
프롬프트 + 현재 조각 + Retriever 검색 결과단위로 여러 번 수행한다. - 프로젝트 판단은 처음부터 여러 조각의 판단 결과가 쌓인 뒤에야 가능하다고 보고 있었다.
데이터 수집은 계속 진행 중이다. 그래서 앞으로의 문서는 단순히 “그럴듯한 아키텍처”가 아니라, 실제 수집 데이터가 어떻게 들어가고 어떻게 검증되는지 확인하는 기준이어야 한다.