Una respuesta con fuentes lleva citas en línea ancladas al texto por posición de caracteres, y una lista estructurada de las fuentes que usó: número de fuente, etiqueta, página, modalidad y un enlace firmado para abrir el original. Tu aplicación renderiza referencias sin analizar la respuesta.
Pregunta una vez. Renderiza las fuentes desde la respuesta.
El modo nativo mantiene la respuesta con forma OpenAI: anotaciones sobre el texto, fuentes en file_search_call.results. Nada que analizar, nada propietario que aprender.
CALYPSO_API_KEY
import os
from openai import OpenAI
client = OpenAI(api_key=os.environ["CALYPSO_API_KEY"],
base_url="https://api.calypso.so/v1")
resp = client.responses.create(
model="calypso-agent",
input="What is our refund policy?",
metadata={"citation_compat": "native", "sources_appendix": "omit"},
)
print(resp.output_text)
for item in resp.output:
if item.type == "file_search_call":
for r in item.results:
a = r.attributes
print(f"[{a['source_index']}] {a['label']}") # refund_policy_2026.pdf (p. 4)
Dos superficies
Responses para interfaces con citas. Chat Completions por compatibilidad.
Ambos endpoints llevan citas. Responses expone toda la superficie estructurada; Chat Completions se limita a la forma url_citation que define esa especificación.
Responses
Las citas viven en
output[] → message → output_text.annotations[]
Las fuentes viven en
output[] → file_search_call.results[]
Recomendado. En streaming envía un evento annotation.added por cita y los resultados completos en response.completed.
Chat Completions
Las citas viven en
choices[0].message.annotations[] como url_citation
Las fuentes viven en
Un apéndice "Sources:" en texto plano dentro del contenido
Las fuentes de archivos y medios se mapean a url_citation con una URL firmada cuando existe y el nombre de archivo como título. En streaming, las anotaciones llegan en un último fragmento.
Los atributos
Qué lleva cada fuente.
Los mismos atributos aparecen en los resultados de Responses y en los de Search. Construye tu lista de fuentes directamente desde ellos.
source_index
Número de fuente estable, desde 1, que coincide con el orden [n] del texto. Úsalo para las insignias y la lista.
label
Listo para mostrar, por ejemplo refund_policy_2026.pdf (p. 4). Si no hay más, usa el nombre del archivo.
page_number · page_label · locator_label
Dónde dentro del documento, cuando se sabe. Los PDFs citan la página; otros documentos citan el archivo.
modality · mime_type
text, multimodal o image, y el tipo MIME. Una cita a una imagen apunta a la propia imagen.
access_url · media_id
Una URL firmada para abrir el original cuando existe, e identificadores de medios para vistas previas.
text · excerpt · preview
La evidencia citada que usó la respuesta, más descriptores estructurados de extracto y vista previa.
Cómo funciona
Preguntar, mapear, abrir.
01
Pregunta a un agente
Llama a Responses con calypso-agent o con un agente con nombre. La recuperación corre sobre sus buckets y la evidencia vuelve con la respuesta.
02
Mapea las posiciones al texto
Cada anotación lleva start_index y end_index. Coloca tus marcadores [n] desde las posiciones, numerados por source_index.
03
Deja que los usuarios abran la fuente
Renderiza la lista de fuentes desde los atributos y enlaza cada entrada a su access_url para que el lector pueda comprobar la página.
Renderizado
Cuatro reglas de la documentación.
01
Ancla por posiciones, no por marcadores
Usa start_index y end_index para colocar referencias. No extraigas tokens [n] del texto.
02
Numera por source_index
Es estable, empieza en 1 y coincide con el orden de las citas. Úsalo para insignias y lista.
03
Ordena antes de cortar
Aplica las anotaciones en orden descendente de start_index para que las inserciones anteriores no desplacen las posiciones posteriores.
04
Respeta el estado de grounding
Muestra un panel de fuentes solo cuando grounded_sources_state es available. hidden significa que la política oculta las fuentes; missing y none significan que no hay nada que mostrar.
De la documentación
El esquema en una tabla.
Modelo
Anotaciones OpenAI: objetos de cita anclados al texto por posición de caracteres; el texto de la respuesta se mantiene plano