AI 에이전트가 진짜 쓸모 있으려면: 보기·읽기·기억하기 설계

AI 에이전트가 진짜 쓸모 있으려면: 보기·읽기·기억하기 설계

페이지 스냅샷은 사진이고 사용자는 영상을 묻는다—에이전트가 실제로 유용해지려면 무엇을 '보고', '읽고', '기억'하는지 설계 단계부터 달라져야 한다

AI 에이전트 컨텍스트 설계 메모리 레이어 코드베이스 컨텍스트 상호작용 추적 접근성 트리 Chronicle 에이전트 메모리
광고

AI 에이전트에 대한 기대는 빠르게 높아지고 있지만, 현장에서 체감하는 실망도 그만큼 크다. 코드를 짜지 못해서가 아니다. 무엇을 봐야 하는지, 어떤 구조로 읽어야 하는지, 무엇을 기억해야 하는지—이 세 가지를 제대로 설계하지 않았기 때문이다. 최근 dev.to에 올라온 세 편의 글이 이 문제를 각자 다른 각도에서 다루고 있는데, 나란히 읽으면 하나의 질문으로 수렴된다: AI 에이전트가 진짜 도움이 되려면 어떤 컨텍스트 인식 구조를 가져야 하는가.


보기: 스냅샷이 아니라 흔적이 필요하다

사용자가 테이블에서 'Blue Widget'을 클릭하고, 팝업이 뜨고, 가격과 상태를 확인한 뒤 팝업을 닫는다. 5초 후 AI 어시스턴트에게 "이 항목에 뭔가 문제가 있나요?"라고 묻는다. 에이전트는 현재 페이지를 캡처한다—팝업은 이미 없고, 테이블에는 25개 항목이 보인다. 에이전트는 사용자가 무엇을 봤는지 전혀 모른다.

Gaurav Chodwadia의 글 "Giving AI Agents Eyes (Part 2)"는 이 구조적 공백을 정확하게 짚는다. 접근성 트리(Accessibility Tree)로 페이지의 현재 상태를 표현하는 것—즉 "지금 무엇이 있는가"를 답하는 것—은 이미 해결됐다. 문제는 "방금 무슨 일이 있었는가"다. 페이지 스냅샷은 사진이고, 사용자는 영상에 대해 묻고 있다.

해법은 세션 리플레이 도구(rrweb, FullStory)처럼 DOM 전체를 직렬화하는 게 아니다. 그건 LLM이 소비하기엔 너무 크고 너무 시각적이다. 필요한 건 200토큰짜리 자연어 상호작용 로그다. 어떤 ARIA 역할의 요소가 클릭됐고, 어떤 팝업이 나타났다가 사라졌는지—그 흔적을 LLM이 읽을 수 있는 형태로 남기는 것. 이 글에서 소개한 구현은 Strategy 패턴으로 이벤트 소스를 교체 가능하게 설계하고, 캡처 단계 클릭 리스너로 호스트 앱의 버블링 차단을 우회하며, 노이즈를 ARIA 역할 기반 필터로 제거한다. 기술적으로 흥미로운 지점은 React 상태의 비동기 특성과 동기 DOM 이벤트 사이의 타이밍 불일치가 세 개의 버그로 복합 발현된다는 것—증상은 하나지만 원인은 레이어마다 숨어 있었다.


읽기: 파일 덤프가 아니라 코드베이스 지도가 필요하다

코딩 에이전트에게 컨텍스트를 준다는 건 흔히 "관련 파일을 프롬프트에 넣는다"는 뜻으로 통한다. 작은 프로젝트에서는 돌아간다. 실제 레포지토리 규모가 되면 무너진다. 함수 하나를 바꾸려면 그 함수가 어디서 정의됐는지, 누가 호출하는지, 어떤 테스트가 영향을 받는지, 최근 어떤 심볼이 변경됐는지—이 모든 관계를 알아야 한다. 그런데 파일을 무작위로 잔뜩 넣어주면 에이전트는 엉뚱한 파일을 기준으로 추론하고, 토큰은 낭비되고, 결과는 불안정해진다.

Animesh Dutta가 만든 오픈소스 프로젝트 Chronicle은 이 문제를 "컨텍스트 엔지니어링" 레이어로 접근한다. 핵심 아이디어는 단순하다: LLM에 코드를 보내기 전에 레포지토리 지능(repo intelligence)을 먼저 구축한다. 함수와 클래스의 심볼 맵, 임포트 의존성, 콜 체인, 변경 영향 범위를 인덱싱한 뒤, 태스크에 필요한 것만 추려 토큰 최적화된 컨텍스트 패킷으로 압축한다. "이 쿼리에 매칭되는 파일은?" 대신 "이 변경이 무엇에 영향을 주는가?"를 먼저 묻는 방식이다.

