Atlas Agent Engine 메모리용 독립형 Python SDK — Atlas Agent Engine 내부 또는 외부에서 사용할 수 있는 AI 에이전트용 장기 메모리입니다.
에이전트 에게 대화 차례를 기록 하고 나중에 학습한 사실(의미론적), 과거 대화(일화), 도메인 지식(분류), 재사용 가능한 절차 등 관련 컨텍스트를 회상할 수 있도록 하나 객체 Memory를 제공합니다. 패키지 자체적으로 설치되며 pydantic 및 httpx에만 의존하므로 플랫폼 스택 가져오지 않고 모든 에이전트 에 삽입됩니다.
플랫폼 배포 에이전트는 이와 동일한 SDK를 사용합니다. 구성하지 않고 런타임은 이미 클러스터 내 전송과 처리 중인 호출의 ID에 연결된 agent_engine_sdk_memory.Memory를 에이전트 에 전달합니다. 동일한 클래스와 동일한 메서드 서명입니다. 아래의 운송 만 다릅니다. 따라서 외부 에이전트 대해 쓰기 (write) 코드는 플랫폼에 배포 때 변경되지 않고 실행되며, 이 README에서 학습 내용은 두 곳에 모두 적용됩니다.
두 가지 점은 다릅니다: ID가 어디에서 오는지(연결 참조), 그리고 앱 바인딩 전송을 제공 할 수 없고 MemoryNotSupportedError를 발생시키는 소수의 호출은 각 연결이 지원하는 항목에 나열되어 있습니다.
메모리가 생소하다면 메모리의 작동 방식부터 시작해 보세요. 시스템 형태에 따라 대부분의 API 설명됩니다. 그런 다음 설치, 연결,사용의 세 단계로 통합합니다. 서버 측 설정은 메모리 서버 구성에서 다룹니다. ID, 오류 및 모델에 대한 참고 자료가 뒤에 오고, 패키지 내부가 마지막에 있습니다.
콘텐츠
메모리 작동 방식
해결되는 문제
메모리는 에이전트 중요한 사실, 대화, 절차, 어휘를 영구적으로 저장 하고, 에이전트 가 LLM과 나눈 대화에서 지속형 학습된 사실을 추출하여 해당 저장 자체를 채웁니다. 추출 자체는 사용자가 구성한 LLM에 의해 수행됩니다.
플랫폼에 배포된 에이전트 의 경우 이 중 어느 것도 연결이 필요하지 않습니다. 런타임은 에이전트 워크플로가 실행될 때 각 대화가 단기 메모리로 바뀌고, 승격과 추출이 배경 에서 비동기적으로 진행되므로 팩트가 정제되는 동안 응답을 차단하는 것이 아무것도 없습니다. 지속형 형을 이미 알고 있는 에이전트 이를 찾기 위해 추출을 기다릴 필요가 없습니다 — save_semantic 및 다른 유형의 쓰기를 사용하여 팩트를 직접 쓰기 (write) 수 있습니다.
다시 읽으면 어느 쪽이든 상관없이 작동합니다. 에이전트 한 번에 한 가지 종류의 사실, 즉 학습한 내용에 대해서는 search_semantic, 이전에 발생한 내용에 대해서는 search_episodes, 텀 의미에 대해서는 search_taxonomic, 어떤 것이 수행되는 방법에 대해서는 discover_procedures 등을 추적하고 처리하다. 결과 자체.
또는 전체 작업 넘길 수도 있습니다. build_context_from_sources은(는) 소스당 하나의 사양을 취하고, 각각 고유한 검색 모드, 필터하다 및 후보 수를 선언한 다음, 모든 소스에서 자체 텀에 따라 결과를 검색하고, 결과의 순위를 지정하고 중복을 제거하고, 토큰 예산으로 자르고, 다음을 반환합니다. 단일 컨텍스트 차단 사용하여 다음 프롬프트로 이동할 수 있습니다. build_context은 모든 소스에 대해 하나의 모드 와 하나의 필터하다 사용하여 동일한 작업을 수행합니다. 달라야 하는 경우 소스별 형식을 사용하세요.
2개의 레이어
메모리는 사물의 수명과 형태에 따라 분할 됩니다.
단기 기억(STM)은 원시 대화로, 세션 범위가 지정된 턴당 하나의 기록 발생하는 대로 기록됩니다. 모든 내용을 순서대로 쓰기 (write) 하고 완료하는 것은 비용이 저렴합니다.
대화에서 살아남은 장기 기억은 서로 다른 질문에 답변 때문에 네 가지 형태로 정제됩니다.
유형 | 보유 | 답변 |
|---|---|---|
| 레이블이 지정된 팩트 | "내가 이것에 대해 무엇을 알 수 있나요?" |
| 요약된 에피소드 | "전에 무슨 일이?" |
| 재사용 가능한 절차 | "이 작업을 수행하려면 어떻게 해야 하나요?" |
| 텀 및 정의 | "여기서 이 단어는 무엇을 MEAN 하나요?" |
프로젝트는 네 가지 형태가 맞지 않는 도메인 레코드에 대해 사용자 지정 유형을 선언할 수도 있습니다.
쓰기가 메모리가 되는 방법
장기 기억은 직접 쓰기 (write) 는 없지만 쓸 수는 있습니다. 일반 경로는 다음과 같습니다.
record_turn(...) you write turns as the conversation happens │ ▼ turns accumulate into a session snapshot a contiguous run of turns, summarised │ ▼ an LLM reads the snapshot and extracts what is durable semantic · episodic · procedural · taxonomic
추출은 비동기식이며 배경 에서 실행되므로 record_turn은 빠른 쓰기 (write) 를 유지합니다. 따라서 한 대화에서 학습한 사실은 다음 차례가 아닌 다음 대화에서 사용할 수 있습니다.
결과는 설계할 가치가 있습니다: 최근 회전은 STM을 통해 즉시 표시되고 추출된 지식은 잠시 후에 나타납니다. 방금 언급한 내용이 필요할 때는 stm을(를) 요청하세요.
추출 실패 시
백그라운드 추출은 임베딩 서비스, 추출 LLM 및 데이터베이스 에 따라 달라지며, 이 중 하나라도 실패할 수 있습니다. 사용자의 쓰기는 다운스트림에서 어떤 일이 발생하든 record_turn이(가) 반환되었을 때 성공했다는 것과 격리됩니다.
배후에서는 실패한 단계를 한 가지 질문으로 분류합니다. 즉, 요청 변경하지 않고 조건을 변경할 수 있나요? 환경 장애(네트워크 오류, 제공자 중단, 속도 제한, API 키 순환 중간)는 백오프를 사용하여 자동으로 재시도되고, 장애에 따라 속도가 조정됩니다: 네트워크 블립은 몇 초 내에 재시도하고, 자격 증명 문제는 키가 사람에 의해 순환되기 때문에 더 느리게 재시도됩니다. 재시도가 결과를 변경할 수 없으므로 콘텐츠 결정 실패는 재시도되지 않습니다. 영구적으로 반복되는 대신 연산자가 볼 수 있는 서버 측에 기록됩니다.
이는 외부 가장자리뿐만 아니라 전체 추출 경로에 적용됩니다. 실패한 단계는 더 이상 조용히 빈 결과를 생성하지 않습니다. 즉, 재시도하거나 연산자가 조치를 취할 수 있는 곳에 기록됩니다.
하나의 사용하지 않는 품목은 나머지를 버리지 않습니다. 단일 메모리를 임베드할 수 없는 경우(해당 내용이 모델에 비해 너무 길거나 제공자 거부한 경우) 해당 메모리는 계속 저장되고 동일한 배치 의 다른 메모리는 영향을 받지 않습니다. 저장된 메모리에 부족한 것은 벡터입니다. 실제로 다음을 수행합니다.
여전히
text검색 및hybrid로 찾을 수 있으며, 하이브리드는 두 순위를 결합하므로 텍스트 면에서 여전히 표면에 표시됩니다.벡터만 비교하는
semantic검색 에서는 찾을 수 없습니다.
이것이 기본값 검색 모드 로 hybrid 을(를) 선호하는 좋은 이유입니다. 정확한 식별자와 드문 단어에 대해 이미 더 나은 선택이며, 임베디드할 수 없는 메모리가 여전히 도달한다는 의미이기도 합니다.
이것이 에이전트 에게 의미하는 바는 다음과 같습니다.
제공자 중단으로 인해 추출된 지식이 지연됩니다. 자신의 차례를 잃지 않습니다. STM은 동기식으로 작성되며 영향을 받지 않습니다. 방금 언급한 내용이 필요할 때
stm를 계속 요청하세요.재시도에는 제한이 있습니다. 재시도 기간보다 오래 지속되는 종속성 중단은 무기한 반복되는 대신 재시도를 중지하고 실패는 삭제되지 않고 기록됩니다.
이 중 어느 것도 SDK를 통해 오류로 표시되지 않습니다. 추출 실패는 서버 측 문제입니다. SDK 표시 신호는 (아직) 검색에 나타나지 않거나 텍스트와 하이브리드를 통해 나타나지만 시맨틱 검색 나타나지 않는 추출된 메모리입니다.
읽기 작동 방식
조립된 산문 또는 기록 자체 - 두 가지 다른 질문입니다.
``build_context_from_sources(...)`` 가 기본값 으로 도달해야 합니다. 쿼리 와 토큰 예산을 제공합니다. 사용자가 지정한 메모리 유형 전체를 검색하고, 결과의 순위를 매기고, 중복에 가까운 항목을 삭제하고, 예산을 줄이고, 프롬프트에 바로 입력할 수 있는 항목을 반환합니다. 하나의 호출 뒤에 숨은 전체 검색 파이프라인 이며 소스당 하나의 사양이 필요하므로 모드와 필터는 모든 항목에 대해 한 번이 아닌 소스별로 설정하다 됩니다.
검색은 세 가지 방법으로 일치시킬 수 있습니다. semantic는 임베딩을 비교하고 동일한 MEAN 를 찾습니다. text은 단어를 일치시키고 동일한 내용을 찾는 항목을 찾습니다. hybrid가 두 가지를 모두 실행하고 순위를 통합합니다. 일반적으로 하이브리드가 올바른 기본값 입니다. 벡터 검색 만으로는 정확한 식별자와 드문 단어를 놓치고 텍스트 검색 만으로는 의역을 놓칠 수 있습니다.
``build_context(...)``는 더 간단한 빌더로 동일한 파이프라인 이지만 읽는 모든 소스에 하나의 모드 와 하나의 필터하다 적용 .
``검색(...)`` 및 유형별 검색 (search_semantic, search_episodes 등)은 직접 검사하거나 후처리하려는 경우 조립된 산문 대신 순위가 매겨진 레코드를 반환합니다.
메모리 범위 지정
모든 기록 기록된 ID를 포함하며, 모든 읽기는 이후가 아닌 데이터베이스 쿼리 에서 해당 ID로 필터링됩니다. 필드에는 조직, 사용자, 프로젝트, 세션 및 선택적으로 에이전트 와 기록 를 사용자에게 비공개로 유지할지 또는 더 널리 읽을 수 있도록 할지 여부를 결정하는 가시성(visibility)이 있습니다.
This matters for a practical reason: a search or build_context scoped to a user will not surface another user’s private memory, because the constraint is part of the query rather than a filter applied to its results. So bind(...) is not a convenience — it is how you declare the scope that subsequent reads and writes operate within, and getting it wrong writes one user’s memory under another’s identity.
user_id 및 visibility이(가) 다른 질문에 답변.
user_id 은(는) 누구의 메모리에 해당하는지 기록 . visibility은(는) 도달하는 거리입니다.
가시성 | 누가 읽을 수 있나요? |
|---|---|
| 다음에 이름이 지정된 사용자만 |
| 프로젝트 의 모든 사용자 — 더 이상 사용되지 않음, 아래 참조 |
| 프로젝트 의 모든 사용자 |
가시성 값은 기록 이 작성된 프로젝트 외부에 도달하지 않습니다. 메모리는 프로젝트 별로 저장되므로 프로젝트 경계는 가시성이 넘을 수 있는 것이 아닙니다 — org 은(는) 과거 이름으로, "한 사용자에게 제한되지 않음"을 의미합니다. "다른 프로젝트에 표시".
경고
⚠️ ``shared``는 더 이상 사용되지 않으며 향후 출시하다 에서 제거될 예정입니다. 단일 사용자 이외의 사용자에게 도달하려는 지식에는 org 을 사용하고, 소유자로 범위가 지정된 모든 지식에는 private 을 사용합니다. shared와 org는 모두 이미 동일한 도달 범위로 확인되므로 기존 기록 shared에서 org로 전환해도 해당 레코드를 읽을 수 있는 사람은 변경되지 않습니다. 이미 shared(으)로 기록된 레코드는 현재로서는 계속해서 다시 읽습니다.
이 둘은 독립적이며, 읽기 시 and로 결합되며, 절대로 as로 결합하지 않습니다. 입력하는 각 필드 쿼리 에 하나 이상의 동등성 조건을 추가합니다. 생략한 각 필드 해당 차원에 제약이 없는 상태로 유지됩니다.
읽기 범위를 지정합니다. | 당신은 돌아갑니다 |
|---|---|
| 모든 가시성에서 사용자가 소유한 모든 것 |
| 소유자와 관계없이 해당 가시성의 모든 기록 |
모두 | 둘 다 일치하는 레코드만 — 가장 좁은 읽기 |
...도 아니고 ...도 아니다 | 프로젝트 의 모든 것 |
세 번째 줄은 사람들을 놀라게 하는 줄입니다. search_semantic(query, user_id="user_1", visibility="org")는 'user_1의 메모리와 조직의 메모리'를 MEAN 하지 않습니다. 이는 'user_1가 소유한 조직에서 볼 수 있는 메모리'를 의미하며, 이는 두 제약 조건 중 하나보다 작습니다. 공유된 지식과 사용자의 비공개 메모리를 읽으려면 호출을 두 번 실행하고 결과를 직접 병합하는 방법은 없습니다.
설치
pip install agent-engine-sdk-memory
from agent_engine_sdk_memory import Memory, MemoryRequestContext
연결
에이전트 실행되는 위치에 따라 연결 방법이 결정되며 차이점은 대부분 누가 ID를 제공하느냐에 따라 달라집니다.
에이전트 실행 | 당신은 구성 | ID의 출처 | 를 참조하세요. |
|---|---|---|---|
플랫폼에서 | 아무것도 — 런타임 인젝션 | 호출당 런타임 | |
다른 곳에서는 |
| 서비스 계정 토큰과 함께 | |
로컬, 개발 중 |
| 당신이 무엇이든 |
API 는 세 가지 모두 동일합니다. 외부에서 배포된 에이전트 대해 작성된 코드는 플랫폼으로 이동해도 변경되지 않고 실행되며, 생성자 호출을 삭제 런타임이 대신 객체 제공합니다.
플랫폼에 배포된 에이전트는 무료로 ID를 얻을 수 있으며, 이것이 바로 실질적인 차이점입니다. 런타임은 처리 중인 호출에 대한 조직, 프로젝트, 사용자 및 세션을 이미 알고 있으므로 이를 바인딩합니다. 외부 에이전트 는 서비스 계정 토큰이 무엇을 의미하는지, 즉 프로젝트 만 알고 있으므로 각 호출이 속한 사용자와 세션을 메모리에 알려야 합니다. 이를 잘못 이해하면 한 사용자의 메모리를 다른 사용자의 ID로 기록하게 되며, 이것이 외부 경로에서 명시적이어야 하는 이유입니다.
호스팅된 플랫폼
managed 서비스입니다. 서비스 계정 액세스 토큰과 프로젝트 ID를 전달합니다.
agentengine CLI 사용하여 토큰을 발행합니다. 서비스 계정을 한 번 생성합니다. 클라이언트 시크릿은 한 번만 표시되므로 즉시 저장합니다.
agentengine service-account create my-agent --project-id <your-project-id> --role AGENT_DEVELOPER
그런 다음 클라이언트 ID 와 시크릿을 단기(1시간) 액세스 토큰으로 교환합니다(curl은 클라이언트 시크릿을 입력하라는 메시지를 표시하므로 셸 기록에서 제외됨).
ACCESS_TOKEN=$(curl --fail-with-body --silent --show-error --user <client-id> --data grant_type=client_credentials https://agentengine.mongodb.com/api/v1/oauth/token | jq -er .access_token)
memory = Memory(service_account_token="<your-access-token>", project_id="<your-project-id>")
입력 | 다음으로 돌아갑니다. | 참고 사항 |
|---|---|---|
|
| 베어러 자격 증명으로 전송되는 서비스 계정 액세스 토큰입니다. 만료되면 다시 발행하세요. |
|
| 읽고 쓰기 (write) 프로젝트 입니다. 호스팅된 서비스에 필요합니다. |
|
| 선택 사항. 비프로덕션 스택 대상으로 호스팅하다 재정의합니다. |
플랫폼은 사용자의 자격 증명을 프로젝트 에 고정하므로 일치하지 않는 project_id는 거부됩니다. 빈 service_account_token은 ValueError를 발생시킵니다.
api_key (및 AGENTIC_MEMORY_API_KEY)은(는) 더 이상 사용되지 않는 별칭으로 허용된 상태로 유지되고 DeprecationWarning을 방출합니다. 새 입력과 레거시 입력을 모두 전달하면 ValueError가 발생합니다. 프로젝트 API 키는 더 이상 HTTP 통해 생성할 수 없으므로 새로운 통합은 서비스 계정 토큰을 사용해야 합니다.
지역 개발
직접 실행 백엔드( 예: 스택 agentengine dev up가 시작됨)를 가리킵니다.
memory = Memory(base_url="http://localhost:8080")
입력 | 다음으로 돌아갑니다. | 참고 사항 |
|---|---|---|
|
| 백엔드의 URL. |
|
| 선택 사항. 로컬 개발을 위해 생략합니다. ( |
로컬 개발을 위해 project_id을 비워 둡니다.
플랫폼 에이전트 내부(앱 바운드)
에이전트 가 Atlas Agent Engine에서 실행될 때는 Memory 인스턴스 전혀 구성하거나 연결하지 않습니다. 애플리케이션 코드는 위의 입력 중 어느 것도 전달하지 않습니다. 런타임에 전달된 처리하다 을 사용합니다. ID(사용자, 세션, 조직, 프로젝트)는 앰비언트 런타임 컨텍스트에서 확인되므로 작업을 직접 호출할 수 있습니다.
# `memory` is supplied by the platform runtime — do not construct it. memory.record_turn(role="user", content="I'm allergic to penicillin.") context = memory.build_context(query="What medications should I avoid?") # bind(...) is still available to scope a call chain to a specific identity.
앱 바인딩 경로에는 몇 가지 역량 격차(공구 호출/모형 회전 메타데이터 및 일부 목록 스타일 읽기)가 있습니다.각 연결이 지원하는 항목의 앱 바인딩 열 및 `docs/capability-matrix.md <docs/capability-matrix.md>`__를 참조하세요.
환경 변수는 폴백입니다.
인수를 생략하면 각 입력도 AGENTIC_MEMORY_* 환경 변수로 대체됩니다. 명시적인 인수는 항상 이깁니다. 인수가 없는 Memory()은 환경에서 세 가지를 모두 읽습니다.
라우팅 작동 방식
project_id 통화가 이동하는 위치를 결정합니다. 인증은 절대 그렇지 않습니다.
project_id를 설정하면 SDK가 프로젝트의 경로/api/v1/projects/{project_id}/memory/*를 호출합니다.비워 두면 SDK가 백엔드
/api/v1/memory/*를 직접 호출합니다.
project_id 가 설정하다 되었지만 백엔드 일치하는 경로(예: 로컬 백엔드 ) 가 없는 경우 호출은 설정 해제를 위한 힌트와 함께 `MemoryRouteNotFoundError <#errors>`__를 발생시킵니다. 그 반대도 마찬가지입니다. project_id 없이 호스팅된 서비스를 대상으로 지정하고 이를 설정하다 하는 힌트와 함께 404를 호출합니다.
고급: 인증된 직접 백엔드
인증과 라우팅은 독립적이므로 project_id이 비어 있는 service_account_token을 전달할 수 있습니다. 그런 다음 SDK는 프로젝트 경로를 건너뛰고 직접 경로에서 인증된 호출을 base_url의 백엔드 로 직접 보냅니다. 이는 직접 도달하는 호스팅된 오케스트레이션 엔진(OE)에 적합합니다.
각 연결이 지원하는 것
기능은 인증이 아닌 통화가 라우팅되는 위치를 따릅니다.
작업 | 호스팅(project_id 설정하다) | 직접(project_id 비어 있음) | 앱 바운드 |
|---|---|---|---|
| ✓ | ✓ | ✓ |
| ✓ | ✓ | ✓ |
| ✓ | ✓ | ✗ |
| ✓ | ✓ | ✓ |
| ✓ | ✓ | ✓ |
| ✓ | ✓ | ✓ |
유형별 CRUD ( | ✓ | ✓ | ✓ 간격 있음 |
사용자 지정 유형 | ✓ (플래그 게이트) | ✗ 실행 컨텍스트 없음 | ✓ |
지원되지 않는 호출은 `MemoryNotSupportedError <#errors>`__를 발생시킵니다 — 알려진 백엔드별 격차에 대한 네트워크 요청 이전 또는 플랫폼만 보고할 수 있는 역량 격차에 대한 응답 후(Errors 참조) — 조용한 실패나 원시 오류가 발생하지 않습니다. HTTP 오류입니다. 유형별 CRUD 의 앱 바인딩된 간격을 포함한 전체 백엔드별 참조는 `docs/capability-matrix.md <docs/capability-matrix.md>`__에 있습니다.
앱 바인딩 에이전트는 위의 모든 사항에 대한 예외입니다. 배포된 플랫폼 에이전트 내부에 플랫폼이 준비된 runtime를 주입하므로 애플리케이션 코드는 이러한 입력 중 어느 것도 전달하지 않습니다.
사용
완전한 왕복: 메모리를 구성하고, 대화 ID를 바인딩하고, 차례를 기록 , 컨텍스트를 조회 .
from agent_engine_sdk_memory import Memory, MemoryRequestContext memory = Memory(service_account_token="<your-access-token>", project_id="<your-project-id>") # Scope every call to a user and conversation. session = memory.bind(MemoryRequestContext(user_id="user_1", session_id="thread_123")) # Record what happened. session.record_turn(role="user", content="I'm allergic to penicillin.") session.record_turn(role="assistant", content="Noted — I'll avoid it.") # Later, pull back the relevant context for a new prompt. Include "stm" # to surface the turns just recorded (the default is episodic, semantic). # max_tokens is an optional gross context-construction budget. context = session.build_context( query="What medications should I avoid?", enabled_sources={"stm", "episodic", "semantic"}, max_tokens=2048, ) # context is a ContextResponse — inject its content into the next prompt.
bind(ctx) 원본을 변경하지 않고 범위가 ctx인 새 처리하다 반환하므로 하나의 Memory이(가) 많은 사용자와 세션에 동시에 제공 할 수 있습니다.
``build_context`` 기본값 소스입니다. 생략된 enabled_sources 기본값은 episodic 및 semantic입니다. stm, taxonomic, procedural 에는 명시적 설정하다 필요합니다.
``max_tokens``. 선택적 양수 총 컨텍스트 구성 예산입니다. 이는 가져오기 비용 이나 약속된 출력 크기가 아닙니다. 검색 및 순위 지정 후 서버 500-토큰 서식 지정 예비비를 뺀 다음 나머지에 맞는 전체 메모리 청크를 탐욕스럽게 선택합니다. 500 이하의 양수 값은 메모리를 위한 예산을 남기지 않습니다. 500를 초과하는 값은 청크 맞지 않을 때 빈 컨텍스트를 생성할 수 있습니다. metadata.token_count는 형식이 지정된 출력만 보고하고 예비는 제외합니다. 이전 동작을 유지하려면 max_tokens를 생략하세요.
``format_style`` 및 ``include_memories``. build_context build_context_from_sources은(는) 두 가지 응답 형성 옵션을 허용합니다. format_style("openai", "claude" 또는 "jinja2", FormatStyle 열거형 유형 주석을 위해 내보내짐)이 formatted_context의 형식을 선택하고, 유효하지 않은 값은 로컬에서 ValueError을 발생시킵니다. 생략하면 서버 구성된 모델에서 형식을 유추합니다. 한 가지 주의 사항: 서버 현재 명시적 값이 기본값 모델 유형과 일치할 때 다시 추론하므로 명시적 "openai"는 OpenAI 제품군 모델이 구성된 서버에서만 그대로 적용됩니다. "claude"와 "jinja2"은 항상 존중됩니다. include_memories=True는 응답의 selected_memories를 사후 예산 MemoryChunk 목록으로 채우므로, 어떤 메모리가 선택되었는지 정확하게 검사할 수 있습니다. 둘 다 호스팅 또는 직접 HTTP 연결이 필요합니다. 앱 바인딩 모드 둘 중 하나가 설정하다 경우 MemoryNotSupportedError를 발생시킵니다.
소스별 컨텍스트 — ``build_context_from_sources``. build_context이(가) 모든 소스에 하나의 필터하다 와 시맨틱 검색을 적용하는 경우, 이 메서드를 사용하면 각 소스가 다음을 통해 자체 검색 mode(text, semantic 또는 hybrid), metadata_filter 및 top_k를 선언할 수 있습니다. SourceSpec. 결과는 여러 소스에서 병합 및 중복 제거되며, 선택적으로 관련성 rerank에 따라 재정렬된 다음 build_context와 같이 형식이 지정되고 예산이 책정됩니다. metadata.ranking_strategy 및 metadata.source_outcomes는 최종 주문이 어떻게 생성되었으며 각 소스가 어떻게 처리되었는지 보고합니다. sources는 비어 있지 않아야 하며 각 소스를 최대 한 번 나열할 수 있으며, 각 소스의 top_k는 1에서 200 사이여야 합니다. session_id은 stm 소스가 포함된 경우에만 필요합니다.
하이브리드는 일반적으로 텍스트가 포함된 소스에 적합한 기본값 입니다. 벡터 검색 만으로는 정확한 식별자와 드문 단어를 놓치고, 텍스트 검색 만으로는 의역을 놓치게 됩니다. 사양에서 생략된 경우 mode의 기본값은 semantic입니다.
필터링 가능한 메타데이터 선언. 필터하다 결과가 아닌 검색 인덱스 내부에 적용되므로 metadata_filter는 프로젝트 에서 선언한 메타데이터 이름만 지정할 수 있습니다. 속성과 이를 제공 해야 하는 인덱스 레그를 project-config.yaml에서 선언합니다.
metadata_partition_key: # Filterable metadata attributes (max 10) - name: tier type: string # string | number | boolean | date - name: confidence type: number metadata_partition_index: semantic: [both] # both legs, so a hybrid source can filter short_term: [both] # stm is searchable only once listed here short_term: embed_on_write: true # required to give stm a vector leg
참고
메모리 서버 0.0.81 이상이 필요합니다. 파티션 키는 이를 지원하는 런타임에서만 사용되며, 메모리 서버 스타트업 시 구성을 읽으며, 구성을 저장하는 것은 적용되지 않습니다. project-config.yaml를 편집한 후 agentengine memory configure로 업로드한 다음, 런타임을 현재 이미지에 롤링합니다.
agentengine memory apply --upgrade
--upgrade 런타임을 환경이 현재 고정하고 있는 이미지로 이동하여 최신 메모리 서버를 선택합니다. 이것이 없으면 런타임은 이미 있는 이미지를 유지합니다. agentengine memory apply --dry-run은(는) 변경하기 전에 확인하려는 경우 사용 중인 이미지를 보고하고, --wait는 런타임이 준비 상태가 보고될 때까지 차단합니다.
필터하다 쓰기 (write) 전에 알아둘 가치가 있는 네 가지 결과:
필터하다 키는 선언된 이름이 아닌 정규화된 인덱스 경로입니다.
tier로 선언된 속성은metadata.tier에서 인덱싱되며, 필터하다 이를 말해야 하며, 접두사가 붙지 않습니다.키는 나열한 레그에서만 필터링할 수 있습니다.
metadata_partition_index소스를[vector],[text]또는[both]에 매핑하고hybrid소스에[both]가 필요합니다: 텍스트 레그가 제공 할 수 없는 필터하다 쿼리 실행되기 전에 거부되며, 자동으로 더 적게 반환하는 대신 쿼리가 실행됩니다.잘못된 키는 큰 소리로 실패합니다.
build_context의 단일 최상위metadata_filter와 달리, 소스별 키는 선언된 설정하다 에 대해 유효성을 검사합니다. 선언되지 않았거나 철자가 잘못된 경로는MemoryBadRequestError를 발생시키며, 메시지에는 허용된 경로가 나열되어 있으므로, 오타가 좁혀진 결과 설정하다 조용히 반환하는 대신 호출에서 실패하게 됩니다.Short-term memory has no index of its own. It is filterable — and searchable by this method at all — only once the project lists
short_terminmetadata_partition_index. Until then anstmsource fails rather than returning nothing: the search errors, and the source is reported with anerrorinmetadata.source_outcomes. Ifstmwas the only source requested, every source has failed and the call returns 503 rather than an empty context, because an empty result would be indistinguishable from a healthy search over an empty corpus. Giving it a vector leg ([vector]or[both]) also requiresshort_term.embed_on_write: true, and the configuration is rejected without it, because a vector index over turns that are never embedded would be dead weight. The text leg needs no embeddings.
선언된 type은 일치하는 의미 체계를 설정합니다. string 키는 토큰으로 인덱싱되므로 일치 항목은 전체 값이며 대소문자를 구분합니다. 즉, "gold"는 Gold이나 gold-tier 중 어느 것과도 일치하지 않습니다. 범위 연산자에는 number 또는 date 키가 필요합니다.
지원되는 절: 같음; $gt / $gte / $lt / $lte, 결합된 경계가 하나의 범위 로 통합됨 ; 세트의 경우 $in / $nin입니다. $ne; $exists; 및 구성을 위한 $and / $or / $nor입니다.
agent_id 선언하지 않고도 필터링할 수 있습니다. 테넌시 필드 org_id, user_id, project_id, session_id, visibility, deleted, is_latest, has_embedding는 액세스 제어를 위해 예약되어 있으며 호출자가 필터링할 수 없습니다.
함께 정리합니다. 위의 구성을 사용하면 다음과 같습니다.
from agent_engine_sdk_memory import SourceSpec context = session.build_context_from_sources( query="what did we decide about the refund policy?", sources=[ # Exact match on a string key, and a range on a numeric one. SourceSpec( source=MemorySource.SEMANTIC, mode=RetrievalMode.HYBRID, metadata_filter={ "metadata.tier": "gold", "metadata.confidence": {"$gt": 0.8}, }, top_k=20, ), # Sources without a filter are unrestricted. SourceSpec(source=MemorySource.EPISODIC, mode=RetrievalMode.HYBRID, top_k=5), SourceSpec(source=MemorySource.STM, mode=RetrievalMode.TEXT, top_k=10), ], rerank=True, )
이 메서드는 세 가지 연결 모드 모두에서 백엔드 에 도달합니다. 호스팅된 프로젝트 경로(project_id 설정하다)에서 게이트웨이는 동일한 소스별 핸들러로 프록시하여 인증된 세션에서 org/ 프로젝트 스탬핑합니다. 직접 경로(project_id가 비어 있음)에서 OE 프록시가 이를 전달합니다. 온플랫폼(앱 바인딩) 런타임에서 플랫폼은 테넌시를 스탬프 처리하고 지속형 실행을 통해 전체 응답을 다시 전달합니다.
record_turn 및 build_context 외에도 Memory 객체 다음을 노출합니다.
검색 —
search(query, sources=[...])이(가) 여러 메모리 유형에 걸쳐 정렬되어 순위가 매겨진list[MemoryChunk]을(를) 반환합니다.search_semantic,search_episodes,search_taxonomic및discover_procedures는 단일 유형을 대상으로 합니다.유형별 쓰기 및 읽기(연결이 CRUD 지원하는 경우) —
save_semantic/get_semantic,save_episode/list_episodes,save_taxonomic/get_taxonomic_term/list_domains및save_procedure/get_procedure.사용자 지정 메모리 유형 —
save(memory_type, content, tags=...)및retrieve(memory_type, query, tags=..., top_k=...)는 프로젝트의 메모리 구성에 선언된 유형에서 작동합니다. 내장 유형 이름은 거부됩니다 — 위의 전용 메서드를 사용하세요. 이러한 호출에는 ID 필드가 없습니다. 플랫폼은 요청 에서 조직, 프로젝트 및 사용자를 스탬프 처리합니다. 사용자 지정 유형 경로를 제공 하지 않거나 기능 비활성화된 플랫폼에서 호출은`MemoryNotSupportedError<#errors>`__를 발생시킵니다.
위에서 바인딩된 session를 사용하는 짧은 예시 — 팩트를 쓰기 (write) , 레이블로 다시 읽고, 여러 유형에서 검색 :
# Save a semantic fact (user_id is inherited from the bound session). session.save_semantic(text="Prefers window seats on flights.", label="seat-preference") # Read it straight back by label. fact = session.get_semantic("seat-preference") # Search across memory types; returns one ranked list[MemoryChunk]. hits = session.search("travel preferences", sources=["semantic", "episodic"], top_k=5)
Memory 컨텍스트 관리자이기도 합니다. with Memory(service_account_token=...) as memory:은 종료 시 기본 전송을 해제합니다.
메모리 서버 구성
SDK는 메모리를 읽고 씁니다. 서버 구성하지 않습니다. 설정 - 임베딩, 메모리 유형이 추출되는 추출 LLM, 필터링 가능한 메타데이터 - 프로젝트 project-config.yaml의 memory: 차단 에 있으며 CLI 통해 적용됩니다. 해당 하위 문서만 업로드됩니다. 파일 의 나머지 부분은 무시됩니다.
agentengine memory configure # store the memory: block for this project agentengine memory apply --wait # roll the memory server so it takes effect
저장은 적용되지 않습니다. configure 은 구성을 저장하고 플랫폼은 자체적으로 프로젝트의 메모리 서버 에 구성을 전달하지만 서버 스타트업 시에만 구성을 읽습니다. 파드가 다시 시작될 때까지 새 설정은 읽지 않은 상태로 디스크에 보관됩니다. agentengine memory apply가 재시작을 수행하고, 프로젝트 에 아직 메모리 런타임이 없는 경우 먼저 메모리 런타임을 프로비저닝합니다.
agentengine memory apply --upgrade 또한 런타임을 환경이 현재 고정하고 있는 메모리 서버 이미지로 이동하므로 최신 서버 선택할 수 있습니다. --upgrade이 없으면 이미지만 남습니다. agentengine memory status은(는) 언제든지 런타임 상태 보고합니다. apply의 --wait는 준비될 때까지 차단합니다.
나중에 변경할 수 없는 설정
구성의 일부는 사실상 한 번 쓰기이므로 메모리 쓰기를 시작하기 전에 결정합니다.
메타데이터 파티션 키 - 선언된 필터링 가능한 속성입니다. 선언된 후에는 키는 제거하거나 유형을 변경할 수 없습니다.
사용자 지정 메모리 유형 선언 — 일단 유형이 허용되면 해당 컬렉션 과 태그 세트 config API 통해 편집하거나 제거할 수 없습니다. 대신 새 유형 이름을 선언합니다.
검색 인덱스 — 아직 존재하지 않는 경우에만 프로비저닝됩니다. 서버 시작된 후 파티션 키 추가해도 기존 인덱스 다시 작성되지 않습니다. 그러면 드리프트가 기록되고 새 키에 대한 필터하다 자동으로 무시되지 않고 데이터베이스 에서 실패합니다. 인덱스 다시 만들기는 수동 작업입니다.
로그 수준, 추출 LLM 및 활성화된 추출 유형을 변경하고 다시 적용할 수 있습니다. 임베딩 모델 또는 차원을 변경하려면 기존 메모리를 마이그레이션하고 다시 임베딩해야 합니다. 차원을 변경하려면 벡터 검색 인덱스를 다시 작성해야 합니다.
ID 확인 방법
메모리 작업의 범위는 MemoryRequestContext로 전달되는 user_id, agent_id 및 session_id입니다. 각 호출에 대해 모든 필드 우선 순위가 가장 높은 세 가지 계층을 통해 확인됩니다.
호출 인수 — 메서드에 직접 전달된 값(예:
search_semantic(query, user_id="user_2")).바인딩된 컨텍스트 —
MemoryRequestContext가bind(...)에 전달되었습니다.런타임 컨텍스트 — 런타임에서 제공하는 앰비언트 ID로, 앱 바인딩된 경로에서 사용합니다.
Blank or whitespace-only values count as unset at every tier; agent_id is always optional. Identity is validated client-side only for the type-specific writes: save_semantic, save_taxonomic, and save_procedure require a user_id, and save_episode requires both user_id and session_id — each raises MemoryIdentityError when the field cannot be resolved. The workflow operations (record_turn, build_context, the searches) and the get_* / list_* reads do not enforce identity locally; they forward whatever resolves to the backend, which may reject the request as a transport error.
``session_id``의 범위는 작업별로 지정됩니다. 대화를 식별하므로 대화 I/O: record_turn 및 build_context의 단기 메모리 레그에 대해서만 (bind/runtime에서) 상속됩니다. 일시적 검색 및 시맨틱 검색 이를 상속하지 않으며 — search_episodes, list_episodes 및 search()의 일시적 검색은 호출 인수에서만 session_id를 해결합니다. 일시적인 메모리는 범위가 지정되지 않은 상태로 세션에 저장되므로(연결된 에피소드는 session_id: null을 가짐), 바인딩된 세션은 모든 지속형 메모리를 자동으로 필터하다 하고 오류 없이 빈 목록을 반환합니다. 세션 범위의 일시적인 읽기를 원하는 경우 검색 호출에 session_id=를 명시적으로 전달합니다. ( 이렇게 하면 SDK가 플랫폼 agent-engine-sdk-langgraph / TenantRuntime 경로와 일치하게 되며, 이 경로에는 이미 간헐적 검색 명시적인 session_id 이 필요합니다 .) user_id 및 agent_id 는 영향을 받지 않으며 여전히 bind/runtime 에서 상속됩니다. on 읽기.
쓰기 (write) 에 대한 가시성 설정
모든 쓰기 (write) visibility이(가) 걸립니다. 유형이 다르게 사용되기 때문에 기본값 메모리 유형에 따라 다릅니다.
쓰기 | 기본값 가시성 |
|---|---|
|
|
|
|
도메인 어휘는 텀 에 따라 공유되기 때문에 분류학적 메모리 기본값은 org입니다. 다른 모든 항목의 기본값은 private이므로, 저장하는 팩트의 범위는 별도로 지정하지 않는 한 해당 정보를 학습한 사용자로 지정됩니다.
record_turn 는 예외입니다: visibility 및 user_id도 필요하지 않습니다. 대화 차례는 항상 바인딩된 사용자 및 세션 아래에 기록되므로, 차례를 기록하기 전에 bind(...) — 사용자의 차례를 설정하다 수 있는 호출별 방법이 없습니다.
# Private to user_1 — the default. session.save_semantic(text="Prefers window seats.", label="seat-preference") # Readable across the whole organization. session.save_semantic( text="Refunds over $500 need manager approval.", label="refund-policy", visibility="org", )
읽기 범위 지정
읽기는 visibility를 설정하지 않은 상태로 두므로, 일반적으로 바인딩된 user_id인 확인되는 ID에 의해서만 제약을 받습니다. 이는 개인화 위한 올바른 기본값 입니다. 즉, 모든 가시성에서 사용자가 소유한 모든 것을 얻을 수 있습니다.
공유된 지식에 도달하려면 가시성 및 여기 및 규칙 바이트를 전달합니다. user_id="user_1"에 바인딩된 처리하다 여전히 해당 user_id에 기여하므로 user_1가 소유한 조직 표시 레코드만 읽습니다.
session = memory.bind(MemoryRequestContext(user_id="user_1", session_id="thread_123")) session.search_semantic("refund policy", visibility="org") # user_1 AND org
user_id=None을 전달해도 확장되지 않습니다. None 또는 빈 인수는 모든 계층 에서 '제공되지 않음'으로 간주되므로 바인딩된 값에 속합니다. user_id 바운드가 없는 처리하다 사용하여 모든 사용자를 읽습니다.
# The original handle is unbound, so it carries no user_id. memory.search_semantic("refund policy", visibility="org") # Or bind only the parts you want. thread = memory.bind(MemoryRequestContext(session_id="thread_123")) thread.search_semantic("refund policy", visibility="org")
따라서 사용자의 기록과 팀이 공유한 지식이 모두 필요한 어시스턴트는 이를 두 번 읽고 병합합니다.
personal = session.search_semantic(query, top_k=5) # user_1, any visibility shared = memory.search_semantic(query, visibility="org", top_k=5) # org-wide, any owner
오류
오류는 두 가지 유형으로 나뉩니다. 클라이언트 사이드 오류는 ValueError의 하위 클래스로, 일반적으로 네트워크 호출 전에 발생합니다.
MemoryClientError— 사용 오류의 기준입니다.MemoryIdentityError— 필수 ID 필드 확인할 수 없습니다.ValueError를 직접 서브클래스화합니다(MemoryClientError의 형제이므로except MemoryClientError에 잡히지 않음).MemoryNotSupportedError— the operation is unavailable for the active connection (see Connecting). The message names the operation and the reason. For the custom-type methods (save/retrieve) it can also be raised after the HTTP call, when the response shows the platform lacks the capability: a bare 404/405 (platform too old to serve the route) or the gateway’s structured 400 reporting custom memory types disabled on the deployment. A structured unknown-type 404 is a request error, not a capability gap, and raisesMemoryBadRequestError.
전송 오류는 MemoryAPIError에서 파생되며 HTTP status 및 응답 본문을 전달합니다.
MemoryAuthError— 인증 또는 권한 부여 실패(401/403).MemoryBadRequestError— 요청 이 거부되었습니다(인증 또는 프로비저닝되지 않은 4xx 이외의 경우).MemoryRouteNotFoundError— 코어 루프 요청 404 처리되어 경로 형태가 백엔드 일치하지 않을 가능성이 높습니다. 이 메시지는project_id을 설정하다 하거나 해제하기 위한 방향 힌트를 제공합니다. 서브클래스MemoryBadRequestError.MemoryNotProvisionedError— 프로젝트의 메모리 런타임에 아직 연결할 수 없습니다.MemoryServerError— 백엔드 오류가 발생했거나(5xx) 구문 분석할 수 없거나 예기치 않은 본문이 반환되었습니다.MemoryConnectionError— 백엔드 에 연결할 수 없습니다.
모델
요청 및 응답 유형은 패키지 루트에서 내보내지고 agent_engine_sdk_memory.models에서 다시 내보내집니다. 검색은 MemoryChunk 및 ContextResponse를 반환합니다. WriteTurnResult, CreateSemanticResult, CreateEpisodicResult 등의 반환 유형 결과를 작성합니다. SearchSource는 검색 가능한 유형을 열거합니다. 컨텍스트 빌딩은 별도의 구성 모델이 아닌 Memory.build_context( 예시 : enabled_sources 및 max_tokens)에서 kwargs로 구성됩니다. agent_engine_sdk이 아닌 agent_engine_sdk_memory에서 가져옵니다.
자체 메타데이터 다시 읽기
record_turn 선택적 metadata 딕셔너리를 취하며, 단기 검색은 청크 의 자체 슬롯인 chunk.metadata["metadata"]에서 이를 반환합니다. 키는 플랫폼의 턴 필드(session_id, role, turn_seq, ...)와 혼합되지 않고 별도로 유지되므로 키가 서로 충돌하지 않습니다. 키의 이름을 role 또는 session_id를 생성하고 사용자 자신의 값을 다시 읽습니다.
Two limits that collision-safety does not cover. Values have to survive the round trip, so they must be JSON-serializable and of a sane size. And to be filterable a key additionally has to be declarable as a metadata partition key: each dot-separated segment must match ^[a-z][a-z0-9_]{0,63}$, at most one dot is allowed, and a few names are reserved (org_id, project_id, user_id, agent_id, content, embedding, embedding_model_id, created_at). A key outside that shape — Tier, $foo, a.b.c — is still stored and returned, it just cannot be filtered on.
An empty dict is treated as no metadata: metadata={} records the turn without a metadata slot on the chunk, so read it with chunk.metadata.get("metadata", {}) if the caller might not have supplied any. Semantic memory behaves identically, which is what lets one read path cover both. Episodic, taxonomic and procedural behave the same way: the dict you write comes back under chunk.metadata["metadata"], and an empty one means no slot at all. Episodic is the one exception: a compatibility filter drops the whole dict, unrelated keys included, if it happens to contain citation_score, llm_confidence_score and combined_score together, since that shape also matches a pre-migration internal blob. Retrieval may also carry chunk.metadata["contextual_metadata"] — that is the platform’s own extraction artifact, not your data, and it is not part of any contract you should depend on.
단기 기억은 세션으로 범위가 지정되므로 쓰기 (write) 와 읽기는 동일한 이름을 지정해야 합니다.
from agent_engine_sdk_memory import ( Memory, MemoryRequestContext, MemorySource, RetrievalMode, SourceSpec, ) session_id = "session-42" memory = Memory(base_url="http://localhost:8080").bind( MemoryRequestContext(user_id="user-1", session_id=session_id) ) memory.record_turn( role="user", content="The engagement is green and the rollout continues.", metadata={"engagement_id": "eng-alpha", "tier": 2}, ) context = memory.build_context_from_sources( query="what is the engagement status?", sources=[ SourceSpec( source=MemorySource.STM, mode=RetrievalMode.HYBRID, metadata_filter={"metadata.engagement_id": "eng-alpha"}, ) ], session_id=session_id, include_memories=True, ) for chunk in context.selected_memories or []: print(chunk.metadata["metadata"]["engagement_id"])
Atlas Search 쓰기 (write) 비동기적으로 인덱싱하므로 직후에 실행된 읽기는 아직 순서를 확인할 수 없습니다.
알아야 할 한 가지 철자 차이는 중첩된 딕셔너리 chunk.metadata["metadata"]["engagement_id"] 내의 베어 이름을 읽지만 정규화된 인덱스 경로 {"metadata.engagement_id": ...}를 필터하다 것입니다. 둘 다 중첩을 인정합니다 — 필터하다 저장된 문서 주소로 하며, 여기서 딕셔너리는 실제로 metadata 아래에 있습니다.
베어 이름에 대한 필터링은 허용된 경로를 나열하는 오류와 함께 거부되므로 실수를 통해 답변 알 수 있습니다.
먼저 프로젝트 에 대해 필터링 가능한 메타데이터 선언해야 합니다. 위의 engagement_id는 metadata_partition_key 아래에 나타나야 하며, short_term는 metadata_partition_index에 나열되어야 합니다.사용에서 필터링 가능한 메타데이터 선언을 참조하세요.
내부
아래 섹션에서는 패키지 빌드되는 방법을 설명합니다. 사용하는 데는 필요하지 않습니다.
패키지 레이아웃
agent_engine_sdk_memory/ ├── memory.py # Memory — the public, transport-free facade ├── protocol.py # MemoryRequestContext, MemoryRuntime + MemoryCrudClient seams ├── identity.py # resolve_identity — call arg > bind ctx > runtime ctx ├── errors.py # MemoryIdentityError + the typed transport-error family ├── models.py # Pydantic models for memory requests/responses ├── validation.py # require_positive_max_tokens — public build_context guard ├── _transport.py # _HttpTransport — shared retry / error-mapping / lifecycle ├── _http_runtime.py # _HttpMemoryRuntime — the workflow ops + per-backend profiles ├── _direct_crud.py # empty-tenancy MemoryCrudClient over the shared transport ├── _wire.py # custom-type request-body builders shared by the CRUD clients ├── _tag_syntax.py # client-side custom-type name + tag-syntax checks ├── _client.py # MemoryClient — internal HTTP client for the Memory Server API └── _denylist.py # do-not-add dependency denylist (see below)
Memory 즉, 워크플로 작업(record_turn, build_context, 검색, discover_procedures)을 삽입된 MemoryRuntime에, 유형별 CRUD 삽입된 MemoryCrudClient에 위임합니다. 공개 표면은 tests/test_package_contract.py의 스냅샷 테스트로 인해 동결됩니다. MemoryClient은(는) 내부에 유지됩니다. 호출별 테넌시(org_id, 본문 수준 project_id)는 공개 서명에 표시되지 않습니다. 공개 표면의 유일한 project_id는 요청 본문이 아닌 URL 로 이동하는 선택적 생성자 경로 형태 선택기입니다.
종속성 거부 목록
The pydantic + httpx-only constraint is enforced, not aspirational. _denylist.py lists known-heavy distributions and import names (langchain, fastapi, pymongo, …), and tests/test_package_contract.py fails if importing the package pulls any of them into sys.modules.
누가 그것을 사용 하 여
agent-engine-runner-shared 이 패키지 작업 공간 종속성으로 선언하고 agent_engine_runner_shared/memory.py에 내부 MemoryClient를 구성하여 실행 컨텍스트 조회를 execution_id_provider 콜러블로 전달하여 이 패키지 플랫폼 코드를 가져오지 않고도 요청별 실행 ID 헤더가 작동하도록 합니다.