Building a context-aware AI assistant on AgentCore and OpenClaw
Quick Summary
AWS는 AgentCore runtime에서 OpenClaw를 실행하고 AgentCore memory로 사용자 맥락을 축적하는 원예 도우미 Sprout을 통해, 사용량 기반으로 운영하는 개인 AI 비서의 구현 구조를 설명한다.
🖼️ 인포그래픽

🖼️ 4컷 인포그래픽

💡 한 줄 요약
AWS는 AgentCore runtime에서 OpenClaw를 실행하고 AgentCore memory로 사용자 맥락을 축적하는 원예 도우미 Sprout을 통해, 사용량 기반으로 운영하는 개인 AI 비서의 구현 구조를 설명한다.
📌 핵심 요약
- Sprout은 OpenClaw의 에이전트 실행·도구·스킬 기능과 AgentCore memory를 결합해 이전 대화의 사용자 선호와 사실을 후속 응답에 활용하며, 페르소나와 스킬 구성을 바꾸면 다른 분야에도 적용할 수 있다.
- Telegram 메시지와 Amazon EventBridge Scheduler의 예약 작업은 같은 AgentCore runtime 에이전트를 호출한다. 전체 구성은 단일 AWS CloudFormation 템플릿에 담기며, 가벼운 개인 사용의 런타임 기준 비용은 2026년 7월 추정 월 약 1~2달러로 제시된다.
- 텍스트는 Claude Haiku 4.5와 OpenClaw 게이트웨이로 처리하고, 이미지는 Claude Sonnet 4.5에 Bedrock Converse API로 직접 전달한다. 두 경로는 페르소나와 메모리를 담은 동일한 시스템 프롬프트를 사용하며, MODEL_ID와 VISION_MODEL_ID로 모델을 변경할 수 있다.
- AgentCore memory는 대화 원문을 단기 이벤트로 저장하고, 비동기 추출을 통해 USER_PREFERENCE, SEMANTIC, SUMMARIZATION 유형의 장기 기록을 만든다. 사용자별 네임스페이스가 서로 다른 Telegram 대화의 메모리를 분리한다.
- 매 메시지마다 장기 기록을 최대 50개, 3초 제한으로 검색하고 명시적 선호를 추론된 사실보다 앞에 배치한다. 검색 실패 시 메모리 없이 응답하며, 서버 측 메타데이터 필터링에는 인덱스 키 선언이 필요하지만 제공된 원문에는 세 키 중 type만 제시된다.
🧩 주요 포인트
- 사용량 기반 AgentCore runtime과 단일 CloudFormation 구성 → 짧게 사용하는 개인 비서의 상시 인프라 부담을 낮추고, OpenClaw와 스킬 구성을 재사용하는 배포 패턴을 제공한다.
- Claude Haiku 4.5·Claude Sonnet 4.5의 역할 분리와 공통 시스템 프롬프트 → 작업별 비용·품질 요구에 대응하면서 텍스트와 이미지 응답에 같은 사용자 맥락을 유지한다.
- 사용자별 메모리 분리, 명시적 선호 우선 정렬, 인덱스 기반 필터링 → 대화의 연속성과 검색 관련성을 높이는 구조이며, 검색 실패 시에는 기억을 활용하지 못하는 제약이 남는다.
🧠 상세 정리
1. 일회성 답변에서 사용자 맥락을 축적하는 비서로
글은 기성 AI 비서가 개별 질문에는 잘 답하더라도 대화의 연속성을 유지하지 못한다는 문제에서 출발한다. 사용자가 몇 주 전에 배수가 빠른 높인 화단, 유기질 비료만 쓰는 선호, 폭염 속 페튜니아의 상태를 설명했어도 상태를 유지하지 않는 비서에게는 다시 알려줘야 한다. 제안하는 해법은 오픈소스 에이전트 시스템 OpenClaw를 AgentCore runtime에서 실행하고, AgentCore memory로 대화를 지속적인 지식으로 전환하는 것이다. 원예 도우미 Sprout이 구현 예시지만, 페르소나와 스킬 매니페스트를 바꾸면 지원 봇이나 피트니스 코치, 내부 헬프데스크에도 같은 파이프라인을 적용할 수 있다고 설명한다. 따라서 핵심 목표는 한 번의 답변 품질 개선보다 사용자에 관한 맥락을 축적하고 필요한 질문에 다시 활용하는 데 있다.
2. 두 진입점을 연결하는 서버리스 구성과 배포 조건
요청은 Telegram 메시지와 예약 작업이라는 두 경로로 들어오지만, 모두 InvokeAgentRuntime API를 통해 같은 AgentCore runtime 에이전트로 모인다. Telegram 메시지는 Amazon API Gateway와 웹훅 AWS Lambda를 거치며, 아침 물주기 알림 같은 예약 작업은 Amazon EventBridge Scheduler와 별도의 cronjob Lambda를 거친다. 런타임 내부의 server.py는 OpenClaw 게이트웨이, AgentCore memory, Amazon Bedrock Converse API를 조정한다. Amazon S3는 작업 공간 저장소를 제공하고, AWS KMS는 암호화, AWS Secrets Manager는 봇 토큰 보관, Amazon CloudWatch는 로그와 지표 수집을 맡는다. 배포에는 AgentCore runtime·memory 접근 권한, 사용할 모델의 접근 권한, Telegram 봇 토큰과 기본적인 오케스트레이션·CloudFormation 이해가 필요하다. 전체 구성은 단일 CloudFormation 템플릿으로 제공되며, Docker의 linux/arm64 빌드 지원과 설정된 AWS CLI는 자체 이미지를 빌드하고 푸시할 때만 필요하다.
3. 활성 연산 과금과 OpenClaw 래퍼의 복구 처리
AgentCore runtime은 컨테이너의 전체 가동 시간이 아니라 에이전트가 실제로 소비하는 연산량에 과금하며, 모델 응답 같은 입출력을 기다리는 시간에는 비용을 청구하지 않는다고 설명한다. 글은 짧게 사용하는 개인 비서의 기준 비용을 월 약 1~2달러, 상시 실행 Amazon EC2 인스턴스를 월 약 35달러로 비교하지만, 이는 2026년 7월의 가벼운 개인 사용 추정치이며 현재 요금 확인이 필요하다고 명시한다. 컨테이너는 포트 8080에서 수신하고 상태 확인용 GET /ping과 진입점인 POST /invocations를 제공하며, 공식 OpenClaw 이미지에 Python 계층을 더한 linux/arm64 다단계 빌드로 구성된다. server.py는 시작 시 openclaw gateway run을 하위 프로세스로 실행하고 상태를 확인하며, 실제 호출에서는 요청 해석부터 메모리 검색과 응답 저장까지 수행한다. 동결된 컨테이너가 다시 활성화될 때 하위 프로세스가 종료되어 있을 수 있으므로, ensure_openclaw_ready()가 호출 경로에서 상태를 재확인하고 필요하면 게이트웨이를 재시작한다. 이 래퍼 방식은 로컬 프로세스로 실행되는 다른 에이전트 프레임워크도 프레임워크 자체를 수정하지 않고 런타임에 연결하는 패턴으로 제시된다.
4. 텍스트와 이미지의 모델 분리, 스킬의 재사용
Sprout은 자주 발생하는 텍스트 대화에 빠르고 저렴한 Claude Haiku 4.5를, 빈도는 낮지만 식물 사진 진단처럼 더 어려운 이미지 작업에는 멀티모달 추론이 강한 Claude Sonnet 4.5를 사용한다. 텍스트는 스킬과 세션 상태를 제공하는 OpenClaw 게이트웨이를 거치지만, 이미지는 server.py가 이미지 바이트를 멀티모달 콘텐츠 블록으로 구성해 Bedrock Converse API에 직접 전달한다. 이 우회는 컨테이너의 OpenClaw 빌드가 image_url 콘텐츠 부분을 Bedrock에 도달하기 전에 제거했던 문제에 대응해 모델이 실제 픽셀을 받도록 하기 위한 선택이다. 두 경로는 페르소나와 메모리를 포함한 같은 시스템 프롬프트를 공유하며, MODEL_ID와 VISION_MODEL_ID 환경 변수로 이미지 재빌드 없이 배포별 모델을 교체할 수 있다. 기능은 community-skills.json에 선언되고 배포 시 스크립트가 컨테이너에 구체화한 뒤 이미지 빌드 전에 OpenClaw 설정에 등록한다. 게시 시점의 Sprout은 날씨, 알림, 식물 메모 스킬을 제공하며, 매니페스트 교체가 다른 분야로의 재사용을 가능하게 한다.
5. Telegram 웹훅과 응답 형식의 실무 제약
Telegram은 웹훅 방식이므로 서버리스 구성을 유지하면서 별도의 클라이언트 개발 없이 개인 비서의 진입점으로 사용할 수 있다고 설명한다. 사용자가 이미 사용하는 기기에서 접근할 수 있고, 봇 API를 통해 텍스트와 이미지, 서식이 있는 응답을 지원한다는 점도 선택 근거다. BotFather가 발급한 봇 토큰은 Secrets Manager에 저장되며, 배포 과정에서 API Gateway 엔드포인트를 가리키는 웹훅을 등록한다. 사용자 메시지를 받은 웹훅 Lambda는 페이로드를 검증하고 InvokeAgentRuntime을 호출하며, 응답은 Telegram 봇 API를 통해 사용자에게 돌아간다. 글은 Telegram의 기존 Markdown 처리 방식에서 이스케이프되지 않은 문자, 특히 응답에 섞인 밑줄 하나가 전체 메시지 전송 실패를 일으킬 수 있다고 지적한다. 이 구현은 모델 출력을 Telegram에서 안전하게 표시할 수 있는 HTML로 변환해 전송하는 방식으로 해당 형식 문제에 대응한다.
6. 단기 이벤트와 비동기 장기 기억, 사용자별 분리
앞선 서버리스 구성만으로는 대화 사이에 사용자를 기억하지 못하므로, 글은 메모리를 연속적인 개인 비서를 만드는 핵심 전환점으로 제시한다. 예를 들어 과거에 유기질 비료만 사용한다고 말한 사용자가 나중에 처치 방법을 물으면, 저장된 선호를 반영해 유기농 선택지를 추천하고 그 이유를 설명할 수 있다는 것이다. 단기 메모리는 CreateEvent로 모든 대화 턴을 저장하며, Telegram 채팅 ID인 actorId와 sessionId를 기준으로 원문 기록을 구분한다. 장기 메모리는 관리형 추출 전략으로 비동기 생성되며, USER_PREFERENCE는 명시적 선택, SEMANTIC은 추론된 사실, SUMMARIZATION은 세션의 사건 요약을 담당한다. 선호와 의미적 사실은 sprout/{chat_id}/long_term에, 세션 요약은 sprout/{chat_id}/episodic/{session_id}에 저장된다. 사용자별 경로를 통해 서로 다른 원예 사용자의 대화가 섞이지 않도록 구성하고, 격리를 이해하고 시험하기 쉽게 만드는 것이 설계 의도다.
7. 매 턴의 검색과 명시적 선호 우선 주입
server.py는 매 메시지마다 관련 장기 기록을 검색하고 순서를 조정한 뒤 시스템 프롬프트에 주입한다. RetrieveMemoryRecords는 sprout/{chat_id}/long_term을 대상으로 사용자 메시지를 검색 질의로 사용하며, 검색 결과는 최대 50개이고 처리 시간에는 3초 제한을 둔다. 검색이 시간 초과되거나 오류가 발생하면 기록 목록을 비우고 메모리 없이 답변하는 방식으로 전체 응답 실패를 피한다. 이어지는 assemble 단계는 USER_PREFERENCE 기록을 먼저 모으고 나머지 기록을 뒤에 배치해, 사용자가 명시적으로 밝힌 선호가 추론된 사실보다 앞서도록 한다. 각 분류 내부의 기존 순서는 유지하고, 프롬프트에 넣기 전에 전체 결과를 다시 최대 50개로 제한한다. 이 구조는 기억을 활용하되 검색 장애 때문에 대화를 중단하지 않는 선택이며, 장애가 발생한 턴에서는 저장된 사용자 맥락을 반영할 수 없다는 제약도 함께 갖는다.
8. 메타데이터로 기억의 주제를 좁히는 조건과 자료의 한계
글은 네임스페이스가 기록의 소유자를 구분한다면, 메타데이터는 그 기록이 무엇에 관한 것인지를 구분한다고 설명한다. 같은 사용자의 장기 메모리에서 페튜니아가 시든다는 질의를 의미 검색만으로 처리하면, 실제로 필요한 기록과 함께 이전의 비료 선호나 무화과나무 가지치기 메모가 검색될 수 있다. 구조화된 메타데이터는 이런 결과가 프롬프트에 들어가기 전에 검색 범위를 좁히기 위한 수단으로 제시된다. 다만 메타데이터 키를 서버 측 필터에 사용하려면 먼저 해당 키를 인덱스 키로 선언해야 한다는 조건이 모든 설계 결정을 좌우한다고 강조한다. 원문은 Sprout이 세 가지 인덱스 키를 사용한다고 소개하고 AWS::BedrockAgentCore::Memory의 IndexedKeys 설정을 보여주기 시작하지만, 제공된 내용은 기록 종류를 구분하는 type 키에서 끝난다. 따라서 나머지 두 키의 이름이나 실제 필터 적용 방식은 이 자료만으로 확인할 수 없다.
🧾 핵심 주장 / 시사점
- 개인 비서의 연속성은 대화 저장만으로 완성되지 않는다. Sprout은 비동기 장기 기록 추출, 질문별 검색, 명시적 선호 우선 정렬을 연결해 기억이 후속 응답에 영향을 주도록 구성한다.
- 이미지 경로를 Bedrock Converse API로 직접 연결한 선택은 OpenClaw 빌드의 콘텐츠 전달 문제에 대응한 것이다. 모델 선택뿐 아니라 실제 입력이 모델까지 전달되는 경로도 응답 품질의 전제가 된다.
- 사용자별 네임스페이스와 구조화된 메타데이터는 서로 다른 역할을 맡는다. 전자는 사용자 간 기억을 분리하고, 후자는 같은 사용자 안에서 질문과 관련된 기억을 좁히지만 서버 측 필터링에는 인덱스 선언이 필요하다.
✅ 액션 아이템
- Sprout의 사용자별 네임스페이스와 AgentCore memory를 바탕으로 대화 맥락 축적 및 사용자 간 메모리 분리 방식 검토.
- Claude Haiku 4.5의 텍스트 경로와 Claude Sonnet 4.5의 이미지 경로를 구분하고, 공통 시스템 프롬프트 및 MODEL_ID·VISION_MODEL_ID 설정 적용 검토.
- 장기 기록 검색의 최대 50개·3초 제한, 명시적 선호 우선 정렬, 검색 실패 시 메모리 없는 응답을 구현 조건으로 반영.
❓ 열린 질문
- 2026년 7월 추정 월 약 1~2달러의 AgentCore runtime 기준 비용은 사용량이 늘어날 때 어떻게 달라지는가?
- 장기 기록 검색의 최대 50개·3초 제한과 검색 실패 시 메모리 없는 응답은 사용자 맥락을 유지하는 데 어떤 영향을 주는가?
- 제공된 원문에 나온 type 외의 두 인덱스 키는 무엇이며, 서버 측 메타데이터 필터링에서 어떻게 사용되는가?