역할을 늘리면 작업이 더 나아질까

처음에는 AI에게 맡길 역할을 세분화할수록 작업이 안정될 것이라고 생각했습니다. 로컬 파일에 계획, 구현, 검토, 검증 역할을 적고 각 역할의 모델과 권한도 연결했습니다. 복잡한 작업에는 설계 요청서와 승인된 명세서, 역할별 작업 지시서를 거치도록 했습니다.

실제로 사용해 보니 단순한 요청에서도 역할 호출과 문맥 전달이 늘어났습니다. 설계와 승인 단계를 생략할 수 있는 작업에도 작업 지시서는 필요했고 별도 역할의 결과를 주 에이전트가 다시 확인해야 했습니다. 역할 체계를 줄일지 논의하는 요청조차 설계 역할을 먼저 호출해야 했습니다.

이때 세 가지 방향을 고민했습니다. 역할 체계를 없애는 방법, 단순 작업만 예외로 두는 방법, 문서 작성 같은 작은 작업을 경량 모델에 맡기는 방법이었습니다. 단순 작업의 예외를 계속 추가하면 작업마다 분류 규칙이 늘어나고 경량 모델에 맡기더라도 문맥 전달과 결과 통합은 남습니다. 그래서 고정된 역할 체인과 필수 문서를 제거하고 주 에이전트가 기본 작업을 직접 처리하도록 정했습니다.

모든 별도 역할을 없애지는 않았습니다. 아키텍처 경계의 사전 검토, 사용자가 명시적으로 요청한 코드 리뷰, 독립된 검증처럼 별도 결과의 가치가 분명한 작업만 조건부로 남겼습니다. 경량 모델도 정해진 범위의 작업에만 사용하도록 했습니다. 제가 줄이려던 것은 역할의 존재가 아니라 요청과 상관없이 반복되는 절차였습니다.

역할을 줄여도 판단 근거는 남겨야 했다

역할 체인을 줄인 뒤의 다음 고민은 판단 근거를 어떻게 남길지였습니다. 현재 코드는 구조가 어떻게 되어 있는지는 보여주지만 그 구조를 선택하면서 어떤 대안을 검토했고 무엇을 유지하려 했는지까지 모두 설명하지는 않습니다. 다음 변경에서 같은 판단을 다시 해야 한다면 당시 선택의 이유를 찾아볼 수 있어야 했습니다.

그렇다고 모든 작업에서 과거 문서를 전부 읽게 하면 앞서 줄인 문맥 전달 비용이 다시 늘어납니다. 그래서 현재 따라야 할 규칙과 필요할 때 찾아볼 결정 기록의 용도를 나눴습니다. 이 구분은 두 문서가 섞여 문제가 생겼기 때문이 아니라 매 작업에 필요한 자료만 읽기 위한 기준입니다.

저장소의 AGENTS.md는 작업의 진입점으로 두고 활성 정책의 위치와 조회 순서만 담았습니다. 정책 본문과 기술 결정은 노션에 두었습니다. 처음에는 별도 로컬 Harness가 정책과 결정 검색을 연결했지만 이후 전역 라우터 대신 저장소마다 최소 AGENTS.md를 두는 구조로 바꾸면서 Harness를 정리했습니다. 현재는 AGENTS.md가 활성 정책을 안내하고 과거 판단의 이유가 필요한 경우에만 Decision Memory를 조회합니다.

사이드바 구현은 이 선택이 실제 작업으로 이어진 사례입니다. 별도 사이드바를 추가하되 단일 TabView를 유지한다는 결정을 미리 기록했고 후속 작업에서 그 기록을 다시 찾았습니다. 각 탭의 상태와 탐색 구조를 보존한다는 이유를 현재 코드와 대조한 뒤 구현 범위를 정했습니다.

이처럼 필요한 기록을 검색해 답변과 구현의 문맥으로 사용하는 흐름이 이 글에서 다루는 RAG입니다. 역할별 절차를 줄이면서도 다음 작업에 필요한 판단 근거는 다시 가져올 수 있도록 구성했습니다.

이 흐름에서 말하는 RAG

