idea_world_labDEV JOURNAL
2026년 6월 27일 토요일

Source Flow Debugger 구현 기록

작성일: 2026년 6월 27일

목적

이 문서는 docs/roadmaps/2026-06-27-source-to-ast-input-flow.md에서 정리한 흐름을 실제 웹 디버거로 구현하고 확인한 기록이다.

오늘 확인한 핵심은 다음이다.

Godot 프로젝트 입력
  -> 상대경로 기준으로 파일 펼치기
  -> 파일 종류 판별
  -> .gd는 AST 성격의 코드 조각으로 분해
  -> .godot, .tscn 같은 텍스트 리소스는 direct chunk로 분해
  -> 각 chunk의 chunkText만 Retriever 입력으로 표시
  -> chunk 아래에서 docs_chunks / api_mapping / label_prototypes 검색 버튼 제공
  -> 검색된 JSONL을 Qwen 검증 요청에 붙일 수 있는 구조로 연결

이번 구현은 완성된 Retriever가 아니라, Retriever와 AST 입력 사이를 눈으로 추적하기 위한 웹 디버거다. 즉 DB 검색 품질을 판단하기 전에, 어떤 파일이 어떤 조각으로 나뉘고 어떤 텍스트가 Retriever 검색 입력으로 들어가는지 먼저 확인하는 용도다.

구현된 웹 흐름

웹 디버거는 http://127.0.0.1:8010/에서 실행했다.

화면에서 확인할 수 있는 영역은 다음과 같다.

  • DB endpoint 입력 영역
  • Qwen validation 입력 영역
  • Source Prompt 입력 영역
  • Expanded Source 입력 영역
  • 파일/청크 요약 지표
  • 파일별 포함/제외 결과
  • chunk별 원문, Retriever Input, DB 검색 버튼, Qwen 요청 preview

오늘 확인한 화면은 다음과 같다.

Source Flow Debugger Godot 분석 화면

Godot 프로젝트 입력 확인

테스트는 작은 Godot 프로젝트 형태로 진행했다.

입력 파일은 다음과 같았다.

minidodge/project.godot
minidodge/scripts/player.gd
minidodge/scripts/enemy.gd
minidodge/scenes/player.tscn
minidodge/README.md

업로드 후 내부 입력은 다음 형태로 펼쳐진다.

# minidodge/project.godot
config_version=5

[application]
config/name="Mini Dodge Upload Test"
run/main_scene="res://scenes/player.tscn"

# minidodge/scripts/player.gd
extends Area2D

signal hit

@export var speed = 400
...

# <상대경로> 헤더는 추적용이다. Retriever에는 이 헤더가 들어가지 않는다.

분석 결과

이번 테스트에서 웹 디버거가 보여준 요약은 다음과 같다.

항목
Files 5
Included 4
Excluded 1
Chunks 14
AST 9
Direct 5
Retriever Inputs 14

파일별 판정은 다음과 같았다.

파일 판정 처리
minidodge/project.godot included project_config, direct chunk
minidodge/scripts/player.gd included gdscript, AST chunk
minidodge/scripts/enemy.gd included gdscript, AST chunk
minidodge/scenes/player.tscn included scene, direct chunk
minidodge/README.md excluded source-analysis 모드에서 문서 파일 제외

.gd 파일 처리

.gd 파일은 AST Parser 역할의 로직으로 들어간다.

예를 들어 player.gd는 다음처럼 나뉘었다.

extends Area2D
signal hit
@export var speed = 400
var screen_size
func _ready():
func _process(delta):
func start(pos):

실제 chunk는 함수 본문을 포함한다.

예를 들어 _process 함수는 하나의 chunk로 유지된다.

func _process(delta):
	var velocity = Vector2.ZERO
	if Input.is_action_pressed(&"move_right"):
		velocity.x += 1
	if Input.is_action_pressed(&"move_left"):
		velocity.x -= 1

	if velocity.length() > 0:
		velocity = velocity.normalized() * speed
		$AnimatedSprite2D.play()
	else:
		$AnimatedSprite2D.stop()

	position += velocity * delta
	position = position.clamp(Vector2.ZERO, screen_size)

