Asked "openai和anthropic关系", the assistant wrote "以下是我找到的内容" and listed three points from its own memory. The stored turn has zero steps, zero sources, zero tool exchange. On screen the only trace of that is the absence of [n] citation marks, and nobody reads absence.
This is the failure mode a loop guard cannot fully close (#509, #543): the model can claim a search it never made and, asked again, can insist the claim was the answer. Fifteen live turns showed DeepSeek-V3 doing exactly that. What the backend cannot decide, the interface can show: an answer with no sources is marked as such.
What to show
On every assistant message whose stored sources is empty, a small, unmissable mark beside the message: "No sources consulted" (or the zh equivalent), in the muted token, the same place citations would otherwise render. The mark is a statement of fact, so it is right on every such message:
- a greeting or a question about the transcript carries it harmlessly;
- a refusal carries it honestly;
- "以下是我找到的内容" with nothing behind it carries it and gives itself away.
No heuristic decides when to show it; the data does. Nothing changes in the loop, the stored turn, or the API: sources is already persisted per message and already sent to the client.
Tests
- Rendering: a message with
sources: [] shows the mark; a message with one source shows citations and no mark; a streaming message shows the mark only once done arrives with no sources (not during the stream).
- History replay: a reopened conversation renders the mark on the turns that had no sources at the time.
Style-guard applies; the mark uses the existing muted token and no new colour.
Related: #509, #543, the runner change that replaces the loop.
Asked "openai和anthropic关系", the assistant wrote "以下是我找到的内容" and listed three points from its own memory. The stored turn has zero steps, zero sources, zero tool exchange. On screen the only trace of that is the absence of
[n]citation marks, and nobody reads absence.This is the failure mode a loop guard cannot fully close (#509, #543): the model can claim a search it never made and, asked again, can insist the claim was the answer. Fifteen live turns showed DeepSeek-V3 doing exactly that. What the backend cannot decide, the interface can show: an answer with no sources is marked as such.
What to show
On every assistant message whose stored
sourcesis empty, a small, unmissable mark beside the message: "No sources consulted" (or the zh equivalent), in the muted token, the same place citations would otherwise render. The mark is a statement of fact, so it is right on every such message:No heuristic decides when to show it; the data does. Nothing changes in the loop, the stored turn, or the API:
sourcesis already persisted per message and already sent to the client.Tests
sources: []shows the mark; a message with one source shows citations and no mark; a streaming message shows the mark only oncedonearrives with no sources (not during the stream).Style-guard applies; the mark uses the existing muted token and no new colour.
Related: #509, #543, the runner change that replaces the loop.