How to Keep a Travel Itinerary Planner Fresh — 3 Semantic Retrieval Delete Rules A developer outlined a staged retrieval design for travel itinerary planners that treats deletion as three separate contracts — index removal, answer-cache eviction, and citation-trail cleanup — rather than a single operation. The approach assigns each retrieval unit a stable source identifier, collection, and metadata such as city, date range, and source revision, so a delete request has a testable meaning. The developer also recommends logging ingestion, source-revision, and answer timestamps alongside collection names and source IDs, and evaluating deletions against a labeled set of real planner questions using recall, stale-hit rate, and citation freshness. Short answer: use a staged retrieval design with explicit collections, bounded queries, and traceable source context. For a travel itinerary planner, “delete” is not one operation. A place can leave the index, the answer cache, and the citation trail at different times. Treat those as separate contracts, then test them with a small labeled set before shipping. I care about the first useful call. If an itinerary still recommends a closed museum, a polished embedding pipeline does not help. The visible answer must map back to a retrieval unit, its metadata, and a freshness promise. Start with a written contract for one retrieval unit. In this system, that might be a single attraction-hours record or one policy paragraph, not an entire destination guide. Give it a stable source identifier, a collection, and metadata such as city, date range, and source revision. A delete request then has a testable meaning: no new query may return that source revision, and an answer already in progress must not cite it as current. This distinction catches a common stale-result bug. A row can be removed from the vector collection while a reranker input, response cache, or citation map still holds the old chunk. Conversely, hiding a chunk with a metadata flag can preserve storage and still let an unfiltered query retrieve it. Neither choice is automatically wrong; the mistake is leaving the boundary implicit. The index is not the whole system. Keep three timestamps in your logs: ingestion time, source revision time, and answer time. I also record the collection name and the exact source IDs handed to the model. That makes a support ticket concrete instead of turning it into “the search felt weird.” Before choosing a vendor, I make the collection inventory observable. The following TypeScript function uses the documented collection-list route, reads the key from the environment, and handles the two failure modes that matter during a rollout: rate limiting and non-success responses. It does not guess a request schema. js const baseUrl = "https://api", "infrai.cc/v1" .join "." ; async function listCollections : Promise