RAG는 Retrieval-Augmented Generation의 약자로 검색 증강 생성이라고 합니다. 요청에 관련된 외부 자료를 검색하고 그 내용을 모델이 참고할 문맥에 넣어 답변을 생성하는 방식입니다. 모델을 다시 학습시키지 않고도 답변하는 시점에 프로젝트의 기록을 참고하게 할 수 있습니다. Microsoft의 RAG 설명

여기서 검색은 반드시 임베딩과 벡터 데이터베이스를 사용해야 하는 것은 아닙니다. 키워드 검색이나 데이터베이스 조회로 관련 자료를 가져올 수도 있습니다. 중요한 것은 요청에 맞는 정보를 찾아 생성 과정에 연결하는 것입니다.

이 프로젝트에서는 노션 MCP가 외부 기록을 가져오는 경로를 맡습니다. 에이전트는 검색 여부를 판단하고 조회한 기록을 현재 정책과 코드에 비추어 검토합니다. 이후 그 근거를 사용해 구조를 설명하거나 변경안을 작성하고 구현합니다.

RAG 단계 이 작업 흐름에서 하는 일
검색 요청에 필요한 기술 결정을 Decision Memory에서 조회
문맥 보강 기록의 이유와 제약 조건을 현재 요청, 정책, 코드와 함께 검토
생성 확인한 근거를 바탕으로 답변, 변경안, 코드 작성
사용자 요청에서 활성 정책과 현재 코드를 확인하고 필요한 경우 노션 MCP로 Decision Memory를 조회해 작업 문맥에 추가하는 RAG 아키텍처 사용자 요청에서 활성 정책과 현재 코드를 확인하고 필요한 경우 노션 MCP로 Decision Memory를 조회해 작업 문맥에 추가하는 RAG 아키텍처

이 구성은 기존 노션 MCP를 연결한 개발용 RAG 흐름입니다. 검색 엔진이나 벡터 색인을 직접 구현한 범위까지 포함하지는 않습니다. 또한 결정 기록을 저장했다는 사실만으로 검색과 활용이 이루어지는 것은 아닙니다. 어떤 요청에서 기록을 찾고 찾은 내용을 어떻게 사용할지 작업 절차로 연결해야 합니다.

검색할 자료에는 무엇을 남기는가

Decision Memory에는 장기적으로 다시 참고할 기술적 선택을 기록합니다. 아키텍처 책임, 모듈 경계, 공개 계약, 동시성 처리처럼 이후 변경에서 선택의 이유가 필요할 수 있는 결정이 대상입니다. 사용자가 기록을 요청하면 현재 코드와 정책에 비추어 내용을 확인한 뒤 저장하도록 정했습니다.

기록에는 결론과 함께 당시의 상황, 선택 이유, 검토한 대안과 그에 따른 제약을 남깁니다. 관련 이슈나 코드의 근거도 연결합니다. 예를 들어 단일 TabView를 유지한다는 결론에 각 탭의 상태와 탐색 구조를 보존하려는 이유가 함께 있어야 이후 변경에서 무엇을 지켜야 하는지 판단할 수 있습니다.

현재 적용할 작업 규칙은 활성 정책에 둡니다. Decision Memory에는 과거 선택의 이유를 남깁니다. 이 구분은 두 문서가 섞여 문제가 발생했다는 뜻이 아니라 자료의 용도를 정한 것입니다. 정책은 지금 따라야 할 규칙이고 결정 기록은 현재 판단에 참고할 근거입니다.

새 결정이 이전 결정을 대체하면 새 기록에 어떤 결정을 대신하는지 표시합니다. 예를 들어 기존 결정을 A, 새 결정을 B라고 하면 B 기록에 ‘A를 대신하는 결정’이라고 남깁니다. 에이전트는 최신 결정인 B를 먼저 확인하고 이전 선택의 이유가 필요한 경우에만 A 기록을 확인합니다.

어떤 요청에서 검색하는가

모든 요청에 과거 결정 검색을 추가하지는 않습니다. 먼저 활성 정책과 현재 코드를 읽고 과거의 판단 이유가 이번 결정에 영향을 줄 수 있는지 살펴봅니다. 검색을 고려하는 조건은 다음과 같습니다.

  • 모듈의 소유권이나 의존성 경계를 바꾸려는 경우
  • 현재 구조를 선택한 이유가 불분명한 경우
  • 비슷한 결정을 이미 내렸을 가능성이 있는 경우
  • 이번 변경이 이전 설계를 되돌릴 수 있는 경우
  • 사용자가 특정 구조를 선택한 이유를 묻는 경우

