DEV Community

Cover image for Cosmic as Agent Memory: Structured, Versioned, and Queryable
Tony Spiro
Tony Spiro

Posted on • Originally published at cosmicjs.com

Cosmic as Agent Memory: Structured, Versioned, and Queryable

AI agents get better the more they run. Every conversation turn, every task completed, every prompt refined adds to a growing body of context that shapes the next output. The compounding effect is real: an agent with 100 turns of memory and a versioned prompt history behaves meaningfully differently from one starting cold.

This post walks through using a structured, versioned, API-accessible store as the memory layer for AI agents, with TypeScript examples. Agent messages, system prompts, findings, and instructions are all stored as structured, versioned, API-accessible Objects. Each new turn adds to the record. Each prompt edit is tracked.

What Agent Memory Actually Needs

The compounding loop only works if the memory layer has the right properties. Most agent frameworks handle working memory well. The gap is episodic and semantic memory: what the agent learned, did, and produced across sessions.

Researchers at Elastic recently published a breakdown of agent memory tiers: working memory (in-context), episodic memory (past interactions), semantic memory (knowledge), and procedural memory (learned behaviors). Good persistent agent memory needs four properties:

  • Structured: queryable by type, status, date, or custom field, not just full-text search
  • Versioned: you need to know what the agent wrote at each point in time, not just the latest state
  • API-accessible: any model, any framework, any language should be able to read and write it
  • Human-reviewable: agents make mistakes; a human needs to inspect and correct outputs without touching a database

Objects as Agent Outputs

When an agent produces output, storing it as a structured Object gives you a queryable record with typed fields, a draft/published workflow so a human can review before promoting to production, a full audit trail of every change, REST API access from any runtime, and a dashboard UI where non-technical team members can inspect, edit, or approve agent outputs.

Here's a simple research agent that stores its findings as Cosmic Objects:

import { createBucketClient } from '@cosmicjs/sdk'

const cosmic = createBucketClient({
  bucketSlug: process.env.COSMIC_BUCKET_SLUG!,
  readKey: process.env.COSMIC_READ_KEY!,
  writeKey: process.env.COSMIC_WRITE_KEY!,
})

async function storeAgentFinding({
  topic,
  summary,
  sourceUrl,
  confidenceScore,
}: {
  topic: string
  summary: string
  sourceUrl: string
  confidenceScore: number
}) {
  const result = await cosmic.objects.insertOne({
    title: topic,
    type: 'agent-findings',
    status: 'draft', // human review before publishing
    metadata: {
      summary,
      source_url: sourceUrl,
      confidence_score: confidenceScore,
      reviewed: false,
    },
  })
  return result.object
}
Enter fullscreen mode Exit fullscreen mode

The output is immediately visible in the dashboard. A team member can review the summary, edit it, toggle reviewed to true, and publish, all without touching code.

Storing Prompts, Context, and Conversation Memory

Agent outputs are only part of the picture. The other half is what goes in to the agent: system prompts, conversation history, and session context.

System Prompts as Objects

Instead of hardcoding system prompts in your codebase, store them as Objects. This gives you version control for prompts (draft a new version, test it, publish when ready, roll back if behavior degrades), non-engineer editable wording without a deploy, and environment-aware prompts per environment with zero code changes.

// Fetch the active system prompt for an agent
const { object: promptObject } = await cosmic.objects
  .findOne({
    type: 'agent-prompts',
    slug: 'content-research-agent',
    status: 'published',
  })
  .props('title,metadata.prompt_text,metadata.version')

const systemPrompt = promptObject.metadata.prompt_text
Enter fullscreen mode Exit fullscreen mode

When you want to update the prompt, you edit it in the dashboard, save a new version, and publish. The agent picks it up on the next run with no deployment required.

Conversation Context and Message History

For agents that need to maintain state across sessions, store the conversation history as structured Objects:

async function storeMessage({
  sessionId,
  role,
  content,
  agentName,
}: {
  sessionId: string
  role: 'user' | 'assistant' | 'system'
  content: string
  agentName: string
}) {
  await cosmic.objects.insertOne({
    title: `${agentName} / ${sessionId} / ${role}`,
    type: 'agent-messages',
    status: 'published',
    metadata: {
      session_id: sessionId,
      role,
      content,
      agent_name: agentName,
    },
  })
}

