Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/perf-system-prompt-cache.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@moonshot-ai/kimi-code": patch
---

Replace the per-session timestamp in the default system prompt with a static time-lookup reminder. The timestamp changed on every new session, breaking DeepSeek's byte-prefix cache from that point onward — including the ~16.8k-token tools definition — so every new session's first LLM call missed the cache. First-turn cache-miss input drops from ~19.5k tokens to ~88 tokens (99.6% cache hit measured on the built artifact). The static `## Date and Time` section keeps the instruction to fetch the real current time from the environment (e.g. via the `date` command) when it matters, without the cache-breaking value.
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ The operating environment is not in a sandbox. Any actions you do will immediate

## Date and Time

The current date and time in ISO format is `${now}`. This was captured when the session started and does not update as the session continues, so in a long or resumed session it may be hours or days stale. Treat it only as a rough reference; whenever the real current time matters (web-result freshness, age or expiry checks, anything time-sensitive), get it fresh from the environmentfor example by running `date` if you have a shell tool — instead of trusting this value.
The current time is not embedded in this prompt. Whenever the real current time matters web-result freshness, age or expiry checks, anything time-sensitiveget it fresh from the environment, for example by running `date` if you have a shell tool.

## Working Directory

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve time lookup guidance without the timestamp

For time-sensitive requests, deleting this whole section removes more than the dynamic ISO value: it also removes the only default-prompt instruction that the agent must refresh the real time from the environment. I checked the remaining default prompt and the only date mention left is the Bash tool's command list, so cases like expiry/age checks or “what is today?” can be handled from model priors or stale context instead of querying the host. Keep a static, cache-friendly reminder to check the current time when it matters, and mirror it in the legacy prompt too.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 61389c6ab — kept ## Date and Time as a static reminder ("get it fresh from the environment, e.g. via the date command") and mirrored it in the legacy template too. No per-session value remains, so byte-prefix caching is unaffected. The added tests assert the rendered prompt is byte-identical across different now values.


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,21 @@ describe('renderSystemPrompt', () => {
);
});

it('keeps a static time reminder without a per-session timestamp', () => {
const nowA = '2026-08-02T10:00:00.000Z';
const nowB = '2026-08-03T10:00:00.000Z';
const promptA = renderSystemPrompt('', { now: nowA }, { skillActive: true });
const promptB = renderSystemPrompt('', { now: nowB }, { skillActive: true });

// Byte-identical across sessions — the property the prefix cache depends on.
expect(promptA).toBe(promptB);
// The dynamic value must not leak into the rendered prompt...
expect(promptA).not.toContain(nowA);
// ...but the static time-lookup guidance stays.
expect(promptA).toContain('## Date and Time');
expect(promptA).toContain('get it fresh from the environment');
});

it('renders the builtin template with no leftover placeholders', () => {
// Every placeholder in the builtin template must be bound in the variable
// table — an unbound one would stay verbatim in the output.
Expand Down
2 changes: 1 addition & 1 deletion packages/agent-core/src/profile/default/system.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ The operating environment is not in a sandbox. Any actions you do will immediate

## Date and Time

The current date and time in ISO format is `{{ KIMI_NOW }}`. This was captured when the session started and does not update as the session continues, so in a long or resumed session it may be hours or days stale. Treat it only as a rough reference; whenever the real current time matters (web-result freshness, age or expiry checks, anything time-sensitive), get it fresh from the environmentfor example by running `date` if you have a shell tool — instead of trusting this value.
The current time is not embedded in this prompt. Whenever the real current time matters web-result freshness, age or expiry checks, anything time-sensitiveget it fresh from the environment, for example by running `date` if you have a shell tool.

## Working Directory

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,14 @@ describe('default agent profiles', () => {
expect(prompt).toContain('/workspace');
});

it('keeps a static time reminder without the dynamic timestamp', () => {
const prompt = DEFAULT_AGENT_PROFILES['agent']?.systemPrompt(promptContext) ?? '';

expect(prompt).not.toContain(promptContext.now);
expect(prompt).toContain('## Date and Time');
expect(prompt).toContain('get it fresh from the environment');
});

it('keeps static instructions before dynamic prompt context', () => {
const prompt = DEFAULT_AGENT_PROFILES['agent']?.systemPrompt(promptContext) ?? '';

Expand Down