Skip to content

projects

client work · Crest Infosystems

eRESI: AI knowledge assistant for a mortgage lender

A production Q&A assistant over a mortgage lender's guideline PDFs. Every answer links to the sentence it came from, and questions it can't answer go to a human underwriter.

In production for the client; built in a Crest Infosystems team

The problem

A mortgage lender’s guidelines and product matrices live in long PDFs. The client wanted a question-and-answer assistant over those documents that shows exactly where every answer comes from, embedded in its intranet and its public website.

What I built

I built the user-facing side: the chat interface, streamed answers, the document-scope picker, chat history and staged loading states. I also wrote the early retrieval and S3 upload services. The work was part of a Crest Infosystems team, in a codebase with a 229-test Vitest suite.

Architecture of eRESI, the mortgage knowledge assistant The client intranet and website embed a React app with a pdf.js viewer. The app sends questions to AWS Lambda, which calls Amazon Bedrock for agentic retrieval with reranking over a knowledge base of guideline PDFs in Amazon S3, and keeps chat history in Amazon DynamoDB. If nothing relevant is found, a fixed reply sends the user to a human underwriter; otherwise the answer streams back with citations, and the viewer opens the cited PDF from S3. Client intranet Client website Embedded React app pdf.js viewer: opens the cited page, highlights the supporting sentences question streamed answer with citations AWS Lambda (API and auth) Amazon Bedrock agentic retrieval with reranking over a knowledge base, filtered per document Amazon DynamoDB chat history reads nothing relevant found Amazon S3: guideline PDFs fixed reply: check with a human underwriter
  1. The client intranet and the client website both embed the React app.
  2. The React app sends the question to AWS Lambda (API and auth).
  3. Lambda calls Amazon Bedrock: agentic retrieval with reranking over a knowledge base, filtered per document.
  4. Bedrock reads the guideline PDFs from Amazon S3.
  5. If nothing relevant is found, the reply is fixed: check with a human underwriter.
  6. Otherwise the answer streams back to the React app with citations.
  7. The pdf.js viewer loads the cited PDF from S3, opens the cited page and highlights the supporting sentences.
  8. Lambda keeps chat history in Amazon DynamoDB.

Citations a reader can check

Every answer carries inline citations. Clicking a citation opens the cited PDF at the right page and highlights the supporting sentences. The retrieval API returns no page numbers, so the location is reconstructed in the browser. When a sentence can’t be matched, the viewer falls back to the page instead of highlighting text that doesn’t support the answer.

When there is no answer

Retrieval runs as Bedrock agentic retrieval with reranking over a shared knowledge base, filtered per document. When retrieval finds nothing relevant, the assistant does not generate a guess. It returns a fixed reply telling the user to check with a human underwriter.

What I’d change

  • Build the evaluation set before the features. A golden set of real questions over the actual guideline PDFs gives an accuracy number and makes model swaps safe. The model provider has already retired one model the system depended on.
  • Make “can’t answer” a measured signal. The fallback fires when retrieval cites nothing. That can’t catch a weak answer that still cites something. A relevance threshold on the reranker scores, tuned against the evaluation set, would.
  • Design access control first. The project started with a demo user switcher and later needed proper server-side authentication and separate access for the two sites. Hiding a tab in React isn’t security; enforcement belongs on the server from the start.

sources

Client work. The source code is private.