여기서 프론트엔드 개발자에게 시사점이 있다. 우리가 Cursor나 Claude Code에 파일을 첨부할 때, 우리는 이미 이 판단을 수동으로 하고 있다. 어떤 컴포넌트를, 어떤 훅을, 어떤 타입 파일을 같이 넣을지—그 선택이 결과를 결정한다. Chronicle은 그 판단을 자동화하고 구조화하려는 시도다. 현재는 Python 레포지토리에 국한된 알파 단계지만, 이 레이어를 명시적으로 설계한다는 발상 자체가 방향을 가리킨다. 로컬 퍼스트로 처리한다는 점도—민감한 코드베이스를 외부 모델에 그대로 넘기지 않는다는 점에서—실용적인 선택이다.


기억하기: 더 많이가 아니라 더 정확하게

에이전트가 세션을 넘나들며 실수를 반복하는 이유는 기억이 없어서가 아니다. 기억해야 할 것과 버려야 할 것을 구분하지 못해서다. dev.to의 "What an AI Agent's Memory Layer Actually Has to Store"는 이 문제를 날카롭게 파고든다: 에이전트는 코드를 못 써서 레포지토리를 망가뜨리는 게 아니라, 코드가 왜 그 모양인지 잊어버려서 망가뜨린다.

패키지 경계를 잊는다. 피처가 배포됐지만 아직 플래그 오프 상태임을 잊는다. 마이그레이션이 절반만 완료됐음을 잊는다. 이전에 문제를 일으킨 추상화를 잊는다. 그러면 다음 세션에서 로컬로는 합리적이지만 글로벌로는 틀린 결정을 내린다.

이 글이 제안하는 메모리 레이어는 놀라울 만큼 단출하다. 저장해야 할 것은 다섯 가지다: 결정(무엇을, 왜, 아직 유효한가), 경계(무엇이 여기 속하고 속하지 않는가), 권위 있는 소스(어디가 이 동작을 소유하는가), 실패 모드(무엇이 전에 망가졌는가), 필수 컨벤션(선택 사항과 하드 제약의 구분). 전체 채팅 히스토리, 로그 덤프, 탐색 과정의 잡담은 세션 창 안에서만 살아야 한다—영구 스토어로 흘러들어가면 안 된다.

구현 형태는 거창하지 않아도 된다. 마크다운 파일 몇 개, 엄격한 JSON 원장, 작은 SQLite 테이블—형태보다 스키마가 중요하다. 스키마 없는 메모리는 그냥 더 큰 트랜스크립트일 뿐이고, 큰 트랜스크립트는 썩는다. 검색이 어려워지고, 노이즈가 늘고, 비용이 올라간다. 그리고 가끔 정리가 필요하다—완료된 마이그레이션, 교체된 경계, 만료된 제약은 아카이브되어야 한다. 살아있는 메모리 표면을 작고 고신호 상태로 유지하는 것이 목표다.


세 가지가 하나의 질문으로 수렴하는 지점

세 글은 서로 다른 레이어를 다루지만 같은 진단을 내린다. 컨텍스트의 양이 아니라 컨텍스트의 구조가 문제다. 더 많은 DOM 데이터, 더 많은 파일, 더 많은 채팅 히스토리를 쑤셔 넣는다고 에이전트가 더 유용해지지 않는다. 사용자의 상호작용 흔적을 LLM이 읽을 수 있는 형태로 남기고, 코드베이스의 관계 구조를 태스크에 맞게 정제하고, 세션이 바뀌어도 살아남아야 할 결정과 경계를 스키마로 보존하는 것—이 세 레이어가 맞물릴 때 에이전트는 비로소 첫 만남처럼 굴지 않는다.

프론트엔드 개발자 입장에서 이건 추상적인 AI 이론이 아니다. Cursor에서 파일을 첨부하는 방식, Claude Code에 프로젝트 컨텍스트를 넘기는 방식, 팀 레포지토리에 AGENTS.md나 아키텍처 결정 기록(ADR)을 유지하는 방식—이 모든 것이 사실 이 세 레이어의 수동 구현이다. 도구가 이 구조를 자동화하는 방향으로 발전하고 있다면, 우리가 먼저 그 구조를 의식적으로 설계해두는 것이 AI와 더 잘 일하는 가장 빠른 경로다.

결국 질문은 하나다. 당신의 에이전트는 지금 무엇을 보고, 어떻게 읽고, 무엇을 기억하도록 설계되어 있는가? 그 설계를 의식하지 않는다면, 에이전트는 매 세션마다 첫 만남을 반복할 것이다.

출처

더 많은 AI 트렌드를 Seedora 앱에서 확인하세요