> ## Documentation Index
> Fetch the complete documentation index at: https://agent.minimax.io/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# MCode Engineering Notes 05 | How Does the Agent Know the Current Time?

> The model has no clock. The most direct fix is to inject the time into the system prompt — but a time that changes every turn can trash the prefix cache. From the intuition through why the prefix matters to how MCode does it.

> [!NOTE]
>
> Start with one question: how does the agent know the current date and time?

Follow that question and you hit the prefix cache — we'll walk through it the way MiniMax Code (MCode for short) actually does, from the intuitive move to the final design.

The earlier notes have all been about subtracting from context. 01 managed subagents, 02 moved tool definitions out, 03 handled long history, 04 said don't make the agent sit and wait on a bash command until the prompt cache expires. Space, time, and the pause tax — all counted. This note cuts a different slice: **even when requests keep coming, put the time in the wrong place and the prefix cache still dies.**

![How does the agent know the current time](https://mintcdn.com/agent-en/81ZdFpgVPy1AzeJU/images/techblog/mcode-notes-05-prefix-cache/cover.png?fit=max\&auto=format\&n=81ZdFpgVPy1AzeJU\&q=85\&s=54db15cf3dc8702cc7c912df865e8cd2)

## The problem: the model has no clock

Once training is done, the model has no live clock. "Commits from the last week," "today's schedule," "was this file changed yesterday afternoon?" — every one of those judgments needs to know what "now" is.

Without the time, it defaults to living in the year its training data ended. So if you tell it — how do you tell it?

## The most direct move: inject the time into the system prompt

The most obvious answer: add one line to the system prompt (SP) — the current time, down to the second.

The reason is solid. One line, a few dozen tokens — next to the full system prompt and thousands of tokens of tool definitions, it looks negligible. Working directory, platform, and shell are already in the environment block; adding a `date` line feels natural.

A lot of harnesses take this path on the first try. We almost did — or used to think this way.

## How it breaks: time changes, the whole prefix misses

The catch: **time changes every turn**, sometimes every second.

The system prompt sits at the front of the request. Put time there, and every turn rewrites the start of the prefix. Tool definitions and history behind it, even if not a single byte moved, all miss — caches match on prefix; one byte changes at the front, and everything after is invalidated.

A public side note: someone noticed that Claude Code had, for a stretch, been stuffing a per-request field into the system prompt, and [a third-party provider's cache hit rate fell close to zero](https://x.com/stevencheng/status/2055922152562696197). The main thread isn't that someone else crashed — it's that **the intuitive path we would take ourselves** has the same structure: one volatile field, at the front of the prefix.

A `date` line that looks cheap, multiplied by turns and requests, and what's expensive is the whole prefix it breaks.

## So why does the prefix matter so much?

![Figure 1: What costs isn't the token count — it's position](https://mintcdn.com/agent-en/81ZdFpgVPy1AzeJU/images/techblog/mcode-notes-05-prefix-cache/fig1.png?fit=max\&auto=format\&n=81ZdFpgVPy1AzeJU\&q=85\&s=26b3ddddd8497373c89e823e1a7dab89)

When the last note talked about background tasks, we hit cache **lifetime**: wait too long in the foreground, the cache expires. This note is the other cut — cache **hits**: wrong place, and even back-to-back requests go back to full price.

One conclusion is enough here:

**Caches match on prefix. One byte changes at the front, and everything after is invalidated.**

So the same content can cost wildly different amounts depending on where it sits:

1. **Content at the very front that changes every time is the most expensive.** It keeps everything after it from hitting the cache. Time down to the second, if stuffed into the system prompt, invalidates the whole prefix every turn — system prompt, tool definitions, history, all recomputed with it.
2. **Content written into history and then left alone has limited impact.** What you write on turn 5 is already part of the prefix by turn 6. As long as it isn't rewritten, later turns keep hitting. The cost is mainly the first write, plus context growing turn by turn — exactly what 03 is about.
3. **Content attached only to the end of this request, never entering history, is never cached.** It doesn't break anyone else's cache, but every send is a full-price input.

Here's the most counterintuitive line in the note:

**A field of a few dozen tokens, in the wrong place, can cost more than thousands of tokens of tool definitions.**

However long the tool definitions are, as long as the bytes don't change each turn, they sit steadily in the cacheable prefix — almost "buy once, use at cache price after." Flip it around: one small field on the prefix that changes every turn sends that whole bargain back to full price in one shot.

A few plain rules fall out of that:

* **Put stable content first; put changing content later.** Current time doesn't go in the system prompt; it rides along with each user message.
* **Don't rewrite what's already in history.** If you need to adjust, only change future turns.
* **Precision that's good enough is enough.** Time down to the second is almost useless to the model, and it guarantees every copy differs from the last.

> [!TIP]
>
> **If you're building an agent harness:** tag every injected chunk with two attributes — "how often it changes" and "where it sits." Things that change fast and sit early get handled first. The prefix cache isn't a cost-saving easter egg; it's a first-class design constraint.

## A quick look: what's in one request

![Figure 2: In one "hi", what is the stable prefix](https://mintcdn.com/agent-en/81ZdFpgVPy1AzeJU/images/techblog/mcode-notes-05-prefix-cache/fig2.png?fit=max\&auto=format\&n=81ZdFpgVPy1AzeJU\&q=85\&s=879c920e5cfad3369227150dd1c8927b)

With the rules in hand, looking at what an MCode request actually looks like makes the next section clearer:

| Content | Where it sits | How often it changes |
| - | - | - |
| Core system prompt (identity, behavior rules) | Front of the request | Essentially fixed |
| Environment info (cwd, platform, shell, model, language) | Inside the system prompt | Fixed within a session |
| Skill catalog (a line or two per skill) | Inside the system prompt | Changes when skills are added/removed |
| Tool definitions (JSON Schema per tool) | The request's `tools` field | Essentially fixed |
| History | Middle | Append-only |
| Per-turn `<agent-context>` (identity, session ID, current time, …) | Start of each user message | A fresh copy every turn |
| System reminders | In the user message, or hung on the end of the request | Triggered by conditions |
| What you said this turn | Last | Changes every turn |

## How MCode does it now

![Figure 3: Same time field — where you put it decides whether the prefix lives](https://mintcdn.com/agent-en/81ZdFpgVPy1AzeJU/images/techblog/mcode-notes-05-prefix-cache/fig3.png?fit=max\&auto=format\&n=81ZdFpgVPy1AzeJU\&q=85\&s=d8c5c0d51f5c0e556946fd18a3e0db68)

Flip that intuitive path around, and you get what we do now.

**The `# Environment` block in the system prompt only holds things that stay put for a session.** Working directory, whether it's a git repo, platform, shell, OS, model, locale, region, data directory — these barely change inside one session, so they sit up front and stay in the cacheable prefix. There is no current time here. In the public code this is the `environment-prompt-composer` family of assembly logic.

**Current time goes into the `<agent-context>` at the start of each turn's user message.** Built by `buildSlimAgentContextBlock`. From turn 2 on it looks roughly like this (illustrative; field values are made up):

```
<agent-context>
  agent: MiniMax Code
  agentName: default
  SESSION ROLE: root
  YOUR SESSION ID: <session id>
  date: Fri Oct 09 2026 13:20 GMT+0800 (China Standard Time)
</agent-context>
```

By the previous section's taxonomy, that's type 2: written into history, then left alone. The time written on turn 5 is already part of the prefix by turn 6; as long as you don't rewrite it, later turns keep hitting. The model still gets "today" and "recently," without touching the system prompt every turn.

The same time field is a disaster at the front of the prefix and only a per-turn tail when it rides with the user message — figure 3 puts the two placements side by side.

Once placement is right, tighten along the same line:

* **Precision that's good enough.** [#459](https://github.com/MiniMax-AI/minimax-code/pull/459) changes `date` from second precision to minute precision (`formatReminderDate`). Timezone and offset stay; seconds change every turn and barely help the model. After placement is right, cut "must change every turn" precision that isn't needed.
* **Don't rewrite what's already in history.** To adjust, only change future turns. Bytes already written into `<agent-context>` stay put, so the prefix you've built up can stand.

> [!TIP]
>
> **If you're building an agent harness:** for anything that changes, ask first whether it belongs in the system prompt. If it does, you're trading the whole prefix for one convenient line. Move it first; then talk about precision.

## Looking back

![Figure 4: Five junctions on the same road](https://mintcdn.com/agent-en/81ZdFpgVPy1AzeJU/images/techblog/mcode-notes-05-prefix-cache/fig4.png?fit=max\&auto=format\&n=81ZdFpgVPy1AzeJU\&q=85\&s=776f360104f339b286241d27567f2dee)

Put the earlier notes side by side and they're junctions on the same road:

* 01: don't manage context by piling on subagents
* 02: load tool definitions on demand; don't stuff them all into every turn
* 03: compress long history when you should; put what matters into memory
* 04: don't make the model sit and wait — cut the "pause tax" — protecting cache **lifetime**
* This note: don't let one time field sink the prefix — protecting cache **hits**

03 said: the context window is a workbench, not a warehouse. This note wants to add: for the things you lay out on that workbench every day, **where they sit matters more than how much there is.**

How does the agent know the current time? The most direct move is to stuff it into the SP; the design that holds up is to let time ride with each turn's user message, and protect that whole stable prefix up front.

## A short self-check for people building agents

| Check | Ask yourself |
| - | - |
| Prefix awareness | Can you point to, in one request, what's the stable prefix and what changes every turn? |
| Necessity | For each piece, where does the model go wrong if you delete it? If you can't say, consider deleting first. |
| Position | Is current time (and other changing content) sitting in the system prompt? If so, move it into each turn's user message. |
| Precision | Does time need seconds? Higher precision makes it easier for every turn to differ. |
| Don't rewrite history | Have `<agent-context>` blocks or reminders already in history been rewritten on later turns? |
| Put-back path | On compaction, session resume, sub-agents — can cut information disappear entirely? Who puts it back? |
| Measure | Before and after a change, are you looking at cache hit rate, per-turn cost, *and* quality? Token count alone isn't enough. |

These changes are all in the [public MiniMax Code repo](https://github.com/MiniMax-AI/minimax-code). Come read the code, file issues, throw bricks.

> [!TIP]
>
> Curious what you've seen: how do you tell the agent the current time? Have you ever had a `date` line sink a whole prefix cache?
