Construction & contracting

Project documents that answer questions instead of being searched

Specs, RFIs, and site reports pile up across a project folder. This system indexes them once, then answers plain questions against them — and names the document every answer came from.

Trigger
A question asked in chat, against a pre-indexed document set
Run mode
Answers only from indexed documents, never from general knowledge
Built with
n8n · Gemini embeddings · Supabase pgvector · Google Drive
Connected to
Google Drive · Supabase

01 / Problem

What the manual version cost

Before the system existed, this all ran on someone's attention.

  • 01

    The answer to a site question usually exists, buried in a document nobody remembers the name of.

  • 02

    Keyword search fails when the document phrases it differently from the person asking.

  • 03

    Checking takes a person who already knows the project, which makes them the bottleneck for everyone else.

  • 04

    An answer given from memory carries no traceable source, which is a problem when the question is contractual.

02 / Solution

What we built instead

Each decision below is a deliberate one — the interesting part is usually where the system refuses to guess.

  • 01

    An indexing run reads every document in the project folder, so adding files is a folder operation rather than a system task.

  • 02

    Each document is split into overlapping chunks and tagged with its source filename before anything is embedded.

  • 03

    Chunks are embedded with Gemini and stored in Supabase pgvector, so retrieval matches on meaning rather than exact wording.

  • 04

    A question is embedded the same way and matched against the store, pulling back the closest passages.

  • 05

    Source filenames are attached to the retrieved passages in code before the model sees them, so citations come from the retrieval step rather than from the model's account of it.

  • 06

    The answering prompt is restricted to the retrieved context, with an explicit instruction to say so when the answer isn't there.

Indexing pipeline

Runs once per document set. Source filenames are attached before embedding, not after.

  1. Trigger

    Indexing run starts

    Manual

  2. Action

    Pull project documents

    Google Drive

  3. Logic

    Split & tag source

  4. AI

    Generate embeddings

    Gemini

  5. Action

    Store in vector database

    Supabase

Query pipeline

Sources are attached in code between retrieval and answering, so the citation can't be invented.

  1. Trigger

    Question asked

    Chat

  2. AI

    Embed the question

    Gemini

  3. Action

    Find matching passages

    Supabase

  4. Logic

    Attach source filenames

  5. AI

    Answer from context only

    Gemini

03 / Result

What the system guarantees

Not projections. These hold because of how the system is built.

  • Every answer names the document it came from, and that filename is carried through by the pipeline rather than generated by the model.

  • A question the documents don't cover returns a plain statement to that effect instead of a plausible invention.

  • Retrieval matches meaning, so a question phrased in site language still finds a passage written in spec language.

  • Indexing and answering are separate pipelines, so re-indexing after new documents arrive doesn't disturb anything on the query side.

Next case study

Routine support questions answered from policy, everything else escalated

Customer support assistant