enemy.gd에서는 Godot 3 단서가 될 수 있는 코드도 chunk로 분리되는 것을 확인했다.

extends KinematicBody2D
func _physics_process(delta):
	velocity = move_and_slide(velocity)

direct chunk 처리

project.godot은 AST Parser로 보내지 않고 설정 섹션 단위로 나뉜다.

예를 들어 다음 내용은 direct chunk다.

[application]
config/name="Mini Dodge Upload Test"
run/main_scene="res://scenes/player.tscn"

player.tscn도 AST Parser로 보내지 않고 resource block 단위로 나뉜다.

예를 들어 다음 내용은 direct chunk다.

[node name="Player" type="Area2D"]
script = ExtResource("1")

이렇게 나눈 이유는 .tscn, .godot 파일도 Godot 프로젝트 판단에는 필요하지만, .gd 함수처럼 AST 함수 단위로 파싱할 대상은 아니기 때문이다.

Retriever 입력 확인

오늘 기준으로 Retriever 입력은 chunkText 하나만 가진다.

예를 들어 extends KinematicBody2D chunk의 Retriever 입력은 다음과 같다.

{
  "chunkText": "extends KinematicBody2D"
}

파일 경로, 라인 번호, 프롬프트, 예상 테이블 이름은 Retriever 입력에 넣지 않는다.

파일 경로와 라인 번호는 UI에서 사람이 추적하기 위한 정보다. 검색 자체는 chunk text로 수행해야 한다.

chunk별 DB 검색 버튼

처음에는 테이블 선택을 전역 옵션처럼 둘 수도 있었지만, 실제로는 chunk마다 검색해야 하는 테이블이 다를 수 있다.

그래서 버튼은 chunk 아래에 배치했다.

docs_chunks 검색
api_mapping 검색
label_prototypes 검색
Validate JSONL

흐름은 다음처럼 잡았다.

현재 chunkText
  -> chunk 아래의 테이블 버튼 클릭
  -> 해당 테이블에서 검색
  -> JSONL 후보 표시
  -> prompt + chunkText + retrieved JSONL로 Qwen 검증

여기서 prompt는 Retriever 입력이 아니다. prompt는 Qwen 검증 단계에서만 사용한다.

오늘 확인한 것

오늘 확인한 것은 크게 네 가지다.

첫째, 빈 화면에서 자동 샘플 코드가 들어가던 문제를 제거했다. 이전에는 페이지가 열리면 Mini Dodge 샘플이 자동으로 들어가서, 빈 폴더를 업로드해도 이전 내용이 남아있는 것처럼 보였다. 이제 새로고침 직후에는 source 입력이 비어 있다.

둘째, 같은 파일이나 폴더를 다시 업로드했을 때 브라우저가 change 이벤트를 다시 발생시키도록 업로드 input 값을 클릭 시점에 비운다.

셋째, 개발 중 정적 JS 캐시가 남지 않도록 로컬 서버 응답에 cache-control: no-store를 붙였다.

넷째, Godot 프로젝트를 넣었을 때 .gd는 AST chunk로, .godot.tscn은 direct chunk로 나뉘는 것을 웹 화면에서 확인했다.

아직 남은 것

청크 단위로 쪼개는 것은 어느 정도 성공한 것 같다.

내일 이어서 볼 핵심은 DB 검색을 어떻게 수행할지다.

특히 다음 부분을 확인해야 한다.

  • chunkText만으로 docs_chunks를 검색했을 때 어떤 JSONL이 돌아오는지
  • chunkText만으로 api_mapping을 검색했을 때 Godot 3 -> 4 근거가 잘 잡히는지
  • chunkText만으로 label_prototypes를 검색했을 때 함수 사용 방식/호출 패턴 예시가 잘 잡히는지
  • 검색 결과가 없거나 엉뚱할 때 Qwen 검증 단계에서 어떻게 폐기할지
  • 검색된 JSONL을 어떤 형태로 화면에 보여주면 판단하기 쉬운지

오늘 만든 웹 디버거는 이 다음 단계를 확인하기 위한 관찰 도구다. 이제 파일이 어떻게 쪼개지는지는 보이기 시작했으니, 다음에는 각 chunk가 DB에서 어떤 근거를 가져오는지 추적해야 한다.