Semantic Search — Regulatory Position (Objections + Filer Contacts)
search_correspondence_embedsUse this to understand the REGULATORY POSITION of a filing — what the state regulator questioned, how the carrier answered, who was on the exchange. NOT to understand what the filing does or how it rates.
Wrong tool for content questions ("what does this filing change", "what's the base rate", "which forms did it introduce", "what's the indicated vs selected rate"). Reach for search_summary_embeds (filing content), search_actuarial_embeds (rate/trend/credibility numerics), or search_filing_embeds (paragraph-level filing body) instead.
Right tool for questions about the state's dialogue with the carrier: "what did CDI push back on", "who is the reviewer on this filing", "which of my Pending Rate filings still have unresolved objections", "every filing involving actuary X".
Pure vector search over correspondence_embeds — the per-chunk embed table populated from three attachment types in a filing's source folder:
correspondence_attachment_*.pdf — CDI objection letters + carrier response letters (the dialogue itself)
supporting_document_attachment_*.pdf — actuarial memos, exhibits, transmittal letters (highest volume of filer contact info)
.pdf (top-level cover page) — SERFF's official filing-person contact block (highest per-page email density)
Every hit is a passage from one of those, ranked by cosine similarity. The excerpt IS the source text — you can quote it back to the user to replay the exchange or identify who filed the paper without a separate PDF fetch. Use source_file on each hit to see which attachment type the excerpt came from.
Facet filters (all optional, all combine with AND on top of the semantic ranking):
email— chunks mentioning this exact address (case-insensitive)email_domain— chunks mentioning any address on this domain (e.g.insurance.ca.govfor CDI reviewers)serff— scope to one filing's threadfiling_status— substring match (usePendingfor live objections,Closedfor resolved)year/year_from/year_to/date_from/date_to— filing-year and filing-date windowsstate,naic,product_type,filing_type,predecessor_prefix— carrier + programme scope
For "which filings did jane.reviewer@insurance.ca.gov touch this quarter", use list_email_workload instead — it aggregates and is designed for caseload views.
Cost: one query-embedding call + one indexed Postgres lookup. Bounded, cheap, fast.
Right surface for:
"What did CDI push back on in this filing?" — pass
serffto scope; get the reviewer's own words."Show me carrier responses to territory-factor objections" — semantic search, no scope; excerpts read as regulator-carrier dialogue.
"Find filings where CDI questioned reinsurance costs" — use the semantic query alone.
"Every objection where jane.reviewer@insurance.ca.gov was on the exchange" — pass
email, optionally combined with the semantic query."All filings whose objection thread involves anyone at Farmers" — pass
email_domain=farmersinsurance.com.
Right combination with other tools: pair with get_filing_correspondence to pull the full ordered thread for one filing once search surfaces a hit worth reading end-to-end.
Wrong surface for:
Filing-content questions (rate manuals, forms, actuarial memos) — use
search_summary_embedsorsearch_filing_embeds."Which filings had ANY objections at all" — for presence-only, prefer
get_filing_correspondencewith afile_count > 0check per SERFF.
Facet coverage (as of 2026): most objection letters do not embed email addresses in the body — CDI reviewers sign off with a name + division, not a mailbox. So email / email_domain scopes will match a minority of chunks even for filings that had a full objection round. Semantic search is the dominant surface here; the email facets are a bonus filter, not the primary shape.
Returns top-K chunks with {serff, source_file, chunk_index, similarity, excerpt, emails, email_domains, page_date, meta}. Default topK=10, max 50. Excerpt is the first 1200 chars of the matching chunk.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| naic | No | Exact NAIC carrier identifier (5-digit string). Restricts to that carrier. | |
| topK | No | Number of top hits to return. Defaults to 10; capped at 50. | |
| year | No | Exact filing year. Mutually exclusive with year_from/year_to. | |
| No | Optional exact-match email filter. Only chunks mentioning this address are searched. Case-insensitive (lowercased on match). Sparse coverage — most objection letters do not embed email addresses in the body. | ||
| query | Yes | Natural-language query. Pass the user's question verbatim — short, specific (5-30 words) matches best. Embedded and cosine-compared against per-chunk correspondence embeddings. | |
| serff | No | Optional SERFF id to scope the semantic search to a single filing's correspondence thread (shape PREFIX-IDENTIFIER). Useful for "what did CDI push back on in this filing?" questions. | |
| state | No | Two-letter US state code, uppercase. Corpus currently covers CA only. | |
| date_to | No | Upper bound on filing date (ISO YYYY-MM-DD). | |
| year_to | No | Upper bound on filing year, inclusive. | |
| date_from | No | Lower bound on filing date (ISO YYYY-MM-DD). | |
| year_from | No | Lower bound on filing year, inclusive. | |
| filing_type | No | Wildcard match on filing type ("Rate", "Rule", "Form", "Withdrawal", etc.). Substring match. | |
| email_domain | No | Optional exact-match email-domain filter (e.g. "insurance.ca.gov", "farmersinsurance.com"). Only chunks mentioning any address on that domain are searched. Case-insensitive. | |
| product_type | No | Wildcard match on product type ("Personal Auto", "Homeowners", "Commercial Auto", "Workers Compensation", etc.). Substring match. | |
| filing_status | No | Wildcard match on filing status ("Pending", "Closed - Approved", "Closed - Withdrawn", etc.). Substring match — use to distinguish live vs closed objections. | |
| predecessor_prefix | No | Bureau / org SERFF prefix ("ISOF", "NCCI", "AAIS", "MSO"). |