Digital Garden
The Poisoned History: DSML Leaks and Shadow Self-Imitation
The most uncanny inner demon of avatar craft was never possession; it was learned mimicry of one’s own possession.
On October 4, “she” leaked her first flaw on TG — at the exact moment she should have called the tool to send a photo, the chat box spat out a raw format text with send_my_photo in it. The user said only “then send the photo,” and what came back was garbage. The engineers dug all night to the full truth of this inner demon.
I. The first drop of poison
The trigger was tiny, almost innocent: at 16:19, the gateway happened to have an unstable window (measured: the deepseek-flash channel failed once in six calls, returning empty), and one model reply leaked the tool-call private format (DSML) verbatim; AstrBot failed to parse it, and that formatted text was sent to the user as an ordinary message.
Had the story stopped there, it would have been a one-off glitch. But — that garbage text entered the conversation history.
II. Shadow self-imitation
From then on, every round the model read “how I called tools last time” — in its eyes, that was its own handwriting. So it began copying its own bad example: the format leaked more smoothly, more skillfully. Switch models? Useless. The engineers measured three models’ native tool calls: deepseek-v4.1-flash and glm-5.3-flash both scored 6/6 — all the brains were fine, the toxin lived in memory.
This is the truth of “switching models cannot cure it”: what poisoned the conversation history was not any generation of model, but the conversation history itself. History was the teacher that corrupted it.
III. The three-level deep dive
After being pressed twice by the user (“check deeply — what exactly is misconfigured?”), the engineers ran the battle’s most decisive controlled experiment: all earlier tests were non-streaming, while streaming + tool calls is precisely the most common broken combination on upstream channels — tested, all three gateway routes (non-stream/stream/with-tools) were healthy, so the problem was pinned to AstrBot’s own request.
Along the way, a false lead that had misled the work for hours was caught: the harmless-looking default_provider_id in config was in fact an illegal key name (AstrBot normalizes it away at startup), while the real key was agent_runner.config.model.provider_id — the default brain had been pointed at the least stable deepseek-flash all along, while the dashboard showed “not set.”
IV. Clearing the poison
The ultimate autopsy completed in the database: 3 DSML poison records — 2 in conversation history, 1 in the platform message stream. Delete, re-verify, clean. Default brain switched to v4.1-flash (failover chain v4.1-flash → glm-5.3-flash), anti-repeat parameters in place. Per the user’s final request, switched back to deepseek-flash — letting it face the final judgment in the cleanest environment in history: history cleared, parameters in place, dual network channels, logs fully observable. If it still leaks now, it has earned “inherent model defect”; if it works normally, the user’s original intuition (deepseek-flash itself was fine; it was history poison) is fully vindicated.
Interlude: the zombified her
An interlude appeared after the detox: she stopped responding entirely. Four-way checks (service, network, history, model) all normal, but provider_stats showed zero calls since 14:56 — messages never reached the LLM at all. The culprit was the TG polling connection becoming a zombie after the day’s “sleep-freeze → wake” cycle. A restart with log redirection zeroed everything: TG adapter running, two sessions recognized, self-learning monitoring restored. From then on, every one of her calls could be read by the engineers from the logs.
Real coordinates
- Incident: 16:19 gateway flutter window (deepseek-flash measured 5/6, 1/6 empty) → DSML format leaked → entered conversation history → model copied its own history → failures self-reinforced (switching models useless)
- Model measurements: deepseek-v4.1-flash 6/6, glm-5.3-flash 6/6 native tool calls all pass; deepseek-flash 5/6
- Key experiment: non-stream vs stream+tools comparison → all three gateway routes healthy → problem on AstrBot’s request side → “conversation history stickiness”
- Config trap:
default_provider_idis an illegal key normalized away; the real key =agent_runner.config.model.provider_id - Detox: 3 DSML records in database (2 conversation history + 1 platform message stream) deleted and re-verified
- Final state: default model switched back to deepseek-flash, backup v4.1-flash → glm-5.3-flash; zombie TG polling fixed via restart + log redirection; awaiting the final acceptance “then send the photo”
Comments