TL;DR
- A base session is an LLM agent session pre-loaded with your project context, saved by
session_id, and resumed as many times as you need. - It works across Claude Code, Codex CLI, and Gemini CLI — same file, same prompt, any agent.
- Separate behavior (agent-specific rule files) from knowledge (shared project context). That separation is the key to scaling multi-agent workflows.
The Problem: Repeating Yourself Three Times
I use three coding agents daily — Claude Code, Codex CLI, and Gemini CLI. At some point I noticed a pattern: I was giving the same explanation over and over.
"This project uses an append-only database. The design docs are in docs/design/. The build system works like this…"
Every new task, every agent, the same preamble. My design docs are around 4,000 lines (~50K tokens). Reading them in takes about two minutes per agent. Three agents means six minutes of context loading before any real work starts — and that's just for one task.
On top of that, each agent has its own config format. CLAUDE.md is Claude-only, .cursorrules is Cursor-only, and so on. Maintaining the same project knowledge across different formats is tedious and error-prone.
I needed a way to load context once and reuse it everywhere.
What Is a Base Session?
A base session is simple: you feed your project context to an agent, record the session_id, and resume from that session whenever you need to work.
┌──────────────────────────────────────┐
│ Phase 1: Build the Base Session │
│ │
│ "Read ctx_full.md and understand │
│ this project." │
│ → Agent loads context │
│ → You record the session_id │
└──────────────┬───────────────────────┘
│ session_id
▼
┌──────────────────────────────────────┐
│ Phase 2–N: Work (as many times │
│ as you need) │
│ │
│ Resume session by session_id │
│ "Implement the delete feature" │
│ "Write tests for the sync module" │
│ "Review this PR" │
│ → Agent already understands the │
│ project │
└──────────────────────────────────────┘
You build once. You resume many times. The agent starts every task already understanding your project.
Why It Helps
1. You Stop Paying the Setup Tax
Without a base session, every task begins with context loading:
Task A → load design docs (~2 min, 50K input tokens) → work
Task B → load design docs (~2 min, 50K input tokens) → work
Task C → load design docs (~2 min, 50K input tokens) → work
─────────────────────────────────────────────
Total: ~6 min loading, 150K input tokens
With a base session:
Build base session (~2 min, 50K input tokens) → record session_id
Task A → resume session (seconds, cache hit) → work
Task B → resume session (seconds, cache hit) → work
Task C → resume session (seconds, cache hit) → work
─────────────────────────────────────────────
Total: ~2 min loading, 50K tokens + cached reads
When you resume a session, the prior context can benefit from the provider's prompt cache. For example, with the Anthropic API, cached input costs 1/10 of fresh input — up to a 90% reduction. Other providers have their own caching mechanisms with varying savings. Either way, the more tasks you run from the same base, the more the savings compound.
base_session ─┬─ implementation task A
├─ implementation task B
└─ review task C
2. One Context File, Any Agent
Instead of maintaining separate config files for each agent (e.g. CLAUDE.md for Claude, .cursorrules for Cursor), you write one plain Markdown file and feed it to any agent:
ctx_full.md ──→ Claude: "Read ctx_full.md" → session_id
──→ Codex: "Read ctx_full.md" → session_id
──→ Gemini: "Read ctx_full.md" → session_id
Same file. Same instruction. No format conversion.
3. Behavior vs. Knowledge — A Clean Separation
This doesn't replace agent-specific config files. It complements them. The key insight is that they serve different roles:
| Agent-specific config (CLAUDE.md, etc.) | Base session | |
|---|---|---|
| Role | Behavior — rules, style, conventions | Knowledge — design, structure, context |
| Scope | One specific agent | Any agent |
| Updated when | Project conventions change | Design docs change / new task cycle |
| Stored as | File in the repo | Session (referenced by session_id) |
| Example | "Use conventional commits" | "This DB is append-only with tombstone deletes…" |
Rules go in config files. Knowledge goes in base sessions. When you switch agents, the rules change but the knowledge stays the same.
4. It Fits Emerging Agent-in-Agent Workflows
A pattern that's becoming more realistic is an orchestrator agent spawning child agents for parallel implementation, review, and testing. Each child needs the project context:
Orchestrator
├─ Agent A (implement) ← needs project context
├─ Agent B (review) ← needs the same context
└─ Agent C (test) ← needs the same context
Without base sessions, that's three full context loads every time. If you pre-build a base session per agent, each child can resume from its own session_id and start working immediately. The initial construction cost pays for itself once you start running the same agents repeatedly.
How to Build One
Step 1: Prepare your context file
Gather the project knowledge you want every agent to have. Plain Markdown works best — it's readable by any agent and easy to maintain.
# Concatenate design docs
cat docs/design/*.md > ctx_full.md
# Or use a tool to generate a project summary
# (whatever fits your workflow)
Tip: Keep it focused. Don't dump your entire codebase. Include design decisions, data models, key APIs, and conventions. In my experience, a well-curated context file works better than a massive one — agents lose signal in noise.
Step 2: Load context and record the session
Feed the context file to each agent you use:
Claude Code:
claude --output-format stream-json \
-p "Read ctx_full.md and understand this project's architecture."
# Extract session_id from JSON output
Codex CLI:
codex exec --full-auto --json \
"Read ctx_full.md and understand this project's architecture."
# Extract session_id from JSON output
Gemini CLI:
gemini --output-format json \
"Read ctx_full.md and understand this project's architecture."
# Extract session_id from JSON output
Note: CLI option names vary by version. Check
--helpfor your installed version.
Step 3: Resume and work
Use the recorded session_id to pick up where you left off. The agent already knows your project.
Interactive:
# Claude (--fork-session keeps the base session clean)
claude -r <session_id> --fork-session
# Codex
codex resume <session_id>
# Gemini
gemini -r <session_id>
Non-interactive (scripting / automation):
# Claude (--fork-session keeps the base session clean)
claude -r <session_id> --fork-session \
--output-format stream-json \
-p "Implement the delete feature."
# Codex
codex exec resume <session_id> \
--full-auto --json \
"Implement the delete feature."
# Gemini
gemini -r <session_id> --output-format json \
"Implement the delete feature."
The --fork-session flag (Claude) is worth highlighting: it branches from the base session instead of appending to it, so your base stays clean for the next task. Other agents may handle session branching differently — check their docs for equivalent options.
You: Implement the delete feature.
Agent: Based on the design docs, this uses a physical delete
plus tombstone hybrid. The raw_deletions table...
(starts working with full project understanding)
Gotchas
| Agent | Session lifetime | Watch out for | Mitigation |
|---|---|---|---|
| Claude | Shorter | Context window fills up during long tasks | Rebuild the session when it gets too long. Keep the base session itself lean. |
| Codex | Longer | Sessions can expire after extended inactivity | Rebuild when expired. Including a date in the session_id you record (e.g. base-2026-03-10) makes it easy to tell when it's stale. |
| Gemini | Longer | May serve cached (stale) file contents | Explicitly instruct the agent to re-read the file if you've updated it. |
Common mistakes:
- Stale context — You update the design docs but forget to rebuild the base session. The agent works from outdated knowledge.
- Polluted sessions — You keep working directly in the base session instead of forking. The next resume inherits unrelated task artifacts.
- Context overload — You try to load everything. The agent's performance degrades. Curate what matters.
(Gotchas observed as of March 2026. Agent capabilities evolve quickly.)
Wrapping Up
- A base session loads project context once and lets you resume by
session_idas many times as needed. - It's reusable: one load, many resumes. Prompt caching can reduce cost on each reuse.
- It's agent-agnostic: the same Markdown file and the same prompt work for Claude, Codex, and Gemini.
- Rules live in config files. Knowledge lives in base sessions. This separation is what makes multi-agent workflows manageable.
- In emerging Agent-in-Agent workflows, pre-built base sessions let child agents skip the context-loading bottleneck and start working immediately.
If you're juggling multiple AI coding agents and tired of repeating yourself, try building a base session. It's a small workflow change that compounds over time.
To automate this workflow, I built ai-cli-mcp — an MCP server that lets you operate Claude, Codex, and Gemini through a single interface: run(model, prompt, session_id) to start or resume any agent, and wait(pids) to collect results from multiple agents in parallel. Handy for scripting base session construction or Agent-in-Agent orchestration.
Top comments (2)
the separation between behavior and knowledge is a clean idea, but one thing to watch out for: session caching behavior varies a lot across providers. anthropic's cache has a 5-min TTL so if you're not hitting the session frequently enough you're just paying full price again. would be worth tracking actual cache hit rates in practice to see if the savings hold up across a real workday.
Some comments may only be visible to logged-in visitors. Sign in to view all comments.