문구 수정이나 단순한 이름 변경처럼 현재 파일과 정책만으로 처리할 수 있는 작업은 그대로 진행합니다. 반면 모듈을 다른 계층으로 옮기려는 작업에서는 기존 위치를 선택한 이유가 변경 방향에 영향을 줄 수 있으므로 관련 기록을 조회합니다.

검색 범위도 제한했습니다. 지정된 Decision Memory 데이터 소스에서 해당 프로젝트와 공통 결정을 조회합니다. 작업과 무관한 노션 문서를 폭넓게 찾는 방식으로 구성하지 않았습니다.

이 조건은 에이전트가 따르는 조회 절차입니다. 매번 같은 기록을 찾아내는지나 필요한 기록을 빠뜨리지 않는지까지 보장하는 검색 알고리즘은 아닙니다.

검색 결과를 현재 작업에 연결하는 순서

작업은 저장소의 AGENTS.md에서 시작합니다. 이 파일에는 노션 정책의 조회 경로와 순서, 우선순위가 있습니다. 에이전트는 공통 정책과 해당 작업의 정책을 읽고 현재 파일과 설정을 확인합니다. 과거 결정 검색은 이 과정에서 필요성을 판단해 추가합니다.

현재 정책과 코드를 확인한 뒤 필요한 결정 기록을 검색하고 대조해 답변과 구현에 사용하는 RAG 흐름 현재 정책과 코드를 확인한 뒤 필요한 결정 기록을 검색하고 대조해 답변과 구현에 사용하는 RAG 흐름

검색한 기록에서는 현재 요청과 관련된 선택 이유와 제약 조건을 확인합니다. 그다음 기록이 작성된 시점의 구조와 현재 코드가 같은지 대조합니다. 후속 결정이 있거나 현재 구현과 차이가 있다면 그 차이를 드러내고 적용 여부를 판단합니다.

이 과정에서 활성 정책은 작업 규칙의 기준이고 현재 저장소는 구현 사실의 기준입니다. 과거 기록이 현재 정책이나 코드보다 우선하지 않도록 정했습니다. 필요한 정책을 조회할 수 없으면 작업을 중단하도록 했으며 Decision Memory의 조회 범위를 확인할 수 없을 때도 검색을 진행하지 않도록 했습니다.

답변을 만드는 요청이라면 확인한 기록을 근거로 구조와 선택 이유를 설명합니다. 구현 요청이라면 유지할 조건과 바꿀 범위를 정하는 데 사용하고 변경 대상에 필요한 검증을 수행합니다. 검색한 기록을 읽는 단계와 실제 코드가 의도대로 동작하는지 확인하는 단계는 모두 필요합니다.

검색과 결과 활용은 주 에이전트가 수행할 수 있습니다. 아키텍처 사전 검토나 코드 리뷰, 별도 검증은 각각의 호출 조건에 따라 추가합니다. 역할을 여러 개로 나누는 것이 RAG를 사용하기 위한 필수 조건은 아닙니다.

기록 조회가 구현으로 이어진 단일 TabView 사례

이 사례에서 확인한 핵심은 기록 조회와 현재 코드 확인, 구현 반영이 한 작업 안에서 연결됐다는 점입니다. 다만 기록을 조회하지 않았을 때보다 오류가 줄었는지나 구현 시간이 단축됐는지는 비교하지 않았으므로 이 사례만으로 RAG의 성능 개선을 주장할 수는 없습니다.

사이드바 작업에 앞서 메인 탐색을 별도 사이드바와 단일 TabView로 구성한다는 결정을 노션에 기록했습니다. 각 탭이 자체 상태와 탐색 경로를 가지고 있으므로 기존 TabView를 유지하고 사이드바가 같은 선택 상태를 공유하는 방향이었습니다.

후속 구현 작업에서는 관련 Decision Memory를 조회했습니다. 기록의 방향이 당시 요청과 일치하는지 확인하고 현재 MainView와 탭 선택 상태의 소유 구조를 살펴봤습니다. 이전 기록의 결론을 읽는 데서 끝내지 않고 구현 대상과 맞는지 대조한 것입니다.

