~/paras-karki · portfolio

Loading portfolio

Skip to content
PK

07

Search and answers over the document archive

Embeddings in PostgreSQL, an Azure AI Search index, and a RAG layer on top: ask in plain English, get an answer that cites its source.

Role
Full Stack Developer · Mavericks Tech Solutions
When
Sep 2025 – present
Relevant for
AI & AgentsSoftware
  1. 01 Embed question
  2. 02 SearchORDER BY embedding <=> $question LIMIT 3
  3. 03 Answer from chunks

property-policy-wording.pdf

  • Covered causes of loss include fire, lightning, windstorm and hail.
  • Sudden and accidental discharge of water from a plumbing system is covered.#1 cosine 0.89
  • Excluded: seepage or leakage continuing over 14 days or more.#2 cosine 0.83

property-schedule-guide.pdf

  • Form PC-1 lists each location with its construction, occupancy, protection and exposure.
  • Every building on Form PC-1 needs a replacement value and the year built.
  • Sprinkler and alarm details go in the protection section of the form.

underwriting-guidelines.pdf

  • Buildings valued up to $5M may be quoted without referral.
  • Buildings older than 1950 are referred to a senior underwriter.
  • Sprinklered risks receive a 10% rate credit.

claims-handbook.pdf

  • Claims should be reported within 30 days of the date of loss.
  • Photos and a repair estimate are required for water claims.#3 cosine 0.76

synthetic documents · illustrative scores · cut-off 0.60

answer · PostgreSQL + pgvector

Yes, a burst pipe is a sudden and accidental discharge, which is covered. Slow leaks that went on for 14 days or more are excluded. To claim, send photos and a repair estimate.

The question never says "plumbing"; vectors match it by meaning.

My part

I built the embeddings in PostgreSQL (pgvector), the Azure AI Search index, and the retrieval and answer layer on top.

Problem

Answers lived in years of archived policy wordings, guidelines and claim files. Finding one meant searching folders and reading PDFs end to end, and keyword search missed anything phrased differently.

Approach

Documents are chunked and embedded. Vectors live beside the records in PostgreSQL with pgvector, so similarity search is plain SQL. The same chunks are indexed in Azure AI Search for hybrid retrieval: keyword and vector scores fused, then a semantic reranker. An LLM answers from the top chunks only, citing each one, and says so when nothing scores high enough.

Outcome

Questions over the archive can be asked in plain English, and each answer cites the passage it came from so it can be checked.

What I did

  • Vectors beside the data

    pgvector keeps similarity search in plain SQL; filters by account, date or document type are ordinary WHERE clauses.

    PostgreSQLpgvector

  • Hybrid search

    Azure AI Search fuses keyword and vector scores, then reranks, catching exact terms like form numbers.

    Azure AI Search

  • Cited answers

    An LLM answers from the retrieved chunks only, citing each one.

  • Honest "not found"

    A score threshold turns weak matches into "not in these documents".

  • Bedrock prototype

    An earlier prototype: documents in an S3 bucket, synced into a Bedrock Knowledge Base (Titan embeddings, OpenSearch Serverless).

    AWS BedrockAmazon S3

Stack

  • PostgreSQL
  • pgvector
  • Azure AI Search
  • Embeddings
  • RAG
  • Python
  • FastAPI
  • AWS Bedrock
  • Amazon S3

Paras Karki · CV

page 1 of 2