Upgrade to PRO for Only $50/Year—Limited-Time Offer! 🔥

Building Serverless AI Memory with Mastra × AWS

Avatar for vvatanabe vvatanabe
December 20, 2025

Building Serverless AI Memory with Mastra × AWS

Avatar for vvatanabe

vvatanabe

December 20, 2025
Tweet

More Decks by vvatanabe

Other Decks in Technology

Transcript

  1. Mastra × AWS における サーバーレスな AI メモリの実現 DynamoDB / Aurora

    Serverless v2 / Aurora DSQL 実践比較 2025.12.20 JAWS-UG Presents - AI Builders Day Speaker : Yuichi Watanabe @Nulab Inc.
  2. セッション概要 AIエージェントは LLM がステートレス。記憶層の設計が品質とコストに直結する。 ここでは「運用負荷を抑える」前提で、どこに何を保存するかを整理する。 ポイント DynamoDB / Aurora v2

    / DSQL の 向き・不向き Memory 特有の 落とし穴(サイズ、ページング、分析、スケールゼロ、運用) 要件別の 構成パターン(どれを採用すると“何が増える”か) セッション概要
  3. 前提:なぜ AI Agent の Memory は難しい? LLM は ステートレス。アプリ側で「記憶」を外部化する必要がある。 ただし

    Memory は一般的な CRUD とアクセスパターンが違う。 追記が多い(会話ログは基本 append-only) 一部は頻繁に更新(Working Memory の差分更新) 意味検索が必要(Semantic Recall / RAG) サイズが増えやすい(Tool 出力の巨大 JSON、添付、ログ…) 分析したくなる(改善ループ:どのツールが効いた?どこで詰まった?) 前提:なぜ Memory が難しい?
  4. スケールは強い。だが Memory は「別部品」と「回避策」が増えがち Mastra 公式アダプタ: @mastra/dynamodb 、内部は ElectroDB(シングルテーブル) 特性:アイドル課金が小さい /

    スパイク設計がしやすい / DB運用作業が少ない import { DynamoDBStore } from "@mastra/dynamodb"; import { Memory } from "@mastra/memory"; const agent = new Agent({ memory: new Memory({ storage: new DynamoDBStore({ name: "dynamodb", config: { tableName: "mastra-single-table", region: "us-east-1", }, }); }); Round 1 - DynamoDB
  5. DynamoDB の得意・不得意 DynamoDB は 想定したクエリは単純で速い。 一方、想定外の条件追加は GSI 設計 or スキャンになりがち。

    決め打ちの読み取り 例:特定スレッドのメッセージを作成日時順に取る 後から増える検索・分析 例:metadata 条件で絞る、集計したい Memory は「改善のための分析要求」が後から増える → ここで負債化しやすい Round 1 - DynamoDB
  6. DynamoDB の Memory で当たりやすい落とし穴 ベクタ検索が別系統:DynamoDB 単体でベクタ検索をサポートしていない 400KB 制限:Tool 出力の巨大 JSON

    で破綻しやすい 条件検索:スキャン or 事前に GSI(将来の条件が読めない) ページングのギャップ:スレッド・メッセージの UI は offset、DynamoDB は cursor 結論:“DynamoDB が吸収してくれない制約” を アプリ側で吸収し続ける ことになりがち Round 1 - DynamoDB
  7. DynamoDB の課題と解決策のパターン 課題 解決策 代償 400KB S3オフロード(DDBは索引、本文はS3) GC / 書込順序

    / 整合性 ベクタ検索 OpenSearch/pgvector/S3 Vectors など 別部品 検索と運用が二系統になる 検索 重要キーだけGSI、残りはETLで分析基盤へ 先読み設計 or パイプライン ページング カーソルとオフセットの対応表キャッシュ保持 仕組みを作るコスト Round 1 - DynamoDB
  8. Round 1 結論 マッチする: Conversation History(スレッド・メッセージ) :単純な追加と一覧取得 小さめの Working Memory:単一キー更新

    + 条件付き更新(OCC 風) マッチしにくい: 柔軟検索・集計:GSI設計か別基盤へ Semantic Recall:ベクタストア別建て 巨大ログ:S3オフロード前提になりやすい Round 1 - DynamoDB
  9. Round 2 - Aurora Serverless v2 (PostgreSQL) SQL / JSON

    / トランザクションを使える一方、待機コストと再開遅延を考える Round 2 - Aurora Serverless v2(PostgreSQL)
  10. SQL / JSON / トランザクション / pgvector を“同居”できる Mastra 公式アダプタ:

    @mastra/pg 強み:SQL / JSONB / 整合性 / pgvector 論点:待機コスト・再開遅延(auto-pause) ・アップデート運用 import { PostgresStore, PgVector } from "@mastra/pg"; const memory = new Memory({ storage: new PostgresStore({ connectionString: process.env.DATABASE_URL! }), vector: new PgVector({ connectionString: process.env.DATABASE_URL! }), }); Round 2 - Aurora Serverless v2(PostgreSQL)
  11. 課題:Scale to Zero の現実(auto-pause) Aurora Serverless v2 は 0 ACU

    で auto-pause できるが… 再開にレイテンシ(例:十数秒オーダー) 長時間停止でさらに遅くなるケースも UX / SLO が厳しいと「0 ACUで止める」運用は採用しにくい Round 2 - Aurora Serverless v2(PostgreSQL)
  12. 課題:Reader/Writer の使い分け Aurora は Writer / Reader endpoint が分かれる。 @mastra/pg

    は基本「単一pool」なので、分けたい場合はラッパーで吸収。 class AuroraSplitStore implements MastraStorage { constructor(private writer: PostgresStore, private reader: PostgresStore) {} // Read 系 → reader getThread(args) { return this.reader.getThread(args); } listMessages(args) { return this.reader.listMessages(args); } // Write 系 → writer saveThread(args) { return this.writer.saveThread(args); } saveMessages(args) { return this.writer.saveMessages(args); } } Round 2 - Aurora Serverless v2(PostgreSQL)
  13. Round 2 結論:機能は揃うが、待機/運用コストと向き合う 1つのDBに寄せられる SQL / JSONB / 集計 /

    整合性 / pgvector サーバーレス運用の論点 auto-pause 再開遅延(SLOに影響) アップデート計画・検証が必要 スケールさせるなら Reader/Writer 分離の実装も発生 「表現力」を取ると「待機と運用」が付いてくる。これを減らせないか? → DSQL Round 2 - Aurora Serverless v2(PostgreSQL)
  14. DSQL を Mastra から使う:アダプタで吸収する 内部で AWS公式の @aws/aurora-dsql-node-postgres-connector を使用 IAM 認証、接続トークン生成を隠蔽。

    使用例: import { DSQLStore } from '@mastra/dsql'; const store = new DSQLStore({ id: 'my-dsql-store', host: 'abc123.dsql.us-east-1.on.aws', }); Round 3 - Aurora DSQL
  15. 踏んだポイント:DDL / スキーマ / JSON 非同期 DDL ストレージアダプタ内の初期化(インデックス作成)処理で「完了待ち」 「失敗時リト ライ」

    「並行実行の制御」が必要 ALTER TABLE ADD COLUMN はできるが、制約付き追加ができない NOT NULL / DEFAULT / CHECK を “追加と同時” に適用できない前提の設計が必要 JSON/JSONB を列型として持てない TEXT 保存して必要時に CAST SELECT * FROM threads WHERE (metadata::jsonb)->>'plan' = 'pro'; Round 3 - Aurora DSQL
  16. 踏んだポイント:サイズ上限 TEXT / bytea が おおよそ2MB 上限、行サイズにも上限 Tool 出力が大きいと S3

    オフロードが必要になる DynamoDB と同じ発想(DBは索引、本文はS3) PRを送っている @mastra/dsql はオフロード機能は未実装(改めて検討) Round 3 - Aurora DSQL
  17. 踏んだポイント:楽観的同時実行制御(OCC) 楽観ロックによる競合時に SQLSTATE 40001 (serialization error)で失敗する 対応:Exponential Backoff + Jitter

    で再試行 → 再試行ロジックはアプリ全体に撒かず ストレージアダプタに閉じ込める Round 3 - Aurora DSQL
  18. サーバーレスなベクターストアとして切り出す S3 上のベクタに対して検索(vector bucket / vector index) 大規模スケール 例:1 index

    あたり最大 20 億 vectors(以前は5,000万だったの40倍) など filterable / non-filterable metadata で絞り込み可能 DynamoDB / DSQL の “ベクタ検索を同居できない” を、別のサーバーレスサービスで補う 補足:Amazon S3 Vectors
  19. Mastra から使う:@mastra/s3vectors 使用例: import { S3Vectors } from "@mastra/s3vectors"; const

    vector = new S3Vectors({ vectorBucketName: process.env.S3_VECTORS_BUCKET!, clientConfig: { region: process.env.AWS_REGION! }, // 大きいテキストは filter に使わない(容量と制約対策) nonFilterableMetadataKeys: ["content"], }); const memory = new Memory({ vector }); 補足:Amazon S3 Vectors
  20. 課題:Semantic Recall は「単一 index 前提」 現状の Mastra 本体の実装だと、Semantic Recall のベクトルが「単一の

    index」に保存 される。 やりたいこと: テナント分離(セキュリティ) 大規模SaaSで index を分割して運用(シャーディング) 補足:Amazon S3 Vectors
  21. 回避策:RequestContext で Memory を差し替える Mastra は Request の文脈 を受け取り、Memory決定を関数にできる。 バケット単位での指定制限有り。

    (インデックス単位で選択する仕組みが欲しい) new Agent({ memory: ({ requestContext }) => { const tenantId = requestContext.get<string>("tenantId"); return new Memory({ vector: new S3Vectors({ vectorBucketName: `my-vector-bucket-${tenantId}`, // バケット単位 clientConfig: { region: process.env.AWS_REGION! }, }), }); }, }); 補足:Amazon S3 Vectors
  22. 比較マトリクス 観点 DDB + S3 Vectors Aurora v2 + pgvector

    DSQL + S3 Vectors 待機コスト ◎ △(0ACU/再開遅延) ◎ 初回応答 ◎ △(再開が課題) ◎ 検索/分析 △(設計必須) ◎(SQL/JSONB/集計) ◦(SQLだが制約あり) 実装コスト 高(回避策多め) 小(接続/運用が焦点) 小(@mastra/dsql) 運用コスト 低 中(バージョンアップ) 低 Vector検索 ◦(S3 Vectors補完) ◎(DB内完結) ◦(S3 Vectors補完) まとめ
  23. 要件別・構成パターン A. SQL で分析・運用しつつ、寄せ先を 1 つにまとめたい Aurora Serverless v2 +

    pgvector (検索、集計、JSON、ベクタを同居させやすい) B. 運用コストを抑え、SQLを使用したい Aurora DSQL + S3 Vectors 分散 DB 側の制約は アダプタに閉じ込める( @mastra/dsql がマージされたら楽) C. 運用コストを抑え、まず動かしたい DynamoDB + S3 Vectors も候補 ただし 回避策(サイズ制限/Offload/別ベクタ/分析/ページング) は自前 まとめ