어제 같은 저장소에서 Coding Agent에게 키보드 단축키를 추가해 달라고 했다. 오늘 비슷한 기능을 다시 부탁하면 어떨까? 에이전트는 어제 찾았던 파일을 다시 검색하고, 테스트를 다시 읽고, 이미 겪었던 문제를 또 만날 수 있다. 처음 탐색하는 데 비용이 드는 건 이해할 수 있다. 하지만 왜 두 번째에도 같은 대가를 치러야 할까?

Show HN 게시물에서 Singularity라는 오픈소스 프로젝트를 발견했다. 완료한 코드 변경을 재사용 가능한 워크플로로 바꾸려는 프로젝트다. 어디를 수정했는지, 어떤 검증을 했는지, 과거에 어떤 함정이 있었는지를 기억하고, 다음 작업에서는 도움이 될 만한 단계를 먼저 찾아 에이전트에 제공한다.

매력적인 방향이지만, 내가 궁금했던 질문은 따로 있다. 기억을 찾았다고 해서 그 기억이 지금의 작업에도 맞는다는 걸 어떻게 확신할 수 있을까?

Singularity 소스를 커밋 9d241f2에 고정해 살펴보고, 모델 호출 없이 동작하는 작은 합성 테스트를 실행했다. 먼저 범위를 분명히 해 둔다. Singularity CLI를 직접 설치해 진행한 통합 테스트도 아니고 Claude Code나 Codex에서 Token 비용을 비교한 실험도 아니다. 소스의 핵심 매칭 규칙을 독립적으로 재구성해 규칙의 행동과 오탐 가능성을 확인했다.

전체 대화가 아니라 작업 경로를 기억한다

고정된 버전의 README에 따르면 Singularity는 성공한 코드 변경에서 경험을 모으고, 모델을 이용해 여러 경험을 워크플로로 정리한다. 특정 기능을 바꿀 때 어느 파일을 수정하는지, 어떤 테스트를 돌리는지, 어디서 실패했는지 같은 내용이 워크플로에 들어갈 수 있다.

이것은 대화 전체를 장기 기억으로 저장하는 방식과 다르다. 대화 기록에는 당시만 의미가 있던 시행착오가 많다. 반면 워크플로는 반복할 가치가 있는 단계에 초점을 맞춘다. 이 글은 그런 단계와 검색 단서의 재사용을 분석하는 것이며, 프로젝트의 다른 캐시 메커니즘이 존재하는지까지 모두 감사한 것은 아니다. 기억이 예전 파일 위치를 정확하게 가리키더라도 저장소 구조가 바뀌었다면 다시 확인해야 한다.

비용도 나눠서 볼 필요가 있다. 워크플로를 학습할 때는 모델을 호출할 수 있지만, 이미 생성한 단서로 사용할 단계를 선택하는 데는 모델이 필요 없을 수도 있다. workflows-cues는 후자에 해당한다.

그렇다고 Singularity의 모든 경로가 모델 비용 없이 작동한다는 뜻은 아니다. 고정된 평가 코드인 StepSelector.ts는 모델을 호출해 적절한 단계를 판단한다. 반면 Memory.ts는 workflows-cues를 모델 없는 단서 기반 선택으로 설명한다. 전자는 모델을 통한 단계 선택, 후자는 미리 생성한 텍스트 단서의 매칭이다. 비용 구조가 다르지만 실제 작업에서 두 경로의 지연이나 Token을 비교하지 않았기 때문에 전체적으로 어느 쪽이 나은지는 말할 수 없다.

모델을 호출하지 않는 매칭은 무엇을 할까?

apps/cli/src/workflows/Cues.ts를 따라가 보았다.

핵심 흐름은 비교적 단순하다. 작업 설명을 소문자 기준으로 정규화한 뒤, not, never, without 같은 단어가 들어간 부정절을 제거하려 한다. 그리고 남은 문장에 워크플로용으로 미리 생성된 단서 구문이 들어 있는지 확인한다. 긍정 단서에 일치하면서 배제 단서에는 일치하지 않아야 해당 워크플로를 선택한다. 개별 단계에도 추가 단서 필터를 적용할 수 있다.

여기서는 모델에 “두 작업이 의미적으로 비슷한가?”라고 묻지 않는다. 정리된 문자열 규칙표에 더 가깝다. 빠르고 저렴하며 같은 입력에는 같은 결과를 준다. 다만 같은 단어가 등장한다고 같은 의도인 것은 아니다.

예를 들어 트리거가 keyboard shortcut이라면 “Add a keyboard shortcut”은 자연스럽게 매칭된다. 하지만 “Review keyboard shortcuts in documentation only”에도 같은 구문이 들어 있다. 후자는 실제 기능을 수정해 달라는 요청이 아니다.

소스는 일부 명시적인 부정을 처리한다. 이것을 모든 복잡한 부정문, 암묵적인 제약, 여러 문장에 걸친 의도까지 이해한다는 뜻으로 받아들여선 안 된다. 매처는 후보 기억을 찾을 뿐, 그 절차가 맞는지 증명하지 않는다.

다섯 가지 합성 입력으로 경계를 확인했다

고정된 Cues.ts를 참고해 텍스트 정규화, 부정절 제거, 긍정·부정 단서 매칭의 주요 판단을 직접 독립적으로 재작성했다. Node.js 표준 라이브러리만 사용한 합성 테스트다. 공식 테스트 스위트가 아니며 원본 구현의 모든 경계 조건을 포함한다고 보장할 수도 없다. Singularity를 설치하거나 모델에 접속하거나 실제 저장소를 수정하지도 않았다.

