Skip to content

fix: suppress citation SSE events for unresolved (hallucinated) citation IDs - #2287

Open
octo-patch wants to merge 1 commit into
SciPhi-AI:mainfrom
octo-patch:fix/suppress-hallucinated-citation-events-2224
Open

fix: suppress citation SSE events for unresolved (hallucinated) citation IDs#2287
octo-patch wants to merge 1 commit into
SciPhi-AI:mainfrom
octo-patch:fix/suppress-hallucinated-citation-events-2224

Conversation

@octo-patch

Copy link
Copy Markdown

Fixes #2224

Problem

When streaming RAG responses, the LLM sometimes generates citation IDs that do not correspond to any retrieved document chunk (i.e., hallucinated citations). In SSEFormatter.yield_citation_event, the previous condition

if not citation_data.get("is_new") or "payload" not in citation_data:
    citation_data["payload"] = None

treated a missing "payload" key (new citation, source not found) the same as a repeated citation (where nulling the payload is intentional). As a result, the server emitted streaming events like:

{"id":"c910e2e","object":"citation","is_new":true,"span":{"start":411,"end":420},"payload":null}

Clients receiving is_new=true with payload=null cannot distinguish between a genuinely new citation (where they expect full source data) and a hallucinated one.

Solution

Split the condition into two explicit branches:

  1. Repeated citation (is_new=false): set payload=null as before — the client already has the payload from the first occurrence.
  2. New citation, source not found (is_new=true, no "payload" key): silently suppress the event. The citation ID was not in the retrieved chunks, so there is nothing meaningful to send. The citation also does not appear in the final final_answer event (that path already filters on citation_payloads), keeping streaming and final-answer behaviour consistent.
  3. New citation, source found (is_new=true, "payload" key present): unchanged — emits with full payload.

Testing

  • Repeated citations still receive payload=null.
  • New citations with a valid source still emit full payload.
  • Hallucinated citation IDs (not in search_results_collector) no longer produce a streaming event, consistent with the final-answer behaviour.

When an LLM generates a citation ID that does not match any retrieved
chunk, SSEFormatter.yield_citation_event was explicitly setting
payload=None and emitting the event, producing a confusing stream
message of the form {"is_new":true,"payload":null}.

The previous condition
  not is_new or "payload" not in citation_data
mistakenly treated a missing "payload" key the same as a repeated
citation. Only repeated citations (is_new=False) should have their
payload nulled out; a new citation with no resolvable source should
be silently suppressed instead.

After this fix:
- Repeated citations: payload set to null (existing behaviour)
- New citations with a found source: payload included (existing behaviour)
- New citations with no matching source: event suppressed, no null-
  payload surprise for clients (fixes SciPhi-AI#2224)

Co-Authored-By: Octopus <liyuan851277048@icloud.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

New citations sometimes have null payload

2 participants