Skip to content

[Discovery Engine] Answer UI drops cited structuredDocumentInfo references #1

Description

@glaziermag

vertexaisearch-withanswersui.py drops cited structuredDocumentInfo references when formatting Answer API citations.

Target code:

def add_references_answers(text: str, citations: List,response):
textref = f"\n References:"
textlinks = []
for i, citation in enumerate(citations):
citindex = int(citation.sources[0].reference_id)
url = response.answer.references[citindex].chunk_info.document_metadata.uri
title = response.answer.references[citindex].chunk_info.document_metadata.title
if not any(url in link for link in textlinks):
textlinks.append(f"\n [{title}]({url})")
text = text + textref + "".join(textlinks)
return text

The public Discovery Engine / Vertex AI Search Answer schema allows Answer.Reference.content to be unstructured_document_info, chunk_info, or structured_document_info:
https://docs.cloud.google.com/generative-ai-app-builder/docs/reference/rpc/google.cloud.discoveryengine.v1#reference

Citation sources then point at answer.references[] by reference_id:
https://docs.cloud.google.com/generative-ai-app-builder/docs/reference/rpc/google.cloud.discoveryengine.v1#citationsource

This app currently assumes every cited reference is chunk_info:

citindex = int(citation.sources[0].reference_id)
url = response.answer.references[citindex].chunk_info.document_metadata.uri
title = response.answer.references[citindex].chunk_info.document_metadata.title
textlinks.append(f"\n [{title}]({url})")

For a valid Answer response where referenceId: "0" points to a structuredDocumentInfo reference, the Python client exposes an empty default chunk_info, so the rendered citation becomes an empty Markdown link.

Minimal no-live-call repro

The fixture below is minimized from a saved HTTP 200 direct REST servingConfigs:answer response. answerQueryToken and resource names are redacted, but the Answer response shape and active reference union branch are preserved.

python3 - <<'PY'
from types import SimpleNamespace

def add_references_answers(text, citations, response):
    textref = f"\n References:"
    textlinks = []
    for i, citation in enumerate(citations):
        citindex = int(citation.sources[0].reference_id)
        url = response.answer.references[citindex].chunk_info.document_metadata.uri
        title = response.answer.references[citindex].chunk_info.document_metadata.title
        if not any(url in link for link in textlinks):
            textlinks.append(f"\n [{title}]({url})")
    text = text + textref + "".join(textlinks)
    return text

fixture = {
    "answer": {
        "answerText": "Alpha requires manual review.",
        "citations": [
            {
                "startIndex": "0",
                "endIndex": "29",
                "sources": [{"referenceId": "0"}],
            }
        ],
        "references": [
            {
                "structuredDocumentInfo": {
                    "document": "projects/PROJECT/locations/global/collections/default_collection/dataStores/DATA_STORE/branches/0/documents/DOC",
                    "title": "Large session includeAnswerDetails parity sentinel",
                    "structData": {},
                }
            }
        ],
        "state": "SUCCEEDED",
    },
    "answerQueryToken": "REDACTED",
}

class EmptyDocumentMetadata:
    uri = ""
    title = ""

class EmptyChunkInfo:
    document_metadata = EmptyDocumentMetadata()

response = SimpleNamespace(
    answer=SimpleNamespace(
        answer_text=fixture["answer"]["answerText"],
        citations=[
            SimpleNamespace(sources=[SimpleNamespace(reference_id="0")])
        ],
        references=[SimpleNamespace(chunk_info=EmptyChunkInfo())],
    )
)

rendered = add_references_answers(
    response.answer.answer_text,
    response.answer.citations,
    response,
)
print(rendered)
assert "Large session includeAnswerDetails parity sentinel" not in rendered
assert "[]()" in rendered
PY

Actual output:

Alpha requires manual review.
 References:
 []()

Expected behavior:

When citation.sources[].reference_id points to a structuredDocumentInfo reference, the UI should use that branch's metadata, for example structured_document_info.title and structured_document_info.uri or a document fallback. It should not render an empty citation label/link.

Impact:

Users can receive a successful Answer response with citations enabled, but cited structured-data sources are displayed as empty links even though the raw response includes usable source metadata.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions