Observation Grain

What is an Observation grain?

An Observation grain captures a perception from a cognitive observer — an LLM, sensor, monitoring agent, or any system that watches and reports on its environment. Observations are a core grain type in the context database for building multi-agent perception pipelines with tracked provenance.

Observations differ from Events in that they always identify who is observing and carry structured metadata about the observation mode, scope, and model. This makes them the input layer for AI agent memory systems where multiple agents perceive the same environment and need to reconcile their views. The autonomous memory engine uses Observations as the foundation for consensus building — when multiple observers reach the same conclusion, their observations can be promoted to a Consensus grain.

The text representation used for embedding and BM25 indexing is the concatenation of observer_id, observer_type, subject, and object: "agent-7 llm user-sentiment positive". Fields like sync_group and frame_id enable grouping related observations across observers and temporal windows without affecting the text index.

FieldTypeRequiredDescription
contentstringyesFree-text description of the observation (stored in object internally)
observer_idstringnoIdentifier of the observer (defaults to "unknown" if omitted)
observer_typestringnoCategory of observer (defaults to "agent" if omitted; e.g., "llm", "sensor", "human")
subjectstringnoWhat is being observed
objectstringnoTarget or context of the observation (overrides content for storage if both provided)
observer_modelstringnoModel or version producing the observation (e.g., "gpt-4o")
frame_idstringnoTemporal frame grouping related observations
sync_groupstringnoGroup ID for synchronizing multi-observer perceptions
observation_modestringno"realtime", "batch", or "streaming"
observation_scopestringno"private", "shared", or "public"
compression_ratiofloatnoHow much the observation was compressed from raw input

Plus all common fields (confidence, tags, namespace, etc.).

How do I create an Observation?

Pass content through the /batch-add endpoint with grain_type: "observation". Only content is required; observer_id defaults to "unknown" and observer_type defaults to "agent" when omitted. Provide observer_id and observer_type explicitly for multi-agent pipelines where observer identity matters.

Set observation_scope to control visibility: "private" for agent-internal perceptions that only the originating agent should recall, "shared" for team-visible observations that peer agents can query, and "public" for cross-system observations available to any consumer. Use observer_model to record which LLM or sensor version produced the perception, which helps when debugging divergent observations from different model versions.

The confidence common field is particularly important for Observations. An LLM-generated observation about user sentiment might carry confidence: 0.7, while a sensor reading might carry confidence: 0.99. Downstream consumers (Reasoning, Consensus) use these scores to weight inputs appropriately.

import areev

db = areev.open("./data")
h = db.add("observation", {
    "content": "user sentiment is positive",
    "observer_id": "agent-7",
    "observer_type": "llm",
    "subject": "user-sentiment",
    "observer_model": "gpt-4o",
    "observation_mode": "realtime",
    "observation_scope": "shared",
    "confidence": 0.85
})
POST /api/memories/default/batch-add
Content-Type: application/json

{
  "grains": [
    {
      "grain_type": "observation",
      "fields": {
        "content": "user sentiment is positive",
        "observer_id": "agent-7",
        "observer_type": "llm",
        "subject": "user-sentiment",
        "observer_model": "gpt-4o",
        "observation_mode": "realtime",
        "observation_scope": "shared"
      }
    }
  ]
}
areev add observation content="user sentiment is positive" observer_id=agent-7 observer_type=llm subject=user-sentiment

How do I build multi-observer perception pipelines?

Use sync_group to link observations from multiple agents watching the same thing, and frame_id to group observations within a temporal window. This lets you query all perceptions of a given event across observers with a single filter.

When three agents observe the same customer interaction, assign them the same sync_group value. Each agent writes its own Observation grain with its independent subject, object, and confidence. To retrieve the full picture, query by sync_group with grain_type: "observation". If the agents agree, promote the result to a Consensus grain with related_to links back to the source observations.

The frame_id field groups observations within a time window (e.g., “frame-42” for all perceptions during a 30-second interaction). Combined with sync_group, this creates a two-dimensional index: which observers, during which time frame. This structure supports replay and analysis of multi-agent perception without requiring agents to coordinate in real time.

for agent_id in ["agent-1", "agent-2", "agent-3"]:
    db.add("observation", {
        "content": "customer intent is purchase",
        "observer_id": agent_id,
        "observer_type": "llm",
        "subject": "customer-intent",
        "sync_group": "sync-2026-03-09-001",
        "frame_id": "frame-42",
        "observation_scope": "shared"
    })

results = db.recall(query="sync-2026-03-09-001", grain_type="observation")
POST /api/memories/default/batch-add
Content-Type: application/json

{
  "grains": [
    {
      "grain_type": "observation",
      "fields": {
        "content": "customer intent is purchase",
        "observer_id": "agent-1",
        "observer_type": "llm",
        "subject": "customer-intent",
        "sync_group": "sync-2026-03-09-001",
        "observation_scope": "shared"
      }
    },
    {
      "grain_type": "observation",
      "fields": {
        "content": "customer intent is browsing",
        "observer_id": "agent-2",
        "observer_type": "llm",
        "subject": "customer-intent",
        "sync_group": "sync-2026-03-09-001",
        "observation_scope": "shared"
      }
    }
  ]
}

When should I use Observation vs. Event?

Use Observation when you need to record who perceived something, through which model, and with what confidence. Use Event for “this happened” records where the observer’s identity is not important.

Observations are the structured perception layer for multi-agent systems. They carry provenance (who saw it), methodology (which model, what mode), and scope (who can see this observation). Events are the general-purpose temporal log for everything else — messages, system notifications, user behavior.

If you find yourself adding observer metadata to an Event’s content field as unstructured text, switch to an Observation grain. The structured fields enable filtering by observer, model, and scope that would require fragile text parsing on Events.

  • Grain Types: Overview of all 10 OMS grain types and shared fields
  • Event: For timestamped occurrences without observer metadata
  • Consensus: For agreed-upon conclusions from multiple observations
  • Belief: For knowledge claims that may originate from observations