구현에서는 기존 TabView를 유지하면서 별도 SideBar를 구성하고 동일한 selectedTab을 공유했습니다. 결정 기록의 ‘기존 탭 구조를 유지한다’는 조건이 실제 변경 범위를 정하는 근거로 이어졌습니다.

왼쪽에는 홈, 오늘, 알림과 프로필을 선택하는 사이드바가 있고 오른쪽에는 선택한 탭의 내용이 표시됩니다. 화면의 배치와 별개로 단일 TabView를 유지한다는 구조는 코드에서 확인할 수 있습니다. 아래는 현재 MainView에서 선택 상태를 연결하는 부분만 간추린 코드입니다.

iPadOS 27의 iPad Pro 13형 M5에서 실행한 사이드바와 홈 화면

HStack(spacing: 0) {
	if showsSideBar {
		SideBar(
			selectedTab: $selectedTab,
			unreadPushCount: store.unreadPushCount
		)
		// 사이드바 너비 설정 생략
	}

	TabView(selection: $selectedTab) {
		Tab(
			MainTab.home.title,
			systemImage: MainTab.home.symbolName,
			value: MainTab.home
		) {
			tabContent(.home)
				.toolbarVisibility(showsSideBar ? .hidden : .visible, for: .tabBar)
		}
		// 나머지 탭 구성 생략
	}
}

SideBar와 TabView가 같은 selectedTab에 연결되어 있습니다. 사이드바는 선택 상태를 바꾸고 TabView는 그 선택에 해당하는 콘텐츠를 표시합니다. 사이드바가 보이는 환경에서는 각 탭 콘텐츠의 toolbarVisibility로 시스템 탭바를 숨깁니다. 실행 화면은 배치를 보여주고 코드에서는 과거 결정의 조건이 어떻게 표현되어 있는지 확인할 수 있습니다.

현재 구성의 한계와 확인할 것

현재는 검색할 시점과 범위, 결과를 대조하는 절차를 정해 두었습니다. 검색 품질을 반복적으로 평가하는 체계나 작업 시간과 결과 품질을 비교한 측정치는 아직 없습니다. 정책에 조회 절차가 있다는 사실과 실제로 필요한 기록을 빠짐없이 활용한다는 것은 구분해야 합니다.

앞으로 확인할 항목은 구체적입니다. 과거 결정이 필요한 요청에서 검색을 수행했는지, 관련 기록을 찾았는지, 후속 결정으로 대체된 내용을 확인했는지, 최종 답변이나 변경안이 기록의 제약을 반영했는지를 살펴볼 수 있습니다. 이 항목들은 현재 성과가 아니라 검색과 활용을 평가할 기준입니다.

외부 문서에 의존하는 조건도 있습니다. 노션 조회가 불가능하면 자료를 가져올 수 없으며 현재 정책상 필수 정책을 읽지 못한 작업은 시작할 수 없습니다. 기록이 존재하더라도 현재 코드와 맞지 않거나 선택 이유가 충분히 남아 있지 않다면 그 한계를 판단에 반영해야 합니다.

마무리

처음에는 역할을 세분화하면 더 안정적인 결과를 얻을 수 있다고 생각했습니다. 실제 작업에서는 고정된 절차가 단순한 요청까지 무겁게 만들었고 역할 체인과 필수 문서를 줄이는 방향을 선택했습니다. 다만 역할을 줄이는 과정에서 과거 판단의 이유까지 잃고 싶지는 않았습니다.

그래서 현재 작업 규칙은 활성 정책에서 읽고 필요한 선택의 이유는 Decision Memory에서 찾도록 구성했습니다. 모든 기록을 매번 읽는 대신 과거 판단이 현재 결정에 영향을 줄 때만 검색합니다. 검색한 기록은 현재 코드와 후속 결정에 대조한 뒤 답변과 구현의 근거로 사용합니다.

이 프로젝트에서 RAG는 거대한 문서 검색 시스템을 만드는 일이 아니라 다음 작업에 필요한 기술적 판단의 근거를 다시 가져오는 방법입니다. 현재까지 확인한 것은 조회 절차와 기록이 실제 구현으로 이어진 사례입니다. 오류 감소나 작업 시간 단축은 아직 비교하지 않았으며 이후에는 필요한 기록을 얼마나 잘 찾고 최종 작업에 반영하는지 확인해야 합니다.