// Retrieve full conversation context for a session
const { objects: messages } = await cosmic.objects
  .find({
    type: 'agent-messages',
    'metadata.session_id': sessionId,
  })
  .props('metadata.role,metadata.content,created_at')
  .sort('created_at')
Enter fullscreen mode Exit fullscreen mode

The agent can reconstruct its full conversation history on every run. The history is human-readable in the dashboard, editable when needed, and queryable across sessions.

Querying Agent Memory

The real power is in retrieval. Because each agent output is a structured Object with typed metafields, you can query across your entire agent history:

// Get all unreviewed findings from the last 7 days
const { objects } = await cosmic.objects
  .find({
    type: 'agent-findings',
    'metadata.reviewed': false,
  })
  .props('id,title,metadata,created_at')
  .sort('-created_at')
  .limit(50)

// Get high-confidence findings on a specific topic
const { objects: topFindings } = await cosmic.objects
  .find({
    type: 'agent-findings',
    'metadata.confidence_score': { $gte: 0.85 },
  })
  .props('id,title,metadata')
  .sort('-metadata.confidence_score')
Enter fullscreen mode Exit fullscreen mode

You are filtering by structured properties, sorting by custom scores, and scoping by review status. The agent's memory is queryable the same way any other content in your system is queryable.

Versioning: Know What the Agent Said When

A full revision history for every Object matters for auditability. If an agent's output informed a business decision, you need to know exactly what it said at the time of that decision, not just the current state. The same applies to prompts. When a prompt change shifts agent behavior, you can trace exactly which version was active and when. That's the kind of audit trail that matters as agents take on more consequential tasks.

Using the MCP Server

Cosmic ships a native MCP Server, which means any agent running in Claude, Cursor, Windsurf, or any MCP-compatible runtime can read and write Objects directly, with no custom API wrapper needed. The MCP Server exposes all 18 Cosmic tools to your agent: create objects, update objects, query by type, filter by metadata, manage media, and more.

Schema Design for Agent Context and Memory

The key to making this work well is defining clean Object types upfront. Three schemas cover most agent context and memory use cases:

agent-findings: summary (textarea), source_url (text), confidence_score (number 0-1), agent_name (text), session_id (text), reviewed (switch), tags (references)

agent-messages: role (select: user/assistant/system), content (textarea), agent_name (text), session_id (text)

agent-prompts: prompt_text (textarea), version (number), notes (textarea)

What You Get Out of the Box

You could build this with Postgres and a custom schema. A headless CMS includes a dashboard UI for every agent output with no custom admin to build, built-in revision history with no extra tables, a REST API ready to consume from any runtime, a draft/published workflow, media handling, and model agnosticism across any framework or language.

Read the full post on the Cosmic blog for the complete walkthrough, including the copy-paste schema setup and getting-started steps.

Top comments (2)

Collapse
 
hayrullahkar profile image
Hayrullah Kar

This is a refreshing take on the agent memory bottleneck. Everyone jumps straight to vector DBs for semantic retrieval, but they completely neglect the operational reality of running agents in production: debugging, human-in-the-loop validation, and prompt regression.

Treating a headless CMS/structured API store as the episodic memory layer is brilliant for one major reason: human observability. When an agent goes off the rails, a non-technical product manager can literally log into a dashboard, fix the corrupted memory object or roll back a borked system prompt version, and save the session without a single database migration.

My only slight critique is on the latency side for real-time conversation state. For high-frequency, multi-turn chat loops, hitting a full API endpoint to append every single raw message string can introduce noticeable network lag compared to local Redis states. But for episodic findings, system prompts, and structured tool outputs? This architecture is incredibly clean.

The native MCP server integration makes it an absolute no-brainer for Cursor/Claude stacks. Love the blueprint!

Collapse
 
tonyspiro profile image
Tony Spiro

Thank you Hayrullah! It's been transformative for us at Cosmic, hoping others get on the bandwagon and use their CMS to store and audit agent context.