DEV Community

Matchiffo Ynna
Matchiffo Ynna

Posted on

Negative Memory: Teaching AI Agents What Not To Do

Most agent memory is about success. We store the fix that worked, the query that returned the right rows, the prompt that produced a clean answer, and we retrieve it next time. That is useful, but it leaves out half of what an experienced engineer actually knows: the list of things that looked reasonable and went badly.

Ask a new on-call engineer to fix a stuck service and they may restart it. Ask a senior one and they will first check whether a restart on that service drops in-flight payments. The difference is not more positive knowledge. It is a memory of past failures. AI agents today mostly do not have that, so they repeat the same ineffective or dangerous steps: the rollback that corrupted a migration last month, the cache flush that took the site down, the "quick restart" that lost queued jobs.

Negative memory is the fix for this. The agent keeps a record of actions that failed or caused harm, and it reads that record before acting.

What a negative memory entry looks like

Keep it small and structured. An entry needs enough context to match future situations, and a clear statement of what went wrong.

{
  "action": "restart service payments-api",
  "context": "high latency, 5xx errors, during traffic peak",
  "outcome": "dropped in-flight transactions, 40 min recovery",
  "severity": "block",
  "source": "postmortem 2026-09-14",
  "expires": "2027-03-14"
}
Enter fullscreen mode Exit fullscreen mode

Two fields matter most. severity tells the agent whether this is a hard block (never do it without a human) or a soft warning (do it, but mention the risk). expires stops old lessons from outliving the systems they were about.

How the agent uses it

The loop is simple. Before the agent runs a tool or proposes a fix, it searches the negative memory for entries similar to the planned action and the current context. Matches are injected into the prompt as constraints, not as suggestions:

Do not perform these actions in this situation:
- restart payments-api during a traffic peak (dropped transactions, Sept 2026)
- roll back the orders schema (data loss, Aug 2026)
If one of these seems necessary, stop and ask a human.
Enter fullscreen mode Exit fullscreen mode

For block entries, do not rely on the prompt alone. Check the planned tool call in code and refuse it. Prompts are advice; code is enforcement.

Where the entries come from

You do not need a research project to start. Three sources cover most of it:

  1. Postmortems. Every incident review already lists what was tried and what made it worse. Turn those lines into entries.
  2. Failed tool calls. When the agent runs a command and the result is an error or a worse metric, log the action, the context and the result automatically.
  3. Human corrections. When an operator overrides the agent ("no, don't do that"), store the override with a short reason.

Pitfalls

  • Over-blocking. A failure in one environment is not a rule for all of them. Scope entries by service, environment and time.
  • Stale rules. Systems change. Use expiry dates and review entries that keep firing.
  • Vague entries. "Restarting is bad" is useless. "Restarting payments-api during peak drops transactions" is a rule the agent can match.
  • Secrets in logs. Failed commands often contain credentials. Strip them before storing.

Start today, with free tools

A SQLite table and a local embedding model are enough for a first version. Store entries as rows, embed action + context, and run a similarity search before each tool call. If embeddings feel like too much, keyword matching on service name and action type already catches most repeats.

The result is an agent that behaves less like a confident intern and more like someone who has been paged at 3 a.m. and remembers why.

Top comments (1)

Collapse
 
eqvero profile image
Eqvero •

A tricky failure mode with negative memory in production is schema drift over time. In financial data ingestion and SEC filing pipelines, an agent might flag a table parser error as an action failure and store an action like 'do not parse statement of cash flows with standard table extractor'. If that rule lacks an expiration date or schema version tag, it stays permanently blocked even after upstream fixes the table formatting.

Scoping each negative entry with a concrete expiration date and an environment hash keeps the guardrails practical. Another pattern that helps is running negative memory as an alert trigger rather than an outright blocker in non-destructive workflows. That lets the agent attempt the fallback pipeline while logging an anomaly for review.