home/blog/Fix LLM drift: a URL your ChatGPT or Claude keeps re-reading

Fix LLM drift: a URL your ChatGPT or Claude keeps re-reading

Here is the pain. You open ChatGPT or Claude, paste a long brief, get a first draft. You ask for a tweak. Good. You ask for another tweak. Mostly good, but it contradicts something from turn one. By the fifth turn the model is reasoning from a half-remembered version of what you sent, you are re-pasting the original, and the conversation feels like it is slowly going stale.

This is not a model bug. The model is doing its best with what it has, which is a context window full of edits, mid-conversation patches, and your own clarifications. Its picture of "the current draft" is fuzzy, and every turn it gets a little fuzzier.

We shipped a fix. Every SyncodeLive session is fetchable as JSON, and there is a button in the editor that copies a prompt telling the LLM to re-fetch that JSON before every turn. The model stops drifting because it stops guessing. The current state is at a URL it can read.

It works for code, but it works just as well for a prompt, a PRD, a resume, a cold email, a blog post, or any other content you are iterating on with an LLM.

How the loop runs

  1. Open a session at syncodelive.com. Paste whatever you are working on: code, a draft prompt, a document.
  2. Click ✨ brainstorm with your LLM in the bottom-left of the editor.
  3. A pre-written prompt is copied to your clipboard.
  4. Paste it into ChatGPT, Claude, Gemini, Perplexity, or any LLM that can fetch URLs.
  5. The LLM fetches the session JSON, summarises the current state in one paragraph, and asks what you want help with.
  6. You edit in the SyncodeLive editor. The next time you ask, the LLM re-fetches and sees what changed.

That is the whole loop. No re-pasting. No "remember I said earlier". The current truth is at the URL.

What the prompt actually says

The exact text on your clipboard, no marketing version:

Here's the deal: in a normal chat, I give you context, we iterate 3-4 turns,
and you start drifting, forgetting my original brief, contradicting earlier
replies, reasoning from a half-remembered version of my document. I waste
turns re-pasting the same thing.

We're going to fix that. My live document is at this URL and stays current
as I edit:

  https://syncodelive.com/x7k2mq.json   ← fetch this
  https://syncodelive.com/x7k2mq        ← human-readable editor

How we work (please follow):
1. BEFORE you answer ANYTHING about my document, fetch the JSON URL. Read
   what I actually have RIGHT NOW. Do not rely on what I pasted earlier in
   this chat, that is stale.
2. Re-fetch on EVERY turn. I am editing in real time; the file may have
   changed since your last reply.
3. Reason from the freshly-fetched content as the single source of truth.
   If your previous reply assumed something the current version contradicts,
   just say so and update, no need to apologize.
4. When you suggest changes, quote the exact filename and line numbers so I
   can apply them directly.
5. If the fetch returns 404 or 410, tell me, my session may have expired
   and we need a fresh one.

The loop we want:
  → you fetch and summarise the current state in one paragraph
  → you point out the ONE most important thing to change next
  → I edit in the editor
  → you re-fetch on the next turn, see my changes, react
  → repeat until done

No giant rewrites, no scope-creep beyond what I asked. Surgical.

The prompt also adapts the noun. If your session is a .prompt file the LLM is told you are iterating on a prompt. If it is a code file, on code. If it is markdown or a document, on a document. The model's mental picture of what you are doing matches reality from turn one.

The propose-edit loop

This is the part I am most excited about. The LLM does not just describe a change. It can propose the change. You see a diff card in your editor and approve or reject with one click.

The clipboard prompt includes an appendix that teaches the LLM how to POST a proposed edit:

POST https://syncodelive.com/api/sessions/x7k2mq/propose
body: {
  "from":    "ChatGPT",
  "message": "tightened the closing paragraph",
  "files":   [ { "id": "f_default", "name": "draft.md",
                 "language": "markdown",
                 "code": "<full new file contents>" } ]
}

When the LLM POSTs, a card slides up from the bottom of your editor: who proposed it, a one-line summary of what they changed, and a per-file unified diff. Two buttons: Approve or Reject. If you Approve, the edit lands in the file and everyone in the session sees it instantly. If you Reject, it vanishes.

The human is always the gate. The LLM never edits anything you did not explicitly approve. This is the same model Gemini uses for "Help me write" in Gmail, applied to any session content.

Six iteration patterns where this is most useful

We ship six templates in the editor's "start with a template" menu. Each one is a battle-tested system prompt that uses the live-fetch loop:

All six are tuned for the same workflow: the LLM treats the role and constraints as stable across re-fetches, while you mutate the actual content in the editor.

What the JSON endpoint returns

If you want to look at the raw shape, hit any session URL with .json appended:

GET https://syncodelive.com/x7k2mq.json
{
  "shortId": "x7k2mq",
  "url": "https://syncodelive.com/x7k2mq",
  "language": "markdown",
  "files": [
    { "id": "f_default", "name": "draft.md", "language": "markdown", "code": "..." }
  ],
  "readOnly": false,
  "lastEditAt": "2026-06-02T09:14:22Z",
  "createdAt": "2026-06-02T09:00:18Z",
  "fetchedAt": "2026-06-02T09:14:25Z"
}

CORS-open. No auth. No rate limit. No cache. The content is the live editor state, pulled from the session's edge process at fetch time, not a stale database row. Sessions expire 48 hours after the last edit; an expired session returns 410 so the AI can tell you.

Why we let any agent hit it

The endpoint is wide open on purpose. Any LLM, any agent, any tool that can make an HTTP GET can read your session JSON, and any tool that can make a POST can propose an edit. We document both the read URL and the propose URL in our llms.txt so models that read llms.txt at crawl time learn the pattern.

The trade is that any content you write in a public session is, in principle, readable by anyone who can guess a six-character ID. There are 36^6 = 2.2 billion combinations, so guessing is not practical, but the rule still stands: do not paste secrets.

What this does not solve

Honest about the gaps:

That last one matters less every month. Every major chat product can fetch now.

Why a URL is the right shape

Pasting content into a chat box is a relic of a moment when LLMs could not reach out into the world. They can now. The right format for live work with an AI is a URL the AI keeps reading, not a snapshot the human keeps repasting.

That is the shape SyncodeLive is built around. The session URL is the source of truth. Your editor renders it. Your teammate's editor renders it. Your LLM fetches it. Your LLM proposes back to it. Everyone, human and machine, is looking at the same thing at the same moment, with no copies and no drift.

Open a session, paste anything you are stuck iterating on, hit ✨ brainstorm with your LLM, and try it for three turns. If you have ever felt the drift, you will feel it stop.

Try it with someone right now.

Open a session, share the link, code together. No signup. The AI is already in the room.

new session →