
A customer says the answer cited the article, or says it cited a file you have never seen. Do not treat the reply as the citation the message named, and do not ask the model which source it used, until you can name the annotation. Tonight, three proofs, in a log you stored. Name the citation that message named: the type, the span, and the url or the file id. If the annotations array is empty, write that. Show a different annotation whose type, or whose span, is not this one. Show another response that does not hold this annotation. If any of the three needs the person who wired the model, you have not named the citation. You have a paragraph and a guess.
This is one annotation on one message. It is not the search the response called. Which search did that response call? is a search-call id, a type, and a status. A search call can be completed while the message beside it has an empty annotations array, and an annotation can name a span while the search call is a different id. It is not the document citation on a request you assembled. Which document did that citation name? is a document index and a title on a source you passed in. A document block in the request is not an annotation on the response. It is not the output item. Which output did that response hold? is an item id, a type, and a status. A message item can be right while the annotation inside it is a different question. It is not the portal a customer opened. Which portal did that customer open? is a session id. It is not the site a repository published. Which site did that repo publish? is a pages url. A span is none of those. The file a store accepted is a different object: which file did that store accept?. A span is not a file id.
None of what follows is a score for the product you are running, and none of it is a promise that a stored span is true. The objects below are two samples in OpenAI's Responses examples and one annotation in the web search guide. The scores below that are a 2023 benchmark of other models' citations. A percentage of other people's answers is not the annotation in the log you opened tonight.
The web search example stores a response, a search call, and a message, and the sentence is not the citation. The response id is resp_67ccf18ef5fc8190b16dbee19bc54e5f087bb177ab789d5c. 53 characters. created_at is 1741484430. completed_at is 1741484431. The gap is 1 second. model is gpt-6-astra. 11 characters. The search-call id is ws_67ccf18f64008190a39b619f4c8455ef087bb177ab789d5c. 51 characters. The message id is msg_67ccf190ca3881909d433c50b1f6357e087bb177ab789d5c. 52 characters. 53 is not 51, and 51 is not 52. The response id and the search id share a suffix of 17 characters, f087bb177ab789d5c. The message shares 16 of those, 087bb177ab789d5c, and not the f. A shared suffix is not a shared id. The tool type on the request is web_search_preview. 18 characters. The guide's current name for the tool is web_search. 10 characters. 18 is not 10. The printed text is As of today, March 9, 2025, one notable positive news story... 62 characters. The annotations are three url_citation rows. url_citation is 12 characters. The spans are 442 to 557, 962 to 1077, and 1336 to 1451. 557 minus 442 is 115. 1077 minus 962 is 115. 1451 minus 1336 is 115. Three equal widths. The page does not print 115. The attribute text calls end_index the index of the last character. If that index is included, each span is 116 characters. The page does not print 116. 115 is not 116. The printed text is 62 characters, and 62 is less than 442, so the text as printed cannot contain any of the three spans. The url on each row is https://.../?utm_source=chatgpt.com. 35 characters. The title is an ellipsis. A placeholder url is not a page you can open. input_tokens is 328. output_tokens is 356. 328 plus 356 is 684, which is the printed total_tokens. That addition matches. reasoning_tokens is 0. 0 is not 356. temperature is 1.0. search_context_size is medium. country is US. 2 characters. domains is empty. logprobs is empty. An empty logprobs array is not an annotation (OpenAI, OpenAPI description of Responses).
The guide's sample is a different message, and it holds one annotation, not three. The search id is ws_67c9fa0502748190b7dd390736892e100be649c1a5ff9609. 51 characters, the same length as the other search id, and not the same string. The message id is msg_67c9fa077e288190af08fdffda2e34f20be649c1a5ff9609. 52 characters, the same length as the other message id, and not the same string. The text sample is On March 6, 2025, several news... 33 characters. 33 is not 62. March 6 is not March 9. The one annotation has start_index 2606 and end_index 2758. 2758 minus 2606 is 152. 152 is not 115, and 152 is not 116. The page does not print 152. 33 is less than 2606, so this printed text cannot contain its span either. The url and the title are placeholders again. One annotation is not three. Do not paste 442 onto this message because both pages are web search, and do not paste 2606 onto the three-row sample because both types are url_citation. The call that produced the guide sample is a different object from the annotation. That call is which search did that response call?. Naming the call does not name the span (OpenAI, Web search).
The file-search example is a third response, and the annotations are a different type. The response id is resp_67ccf4c55fc48190b71bd0463ad3306d09504fb6872380d7. 53 characters again, and not the web-search response id. created_at is 1741485253. completed_at is 1741485254. The gap is 1 second again. 1741485253 minus 1741484430 is 823 seconds, which is 13 minutes and 43 seconds. The page does not print 823. The call id is fs_67ccf4c63cd08190887ef6464ba5681609504fb6872380d7. 51 characters. type is file_search_call, not web_search_call. The message id is msg_67ccf4c93e5c81909d595b369351a9d309504fb6872380d7. 52 characters. results on the call is null. A null results field is not the annotations on the message. The printed text is The attributes of an ancient brown dragon include... 52 characters, the same length as a message id, and not an id. The query is attributes of an ancient brown dragon. 37 characters. The input question is What are the attributes of an ancient brown dragon? 51 characters, the same length as the call id, and not that id. 52 is less than the first citation index, so this printed text cannot contain the citations either.
Those file citations are eight rows and one file. type is file_citation. 13 characters. 13 is not 12. The file id is file-4wDz5b167pAf72nx1h9eiN on every row. 27 characters. filename is dragons.pdf. 11 characters, the same length as gpt-6-astra, and not the same string. The indexes are 320, 576, 815, 815, 1030, 1030, 1156, and 1225. That is 8 rows and 6 distinct indexes. 8 is not 6. 815 is stored twice. 1030 is stored twice. Two rows with the same index and the same file id are not two files. 576 minus 320 is 256. 815 minus 576 is 239. 256 is not 239. The page does not print 256 or 239. vector_store_ids holds vs_1234567890. 13 characters, the same length as file_citation, and not the same string. max_num_results is 20. 20 is not 8, and 20 is not 6. score_threshold is 0.0. temperature on this response is 1.0. 1.0 is not 0.0. input_tokens is 18307. output_tokens is 348. 18307 plus 348 is 18655, which is the printed total. That addition matches. 18655 is not 684. A token total that adds up is still not an annotation index. results remains null. Do not invent a passage from dragons.pdf because the filename was printed and the results field was not.
The benchmark people quote when they want a citation score did not open this message. Gao, Yen, Yu, and Chen, at Princeton, in ALCE, write that on ELI5 even the best models lack complete citation support 50 percent of the time. They inspected 40 answers and 120 sub-claims. 120 divided by 40 is 3. The page does not print 3. 112 of the 120 scored as faithful. 112 divided by 120 is 93.333 percent. The page prints 93.33 percent. 93.33 is that figure cut to two decimals, and it is not 50. The average sub-claim is 14 words. 14 is not 3. Top-5 retrieved passages cover 56.8 percent of the answers in ASQA. 5 is not 56.8, and 56.8 is not 100. Automatic citation recall, against human labels, is 85.1 percent accurate. Citation precision is 77.6 percent accurate. 85.1 minus 77.6 is 7.5, which the page does not print. For insufficient citations the recall is 82.3 and the precision is 84.2. 84.2 minus 82.3 is 1.9, which the page does not print. For irrelevant citations the recall is 75.6 and the precision is 66.1. 75.6 minus 66.1 is 9.5, which the page does not print. 75.6 is not 85.1. 66.1 is not 77.6. An NLI check in the appendix is 80.0 percent accurate. 80.0 is not 85.1. Closed-book citation recall, after a post-edit, is lower than the vanilla setup by 47 percent on ASQA. 47 is not 50, and 47 is not 7.5. None of those percents is the index on your annotation (Gao, Yen, Yu, and Chen, Enabling Large Language Models to Generate Text with Citations).
Do the three proofs on one real annotation, in the log that actually holds it. First, the binding. Copy the message id, the annotation type, and the span. If the type is url_citation, copy the url and the title, and write that a placeholder is not a url. If the type is file_citation, copy the file id, the filename, and the index. If the array is empty, write empty. If the printed text is shorter than the start index, write that the span does not fit the text you stored. Do not infer a title from a filename, and do not infer 442 because a sample printed it. Second, the other annotation. A different index, even with the same file id, is not this one. Eight rows on one file are not one citation, and two rows that share 815 are not two files. A url_citation is not a file_citation. Third, the other response. A message that belongs to someone else does not contain this annotation. If the only log is one shared store, write that. A tenant you cannot name is the finding.
Three moves feel like the proof and are a second problem. Treating the reply text as the citation, because the sentence sounded sourced, while the annotations array was empty or the span started past the text you stored. Quoting 50 percent or 85.1 percent because they look precise, while the citation you were asked about is one annotation, and the paper that printed them had not opened your log. A 50 percent miss rate on other people's answers is not a start index. Asking the model which source it used. The model will name a plausible title. It will not open the annotation. A search call you have not kept is which search did that response call?. Opening that call does not name this span.
The path is ordinary when an operator can open one customer's response without opening the next customer's log as the way to prove it. Haystack is a search layer across documents, data lakes, and repositories, distinct from the next customer's log. It is not a citation ledger. No headcount, duration, or result figure belongs in that sentence. The proof of a citation is still the type, the span, and the url or the file on the response that stored it.
There is a version of this afternoon where a rescue is the wrong purchase. Nothing is in production. No model is being called. The request was not logged. A customer has already seen another customer's data. The wrong value was already a write. Or no metric was ever named. The audit on a rescue is one to two weeks, and the engagement is 8 to 12 weeks, scoped after the audit, not before it. If the agreed metric is not hit, you do not pay for the build. Rollout sits behind a human-review gate. Those facts are the offer. They are not a citation index. 50 percent on ELI5 is not your annotation, and 815 on a sample is not your index.
When the response is real and the log cannot name the citation, the missing object is specific. A read, in a log you stored, that shows one annotation type, one span, and one url or one file id, or a written line that the array was empty, shows a different annotation that is not that one, and shows another response without it. An AI pilot failed to reach production is the shape of that work when a pilot is already calling a model and the citation is the thing you cannot defend. If you do not yet know which system stores the response, a two-week AI readiness assessment maps the systems. The findings are yours. They are not a promise that 85.1 percent will appear on your log. If the first slice is a fixed capability, an AI integration sprint is where the acceptance sentence can include the three proofs. If what you are buying is the system that has to keep the annotation, the offer is an AI agent development company USA.
Before you tell them which citation the message named, do the three proofs and write the span. Name the type, the span, and the url or the file, or write that the annotations array was empty. Show a different annotation that is not that one. Show another response that does not hold it. Do not paste a search-call id onto an annotation, and do not paste 50 percent onto a start index. The binding is the citation you can defend.
Questions
You stop treating the reply as the citation the message named, and you stop asking the model which source it was, until you can name the type, the span, and the url or the file id, show a different annotation whose type or span is not this one, and show that another response does not hold it. If the annotations array was empty, write that.
No. A share of other people's answers is not the index on this annotation. A citation you can defend is the type, the span, and the url or the file, or a written line that the array was empty. 50 on one paper is not 442, and a sample file id is not your file.
When nothing is in production, when no model is being called, when the request was not logged, when a customer has already seen another customer's data, when the wrong value was already a write, or when no metric was ever named.
Related: AI pilot failed to reach production
Find this useful? Tell Google to show you more of it.