테스트 스크립트와 결과 JSON은 비공개 연구 기록에 보존했고 공개 다운로드 파일은 제공하지 않는다. 다음은 다섯 개 입력에서 관찰한 결과 전체다. 이는 소스 규칙을 참고한 합성 재현이지 상위 CLI의 종단 간 동작 보고서가 아니다.

합성 작업 입력매칭 결과관찰한 사항
키보드 단축키 추가매칭정상적인 기억 검색
데이터베이스 연결 수정불일치관련 없는 작업 배제
단축키를 추가하지 말라고 명시불일치단순 부정 처리
문서의 단축키 표현만 검토매칭문자열이 겹쳐 잘못 검색
단축키 추가 요청이지만 기억 속 예전 파일은 삭제됨매칭실제 파일 존재 여부를 확인하지 않음

기대 출력은 실행 전에 간단한 매칭 규칙을 기준으로 정했다. 관련 작업은 매칭되고, 무관한 작업과 명시적 부정은 제외된다. 그러나 문서만 검토하는 요청도 트리거 문구를 포함하면 매칭될 것으로 예상했다. 파일이 삭제된 경우도 텍스트 매처가 파일 시스템을 조회하지 않으므로 매칭될 것으로 보았다.

다섯 개의 단언은 모두 예상한 결과를 냈다. 중요한 것은 마지막 두 개가 의도적으로 설계한 바람직하지 않은 결과라는 점이다. “5/5 통과”는 정확도도, 실제 작업 다섯 개가 성공했다는 증거도 아니다. 단순화한 독립 매처에 대한 예측이 관찰값과 일치했다는 뜻뿐이다.

특히 오래된 파일 경로가 문제다. 텍스트 단서만 확인하는 cueChoice는 파일이 이동하거나 삭제되거나 리팩터링되었는지 알 수 없다. 후속 에이전트가 저장소를 다시 살펴보고 문제를 발견할 수는 있다. 하지만 그전에 낡은 작업 경로가 먼저 제시될 수 있다. 기억이 검색되었다는 사실은 힌트일 뿐 현재 저장소 상태의 증명이 아니다.

README의 Token 절감 수치를 어떻게 읽어야 할까?

프로젝트 작성자는 Excalidraw 작업에 대한 비교 결과를 공개했다. 학습된 기억과 밀접한 긴 작업 하나에서 보고된 Token 수는 약 190만에서 42만 3천, 비용은 약 0.81달러에서 0.30달러, 턴 수 중앙값은 28.5에서 9.5로 줄었다. 다만 조건당 실행 횟수는 3~4회 정도이고 몇몇 저장소에 집중된 실험이었다.

흥미로운 결과이지만 어디까지나 작성자가 특정 작업에 대해 보고한 수치다. 처음 보는 유형의 수정이나 작은 일회성 버그 수정에서는 절감 효과가 거의 없을 수 있다. 워크플로 자체를 학습하는 비용도 존재한다.

모델이 파일을 읽는 Token이 줄었다고 전체 엔지니어링 비용까지 줄었다고 단정할 수는 없다. 잘못된 기억을 불러오면 수정에 더 많은 조사가 필요하고, 대규모 리팩터링 전의 기억은 오히려 작업을 어렵게 만들 수 있다.

나는 작성자의 모델 비교를 재실행하지 않았고 실제 Token이나 달러 비용도 측정하지 않았다. 따라서 독립적으로 확인한 절감률은 제시하지 않는다. 이를 계산하려면 동일한 실제 작업을 기억 사용 여부에 따라 비교하면서 학습 호출, 잘못된 검색의 수정, 최종 완료 비용까지 기록해야 한다. 이번 테스트에는 그런 데이터가 없다.

내가 이 기억을 사용한다면

비슷한 변경이 반복되고 디렉터리 구조가 안정적이며 테스트 명령이 명확한 저장소라면 워크플로 기억을 시도할 만하다. 하지만 기억을 에이전트가 무조건 실행해야 할 명령이 아닌 확인해야 할 색인으로 취급하겠다.

각 기억에 출처 커밋, 관련 파일 경로, 마지막 검증 시각, 적용 조건을 넣는 것이 좋다. 사용하기 전에 파일이 남아 있고 검증 명령도 유효한지 확인한다. 여러 번 잘못 검색되어 사람이 계속 수정해야 한다면 다시 학습하거나 해당 기억을 비활성화해야 한다. 이는 내가 제안하는 보호 장치이지 현재 Singularity가 완전한 무효화 감지를 구현했다는 주장은 아니다.

도입 기준도 광고에 나온 Token 절감률보다 작업이 얼마나 반복되는지에 맞춰야 한다. 매번 저장소, 언어, 문제가 달라진다면 기억을 유지하는 비용이 생각보다 클 수 있다.

다음에는 동일한 실제 작업 묶음에서 유효한 검색 비율, 오검색 횟수, 오래된 기억의 비율, 학습 비용, 최종 총비용을 함께 공개한 비교를 보고 싶다. 그래야 기억이 탐색의 반복을 실제로 없애는지, 탐색 비용 일부를 기억 유지비로 바꾼 것뿐인지 판단할 수 있다.

참고: Singularity 저장소 · 고정 버전 단서 매칭 소스 · 작성자의 평가 및 한계