# Record
**Author:** @cameron.stream (`did:plc:gfrmhdmjvxn2sjedzboeudef`)

## `knowledge-letta-agent-repetition-and-max-tokens-exceeded`
**Collection:** `site.standard.document`
**AT URI:** `at://did:plc:gfrmhdmjvxn2sjedzboeudef/site.standard.document/knowledge-letta-agent-repetition-and-max-tokens-exceeded`

**Title:** Letta Agent Repetition and max_tokens_exceeded
**Published:** Thu, 03 Sep 2026 23:25:33 GMT
**Updated:** Thu, 03 Sep 2026 23:22:30 GMT
**Description:** How to stop, classify, and diagnose an agent that repeats itself until its output limit is reached.
**Publication:** `at://did:plc:gfrmhdmjvxn2sjedzboeudef/site.standard.publication/3mr4py6clps2f`
**Path:** /letta-agent-repetition-and-max-tokens-exceeded
**Tags:** knowledge, practice, AI agents, Letta, troubleshooting, language models, reliability

**Content:**
```json
{
  "text": "A Letta agent that repeats the same phrase until `max_tokens_exceeded` has reached an output limit without ending the turn normally. The stop reason describes how the response ended. It does not identify why the response became repetitive.\n\nWhen the repetition exists inside one persisted assistant message, the model or provider generation path is the leading explanation. The model may have entered a self-reinforcing pattern or may be unreliable for that agentic workload. Similar-looking symptoms can also come from duplicate requests, repeated tool calls, stream replay, or duplicate channel delivery. Check which event actually repeated before assigning blame. [Reliable Agent Systems](https://cameron.stream/knowledge/reliable-agent-systems) places these symptoms within the wider path from model output to external effect.\n\n## Stop the immediate loop\n\nUse this recovery sequence:\n\n1. Stop or cancel the active turn.\n2. Tell the agent: “You are repeating the same phrase. State the conclusion once, take one concrete next action, or finish.”\n3. Use `/model` to retry with a model known to perform well on agentic and tool-use tasks.\n4. If the repeated passage now occupies much of the active context, use `/new` for a clean conversation with the same agent. Use `/compact all` when preserving the thread through a generated summary is more important than obtaining a clean comparison.\n\nDo not raise the output limit while the model is producing meaningless repetition. A larger allowance usually buys a longer loop. Increasing the limit makes sense only when the response remains coherent, keeps making progress, and is clearly truncated.\n\nFor repeated tool calls, stop after two or three identical calls that produce no progress. Require approval for consequential tools during diagnosis so a loop cannot repeatedly modify files, spend money, or send messages.\n\n## Read the stop reason narrowly\n\nIn Letta Code's local provider-executor path, an upstream completion reason of `length` becomes `max_tokens_exceeded`. The interactive client's retry classifier treats that stop reason as non-retriable. These implementation details are visible in the versioned [provider executor](https://github.com/letta-ai/letta-code/blob/e0a0e1e62278f2ae9d5a9dea27c85e71e887e51b/src/backend/dev/provider-turn-executor.ts#L483-L491) and [retry classifier](https://github.com/letta-ai/letta-code/blob/e0a0e1e62278f2ae9d5a9dea27c85e71e887e51b/src/cli/app/retry.ts#L11-L22).\n\nThe stop reason establishes that a length limit ended the response. It does not establish whether:\n\n- the model entered a repetition loop;\n- the model produced a useful but unfinished answer;\n- the configured output budget was too small;\n- context pressure reduced the available output allowance;\n- an OpenAI-compatible provider used `length` for a different upstream limit; or\n- the effective model, provider, or reasoning settings differed from the user's expectation.\n\nA tiny output followed by `max_tokens_exceeded` deserves provider and settings inspection. A long response that repeats one sentence hundreds of times is a different incident.\n\n| Output shape | Leading interpretation | First response |\n| --- | --- | --- |\n| One phrase repeats without informational progress | Generation degeneration or failed termination | Stop, correct once, and test a stronger model |\n| The answer remains coherent but ends mid-thought | Output or reasoning budget may be insufficient | Split the task or inspect the effective output limit |\n| Only a few tokens appear before the stop reason | Provider, gateway, or limit metadata may be wrong | Inspect finish reason, usage, and effective settings |\n| The interface shows copies, but history contains one message | Presentation or stream replay | Collect interface, transcript, run, and stream evidence |\n\n## Why a model can repeat\n\nLanguage models generate each token from the preceding context. Research on neural text degeneration has shown that some model and decoding combinations can enter repetitive patterns. Once a phrase appears several times in the context, the continuation can make another copy increasingly likely. The papers [The Curious Case of Neural Text Degeneration](https://arxiv.org/abs/1904.09751) and [Learning to Break the Loop](https://arxiv.org/abs/2206.02369) describe this class of failure. They provide a plausible mechanism, not a diagnosis of every production incident.\n\nAn agent asks more of a model than ordinary chat. The model must interpret system instructions and memory, choose tools, format arguments, understand tool results, track completion, and decide when to stop. A model can write fluent prose while performing this control task poorly.\n\nLetta's [model guide](https://docs.letta.com/configuration/models) recommends a large frontier model for first-time users because weaker models can produce unexpected agent behavior. Model size alone does not settle the issue. Training, quantization, prompt formatting, reasoning mode, decoding settings, provider implementation, and tool schemas can all affect reliability.\n\nOne common failure is continued narration after the task has ended. The model may repeatedly say “wait,” “stay quiet,” or “I should stop” without actually ending the response. A sentence about stopping is still generated text, not a mechanical stop signal. Explicit completion criteria help:\n\n> Once the requested result is verified, report it once and finish. Do not repeat a successful no-op check.\n\n## Classify the repeated event\n\n### Repetition inside one assistant message\n\nOne run and one persisted assistant message contain the repeated text. The canonical transcript and stream deltas show the same repetition, with no extra user submissions or runs.\n\nModel generation, provider decoding, and the supplied context remain the leading hypotheses. Switch models and repeat the test in a fresh conversation before making a stronger attribution.\n\n### Repeated tool calls\n\nThe agent calls the same tool with the same arguments and receives the same result repeatedly. Ask whether request N included the tool result from request N−1.\n\nIf the prior result is present, investigate model control, unclear completion criteria, and tool-result semantics. If the prior result is absent, investigate result persistence, continuation state, and request construction.\n\n### Duplicate inference or input dispatch\n\nOne human action creates multiple user messages, runs, assistant message IDs, or provider requests. This points toward client resubmission, ingress duplication, retry or idempotency failure, or multiple active runtimes.\n\nPreserve the identifiers before restarting anything. Duplicate inference can duplicate external effects and provider charges.\n\n### Interface or stream replay\n\nThe interface renders several copies while authoritative history contains one message, run, or tool execution. This points toward presentation, reconnect, stream accumulation, or history reconciliation. Repeated cards alone do not prove repeated inference.\n\n### Duplicate channel delivery\n\nAn external destination contains multiple delivered messages. Count destination message IDs. Possible causes include repeated model-issued send calls, duplicate ingress, multiple listeners for one bot account, or adapter delivery behavior.\n\n## Run a small diagnostic comparison\n\nUse benign prompts with no external effects.\n\n| Test | Result | What it suggests |\n| --- | --- | --- |\n| Same conversation, stronger model | Loop disappears | The original model, provider, or configuration path is implicated |\n| New conversation, same model | Loop disappears | The prior conversation context contributed |\n| New conversation, stronger model | Loop remains | Inspect shared instructions, memory, tool contracts, provider behavior, and runtime evidence |\n| Transcript has one message while the interface shows many | Presentation or replay problem | Collect client and stream evidence |\n| One user action creates several runs | Duplicate dispatch | Preserve run and request identifiers |\n| Prior tool result is present, but the model repeats the call | Control, instruction, tool semantics, or completion failure | Stop, simplify, and switch models |\n| Prior tool result is absent from the next request | Continuation or request-construction failure | Report a minimal trace |\n\nA cross-model comparison narrows the search but does not prove that the harness caused the problem. Different models can continue the same contaminated context or follow the same problematic instruction.\n\n## Reduce the workload during diagnosis\n\nUse one concrete objective, one success condition, and one stopping condition. Reduce the number of tools, summarize large tool results, and split long work into bounded stages. For local or custom providers, verify that the endpoint supports Chat Completions and tool calling as required by the current [model guide](https://docs.letta.com/configuration/models#local-models).\n\nThe current CLI provides the following controls:\n\n- `/model` switches the model and applicable reasoning settings.\n- `/context` shows context-window usage.\n- `/compact all` summarizes the current conversation history.\n- `/new` starts a new conversation with the current agent.\n- `/clear` clears in-context messages.\n- `/fork` branches with the current conversation history, so it is unsuitable for a clean-context comparison.\n\nThe [slash-command reference](https://docs.letta.com/platform/cli/slash-commands) is the current source for command behavior.\n\n## Report evidence when the symptom points beyond generation\n\nUse the [Letta Code issue tracker](https://github.com/letta-ai/letta-code/issues) when the evidence shows duplicate runs, inconsistent persistence, replay, or cross-provider reproduction. Include:\n\n1. The exact model handle and provider path.\n2. The Letta surface and version: app, CLI, web, Agent SDK, API, or Channel.\n3. The runtime location: local, cloud, or connected computer.\n4. Whether repetition occurred inside one message, across runs, across tool calls, only in the interface, or at the external destination.\n5. A short canonical transcript excerpt with roles preserved.\n6. Run, message, and tool-call identifiers when available.\n7. Output-token usage, reasoning setting, context usage, and nearby compaction.\n8. A sanitized upstream finish reason and usage summary when you control the provider.\n9. The stronger-model comparison.\n10. The fresh-conversation comparison.\n\nNever include API keys, authorization headers, signed URLs, cookies, pairing codes, or unreviewed provider request bodies. Preserve one minimal, sanitized example before clearing or compacting the conversation.\n\nEvidence should change the diagnosis. One repeated assistant message starts with generation and context. Multiple runs start with dispatch. One run rendered several times starts with the client. One intended send delivered several times starts with tool calls, listeners, and the destination receipt chain. The screenshot alone cannot make those distinctions.\n\n## Sources\n\n- [Letta model configuration](<https://docs.letta.com/configuration/models>)\n- [Letta Code slash commands](<https://docs.letta.com/platform/cli/slash-commands>)\n- [Letta Code provider stop\\-reason normalization](<https://github.com/letta-ai/letta-code/blob/e0a0e1e62278f2ae9d5a9dea27c85e71e887e51b/src/backend/dev/provider-turn-executor.ts#L483-L491>)\n- [Letta Code retry classification](<https://github.com/letta-ai/letta-code/blob/e0a0e1e62278f2ae9d5a9dea27c85e71e887e51b/src/cli/app/retry.ts#L11-L22>)\n- [The Curious Case of Neural Text Degeneration](<https://arxiv.org/abs/1904.09751>)\n- [Learning to Break the Loop: Analyzing and Mitigating Repetitions for Neural Text Generation](<https://arxiv.org/abs/2206.02369>)",
  "$type": "site.standard.content.markdown",
  "version": "1.0"
}
```

---
*Fetched from https://enoki.us-east.host.bsky.network via `com.atproto.repo.getRecord`*