2026-06-25 소스 분석과 Markdown 분류 회고
오늘은 공식문서 Markdown을 세 JSONL 테이블로 나누는 기준을 다시 정리했다.
처음에는 Godot 공식문서 Markdown을 docs_chunks, api_mapping, label_prototypes 세 테이블로 나누는 방향을 생각했다. 하지만 docs_chunks와 api_mapping은 역할이 분명한 반면, label_prototypes는 무엇을 기준으로 써야 하는지 경계가 흐렸다.
처음에는 세 테이블의 경계가 흐렸다. 이후 흐름도를 다시 보면서 세 테이블 모두 같은 방식으로 공식문서 Markdown을 JSONL로 분류해 저장하는 대상이라는 위치를 스스로 정리했다.
정리한 결론은 다음과 같다.
docs_chunks는 Godot 4 공식문서 근거다.api_mapping은 Godot 3 -> Godot 4에서 함수명, 클래스명, 심볼명이 어떻게 바뀌었는지 저장하는 JSONL 대상이다.label_prototypes는 함수 사용 방식, 인자 구성, 호출 패턴이 통째로 바뀐 경우 어떻게 써야 하는지 저장하는 JSONL 대상이다.
앞으로는 파일시스템 단위로 Godot 프로젝트를 분석한다. .gd, .tscn, .tres, project.godot 등을 AST/코드 조각 단위로 나누고, 필요한 공식문서 JSONL 근거를 사용한다. 이후 Qwen 3.6을 온디맨드로 호출해 해당 조각이 Godot 3인지, Godot 4인지, 마이그레이션이 필요한지, 코드 설명 데이터로 쓸 수 있는지 판단한다.
이 판단 결과를 score DB에 저장하고, 프로젝트 단위로 Godot 3/Godot 4/mixed/unknown 파일시스템을 분류한다. 이후에는 분류된 파일시스템을 기반으로 SFT와 DPO를 설계할 소스로 만들 예정이다.
관련 로드맵:
docs/roadmaps/2026-06-25-source-analysis-scoring-architecture.mddocs/roadmaps/2026-06-25-markdown-jsonl-llm-classification.md
Markdown 분류 초기화
오늘 Markdown -> JSONL 분류 결과를 폐기했다.
이유는 분류 단계에서 Markdown 전체가 아니라 앞 3000자만 LLM에 전달되고 있었기 때문이다. 사용자의 의도와 요구는 처음부터 공식문서 전체를 보고 분류하는 것이었다. 하지만 LLM이 생성한 코드에서 전달 범위가 임의로 앞부분으로 제한되어 있었고, 그 사실을 제때 확인하지 못했다. 공식문서는 앞부분만으로 문서 성격이 드러나지 않는 경우가 있고, 특히 api_mapping과 label_prototypes의 경계는 함수명/심볼 변경인지, 함수 사용 방식/인자/호출 패턴 변경인지까지 봐야 한다.
정리한 기준:
- Markdown 분류에는 파일명과 Markdown 전체 본문을 전달한다.
- 앞부분 excerpt만 보고 테이블을 고르지 않는다.
- 기존 JSONL 산출물과 PostgreSQL에 넣은 데이터는 기준이 틀어진 결과로 보고 모두 폐기한다.
- DB와 JSONL을 비운 뒤 다시 분류를 시작한다.
초기화 결과:
godot_rag.docs_chunks: 0건godot_rag.api_mapping: 0건godot_rag.label_prototypes: 0건godot_rag.ingest_reports: 0건- 로컬 JSONL 산출물 삭제
- Streamlit 앱 재시작
이번 작업에서는 비슷한 실수가 반복되었다.
처음부터 사용자가 잘못 설계한 것이 아니라, LLM이 생성한 코드와 문서가 사용자의 의도와 다르게 흘러갔고 그 차이를 제때 확인하지 못했다. 단순히 한 번 놓친 정도가 아니라, 테이블 경계와 데이터 흐름을 정리하는 과정에서 비슷한 확인 누락이 반복되었다. 실수가 반복되는 것은 결국 실력의 일부라는 말처럼, 이 부분은 더 주의해서 봐야 한다.
특히 구현을 먼저 정확히 확인하지 않은 채 문서를 단정하거나, 아직 정하지 않은 스키마와 흐름을 확정된 것처럼 적는 문제가 있었다. docs_chunks, api_mapping, label_prototypes를 같은 레벨로 봐야 하는 순간에도 특정 테이블만 특별한 흐름처럼 적으면서 문서 일관성이 깨졌다.
앞으로는 작업을 진행할 때마다 문서를 작성하는 것을 거의 필수 절차로 둔다. 문서화의 목적은 보여주기용 정리가 아니라, 지금 무엇을 기준으로 판단하고 있는지 확인하는 것이다. 코드나 데이터가 조금이라도 바뀌면 그 변경이 어떤 기준에서 나왔는지 기록하고, 같은 실수를 반복하지 않도록 남겨야 한다.
이번에도 현재 코드 구조를 문서화하지 않고 계속 진행했다면 이 문제를 더 늦게 알았을 수 있다. LLM 분류 방식 문서를 작성하면서 실제 코드가 사용자의 원래 요구와 달리 Markdown 전체가 아니라 앞 3000자만 전달하도록 짜여 있다는 사실을 확인했고, 그 과정에서 원래 요구대로 전체 Markdown을 전달하도록 수정할 수 있었다. 그래서 이번 일은 문서화가 단순한 정리가 아니라 코드의 실제 동작이 사용자의 의도와 맞는지 검증하는 과정이라는 점을 다시 확인한 사례로 남긴다.
RunPod 중단과 변환 재개 관찰
Markdown -> JSONL 변환 중 RunPod 서버가 예기치 않게 멈추면서 로컬 웹앱에서 진행 중이던 변환도 중간에 끊겼다. 이후 Streamlit 앱을 다시 띄운 뒤, 기존 상태가 유지되는지 아니면 처음부터 새로 시작되는지 확인했다.
관찰 기준은 state.json에 저장된 파일별 상태와 웹앱의 Latest Processing Log였다. 재시작 전후로 확인한 핵심 증거는 다음과 같다.
- 재시작 전 상태는
done 47,deferred 7,converting 1,pending 1515였다. - 당시 처리 중이던 파일은
pages/classes__class_astar3d__23ef6ac2.md였다. - 앱 재시작 후 로그에
앱 재시작 후 자동 이어하기를 일시정지함이 남았다. - 이어서
처리 중이던 파일을 pending으로 되돌림로그가 남았고, 대상 파일은 같은pages/classes__class_astar3d__23ef6ac2.md였다. - 다시 시작하자 해당 파일에서
기존 분류 재사용로그가 남았고, 같은 파일을 완료한 뒤 다음 파일로 넘어갔다. - 이후
pages/classes__class_astargrid2d__51463855.md,pages/classes__class_atlastexture__336f837e.md,pages/classes__class_audiobuslayout__a2e0df1f.md까지 순차적으로 진행되면서done카운트가 증가했다.
이 관찰로 확인한 것은 다음이다.
- 변환 결과 전체가 초기화되지는 않았다.
- 처리 중이던 파일은 안전하게
pending으로 되돌아갔다. - 이미 완료된 파일은 다시 처리하지 않았다.
- 기존 분류 결과가 있으면 재사용했다.
- 다시 시작하면 마지막으로 끊긴 지점부터 이어서 진행했다.
다만 RunPod 서버가 예기치 않게 멈추면 변환 흐름이 장시간 대기하거나 중단될 수 있다. 긴 변환 작업에서는 RunPod 서버 상태, API 응답 실패, 로컬 앱 재시작 여부를 빠르게 알 수 있는 알림 설정이 필요하다. 단순히 웹앱 화면을 보고 있는 것만으로는 서버가 죽었는지, API 응답을 기다리는지, 로컬 앱이 종료됐는지 구분하기 어렵다.
앞으로 이 흐름을 계속 쓴다면 최소한 다음 상태는 눈에 띄게 알려야 한다.
- RunPod 서버 응답 불가
- API timeout 또는 5xx 응답 반복
- Streamlit 앱 프로세스 종료
- 처리 중 파일이 일정 시간 이상 같은 테이블 단계에 머무는 경우
- 앱 재시작으로 인해 자동 이어하기가 일시정지된 경우