왜 루프가 둘인가
GEODE 안에는 서로 맞물린 루프가 둘 있습니다. 둘을 구분하면 나머지 문서가 한결 읽기 쉬워집니다. 안쪽 루프는 작업 하나를 처리합니다. 바깥쪽 루프는 그 작업을 처리하는 시스템을 시간이 지나며 다듬습니다.
안쪽 루프는 매 요청마다 돕니다. 바깥쪽 루프는 가끔, 예약된 시점에 돕니다. 둘은 같은 코드를 공유하지 않습니다. 대신 한 가지를 주고받습니다. 바로 안쪽 루프가 남긴 기록입니다.
안쪽: agentic 루프
안쪽 루프는 작업 하나를 실행하는 기본 단위입니다. core/agent/loop/agent_loop.py의 AgenticLoop가 그것입니다. 형태는 단순합니다. LLM을 호출하고, 모델이 요청한 도구를 실행하고, 결과를 관찰하고, 다시 호출합니다. 모델이 더 호출할 도구가 없거나 종료 신호를 보내면 멈춥니다.
call LLM -> tool calls? -> run tools -> observe -> call LLM ...
|
+-- no more tool calls -> answer이 한 번의 실행이 끝나면 두 가지가 남습니다. 사용자에게 줄 결과, 그리고 무슨 일이 있었는지 기록한 트랜스크립트입니다. 트랜스크립트는 버려지지 않습니다. 바깥쪽 루프가 읽을 재료가 됩니다.
한 턴이 실제로 어떻게 도는지, 어떤 경로로 끝나는지는 안쪽 agentic 루프에서 자세히 다룹니다.
바깥쪽: 자기개선 루프
바깥쪽 루프가 다루는 대상은 작업이 아니라 시스템 자체입니다. 안쪽 루프가 어떻게 행동하는지 관측하고, 그 행동을 결정하는 정책을 한 군데 바꾼 뒤, 바뀐 정책으로 다시 측정합니다. 좋아졌으면 채택하고, 아니면 되돌립니다.
- 관측. Petri 평가가 안쪽 루프의 트랜스크립트를 차원별로 채점합니다.
- 변형.
autoresearch/state/policies/의 정책 파일 하나를 한 번에 한 군데만 바꿉니다. - 재감사. 바뀐 정책으로 다시 Petri 감사를 돌립니다.
- 귀속. 점수 변화를 그 변형 탓으로 돌려도 되는지 판단합니다.
- 승격 또는 되돌리기. 차원이 기준을 넘으면
autoresearch/state/baseline.json을 갱신하고, 아니면 정책을 변형 이전으로 되돌립니다.
이 흐름의 전체 그림은 폐루프에서, 측정에 쓰는 평가 프레임워크는 Petri × GEODE에서 다룹니다.
둘이 맞물리는 방식
핵심은 두 루프가 직접 호출하지 않는다는 점입니다. 둘은 데이터로 연결됩니다. 안쪽 루프는 트랜스크립트와 결과를 만들고, 바깥쪽 루프는 그것을 Petri 감사로 읽어 정책을 바꿉니다. 바뀐 정책은 다음 번 안쪽 루프가 행동하는 방식을 바꿉니다.
outer loop (occasional, scheduled)
observe -> mutate policy -> re-audit -> attribute -> promote / revert
^ |
| v
+-------------------------------------------+
| inner loop (every request) |
| call LLM -> run tools -> observe -> ... |
| produces: answer + transcript |
+-------------------------------------------+
| ^
+-- transcript ----------------------+
(read by the outer loop's audit)그래서 정책을 바꾸면 코드를 바꾸지 않아도 안쪽 루프의 행동이 달라집니다. 정책은 안쪽 루프가 매 호출마다 읽는 파일이고, 바깥쪽 루프는 그 파일을 쓰는 쪽입니다. 한쪽은 읽고 한쪽은 씁니다. 둘은 그렇게 한 시스템으로 맞물립니다.