Kogen

Notes

Why I fork my ChatGPT conversations

I’ve organized a lot of projects in ChatGPT, each with a corresponding folder in iCloud. The folders have a clear starting point and links to the project knowledge and workflows. An agent in a new conversation can find its way around, read what it needs and get on with the task after I explain it in a sentence or a paragraph.

I have a lot of work that follows the same procedures. I don’t want to explain those procedures every time, so I’ve put that explanation in the files. I can ask about a feature, an issue or another recurring task without first walking the agent through how we do everything.

That solves a lot of repetition for me. The agent still has to do the reading in each new conversation, though, and that uses tokens.

My usage doesn’t drain as quickly as it seems to for some of the people I see on Twitter. I try to use an appropriate model for the task, which I wrote about in You don’t need Astra. But I’m always looking for ways to reduce the cost.

In one Kogen comparison on 25 October, cached input reached 89.5% for Build and 83.8% for Review, up from 16.3% and 6.5%. The estimated list-price cost was 67% lower, with the same correctness results. That came from improving cache handling in Kogen’s own requests. I wondered whether I could get a similar benefit in my ChatGPT conversations.

The cache announcement

Tibo announced persistent caching for signed-in Codex and Work with “we keep cache forever”. He said returning to an old conversation after a gap would hit the cache without an idle-time penalty.

Day 16/ You can now cache for 12h in the API and for logged in users across Codex & Work we keep cache forever and you don’t have any penalty for coming back to an old conversation or resuming after a few hours and are now guaranteed to hit the cache.

OpenAI Developers
OpenAI Developers
@OpenAIDevs

You can now choose 12-hour prompt caching in the API. Persistent agents, like dots, reuse context throughout the day. You can keep shared instructions, tools, and context cached longer and pay the lower cached-input rate, even when requests are hours apart.

That was the reason I started investigating this. If a conversation had already read the project files and worked through the common setup, I wanted to keep using that preparation. Forking looked like a way to do that while giving each task its own conversation. I didn’t realize then that forking and cache reuse were different things. More on that later.

A base for feature work

I started with a project conversation that had read the general knowledge. From that I prepared a more specific conversation for feature discussions, with the relevant workflow and tool instructions. Then I forked individual feature tasks from that checkpoint.

These screenshots are from the ChatGPT desktop app for macOS. The first conversation is the feature base; the second is a task about Kogen onboarding:

ChatGPT for macOS sidebar entry titled Base · Kogen features · v1.A task fork in ChatGPT for macOS titled Feature · Kogen onboarding.
The base contains the shared preparation. The onboarding question gets its own conversation.

The important part is that the base actually reads the files. A list of paths and a promise to read them later won’t put their contents into the inherited history. I ask the agent to read the sources, finish any truncated output, check its understanding and stop before starting a real task.

The task fork can then use what is already there. It adds my new request and reads the current information needed to answer it. It doesn’t need another copy of an unchanged guide that the base has already read.

Stable project context comes first, followed by feature guidance. Separate tasks share that beginning and append their own new input.
The tasks share a beginning, then diverge. Open the diagram at full size to zoom in.

I keep the tasks out of the base so the next feature doesn’t inherit an unrelated investigation. I also keep different kinds of work in separate bases. That follows the argument in I don’t want AGENTS.md: agents need the instructions for their particular jobs. The common project knowledge can come first, with the workflow-specific guidance added in its branch.

What I ended up reusing

Cache was what led me here. The part I can use directly is the prepared conversation itself: the messages, generated answers and results of reading the files. Forking carries that history forward. It doesn’t generate those old answers again or make the agent repeat every operation that produced them.

That can remove work before the task starts: another round of file reads, another explanation of the workflow, another response saying the agent has understood it. The next task can begin with its question.

Provider caching can help with the cost of using the inherited context. When the model answers the next question, the relevant history is still input. If its beginning matches eligible cached input, that part can receive the cached rate. The new answer and reasoning are new output.

So I’m reusing the completed preparation, and potentially its cached processing too. Copying the conversation history and getting a provider cache hit are separate things to check.

OpenAI’s Standard credit rates, checked on 30 October, show why the cached part is worth caring about:

Standard speed · credits per million input tokens
ModelInputCached input
GPT-6.1 Sol502.5
GPT-6.1 Terra251.25

For Sol and Terra, eligible cached input costs 95% less at those rates. With Sol, 100,000 ordinary input tokens cost 5 credits; 100,000 cached input tokens cost 0.25. The preparation, new task input and generated output still count.

Tibo’s later announcement says changing reasoning effort during a Codex or Work conversation no longer invalidates cache. Changing models is a different operation; that announcement doesn’t promise cache reuse across models.

What the counters showed

I checked the original records from a small signed-in Codex test. We sent the same new question to two forks of one prepared checkpoint:

Tokens for each new response; inherited cumulative totals excluded
ResponseInputCached partNew output
Fork A11,369016
Fork B11,36911,13616

Both replies generated 16 new output tokens. One reported 11,136 of its 11,369 input tokens as cached; the other reported zero cached input. The table counts only the new responses, excluding the parent’s old usage totals. Creating the forks had copied the earlier answers, not generated them again.

That confirms the distinction I needed: I can reuse the conversation’s preparation without generating it again, while cache reuse on the next response is a separate observation. The zero in that table is a cached-input count, not zero input, zero output or a measured account deduction. The records don’t explain the difference between the two forks.

A large base can also carry more material than the task needs. I don’t want a high cache percentage to hide the cost of sending a bloated context. A fair comparison needs the full cost of an acceptable result, including preparation and retries, against a fresh conversation given the relevant information.

When a guide changes, I refresh the base. Existing forks don’t acquire later corrections to their parent. And the onboarding task still needs the current installation instructions; inherited preparation doesn’t replace reading changed code or records.

Claude Code also supports forking a resumed session with claude --resume <session-id> --fork-session. The same organization is possible there, but I haven’t looked into its cache and billing behavior. I switched from the Claude desktop app to ChatGPT months ago. For now, the useful change in my own setup is that each recurring task can start after the common reading has already been done.

← All notes