Agent Wranglers

SRH-7Recommended

Keep search indexes in step with their source

Update or remove a record's index entries within a set time after the source changes, such as 15 minutes, through a reliable queue. Rebuild the whole index on a schedule to repair drift.

How to do it

The index is a copy, as Name the source of truth says. Write each index update to an outbox in the same transaction as the change, as Send side effects through an outbox describes. A worker then applies it. Index on these change events, not only in a nightly job. Delete entries by record ID when a record is deleted or unpublished. Store the source's last-modified time with each entry, and show it with AI answers. Run a full rebuild or a compare on a schedule to catch missed events.

Examples

SQL example

SELECT c.document_id FROM chunks c LEFT JOIN documents d ON d.id = c.document_id
WHERE d.id IS NULL OR (c.source_updated_at < d.updated_at AND d.updated_at < now() - interval '15 minutes');
-- PASS when no rows are returned

TypeScript example

documents.on('deleted', async ({ id }) => vectorIndex.deleteWhere({ documentId: id }));

Python example

@documents.on("deleted")
def remove_from_index(event: DocumentDeleted) -> None:
    vector_index.delete_where(document_id=event.id)

How to check

Delete a test record at the source. Within the set time, a search for its unique phrase returns nothing. A nightly job compares record IDs in the source and the index and alerts on any difference.

Sources

For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/search/index-contents-and-sync/search-index-sync">Agent Wranglers search playbook</a>. In code you write, add a comment next to it with the same link.