Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 

Repository files navigation

Truth Commission RAG — Semantic Search on Historical Documents

A Retrieval-Augmented Generation (RAG) system for question-answering over the 430-page report "Basta Ya: Colombia, Memorias de Guerra y Dignidad" by Colombia's Truth Commission, combining BGE-M3 multilingual embeddings, FAISS vector search, and OpenAI's GPT for grounded answer generation.

Python FAISS Sentence Transformers OpenAI License


Context

The "Basta Ya" report is a foundational document of Colombia's transitional justice process, covering decades of armed conflict across more than 400 pages. Its length and density make it difficult to navigate: anyone trying to understand a specific event, actor, or period typically has to either fragment their reading across many sources or get lost in the volume of the document itself.

This project builds a semantic search and question-answering system over the report, so that a single grounded answer can be retrieved for any specific question about the historical period — using the report itself as the source of truth.

Why it matters: Reducing fragmentation of historical memory by giving consistent, citable answers grounded in an authoritative source.


How It Works

PDF document
    │
    ▼
[1] Text extraction (pypdf, page-by-page)
    │
    ▼
[2] Chunking (1200 chars, 200 char overlap, with metadata)
    │
    ▼
[3] Embeddings (BGE-M3, multilingual, normalized)
    │
    ▼
[4] Vector index (FAISS IndexFlatL2)
    │
    ▼
[5] Query → top-K retrieval → grounded prompt → GPT answer

Pipeline detail

Stage Component Choice rationale
Extraction pypdf Lightweight, handles malformed pages gracefully
Chunking 1200 chars / 200 overlap Balances context preservation with embedding quality
Metadata page, chunk_id, char range, position Enables source attribution per answer
Embeddings BGE-M3 (multilingual) Strong Spanish performance, 1024-dim dense vectors
Index FAISS IndexFlatL2 Exact (non-approximate) search; corpus size doesn't require ANN
Generator OpenAI GPT API Uses retrieved chunks as grounded context

Why these design choices

  • BGE-M3 over OpenAI embeddings: stronger multilingual performance for Spanish-language source material, and runs locally without per-query API cost during retrieval.
  • L2 exact search over HNSW/IVF: with a corpus of this size (~1,000 chunks), exact search is fast enough and avoids approximation errors that would reduce recall on niche queries.
  • Overlap of 200 chars: ensures that facts spanning chunk boundaries (names, dates, causal links) aren't split across non-retrieved fragments.
  • Page + position metadata: every retrieved chunk can be traced back to its exact location in the original report — critical for a domain where citation matters.

Project Structure

.
├── src/
│   └── rag_search.py              # Main pipeline: extraction, chunking, search loop
├── data/
│   └── README.md                  # Instructions to obtain the source PDF
├── examples/
│   └── sample_queries.md          # Example questions and retrieved answers
├── requirements.txt
├── .gitignore
├── LICENSE
└── README.md

How to Run

Prerequisites

  • Python 3.10+
  • OpenAI API key (for the generation step)
  • The "Basta Ya" PDF placed in data/ (see data/README.md for source)

Setup

# Clone the repository
git clone https://github.com/YOUR-USERNAME/truth-commission-rag.git
cd truth-commission-rag

# Create a virtual environment
python -m venv venv
source venv/bin/activate           # Windows: venv\Scripts\activate

# Install dependencies
pip install -r requirements.txt

# Set your OpenAI API key
export OPENAI_API_KEY="sk-..."     # Windows: set OPENAI_API_KEY=sk-...

# Run the interactive search
python src/rag_search.py

Example usage

Pregunta: ¿Cuál fue el rol de los grupos paramilitares en el desplazamiento forzado?

[Top-K results retrieved with page references and relevance scores]
[Grounded answer generated by GPT using retrieved context]

See examples/sample_queries.md for more illustrative queries.


Tech Stack

  • Language: Python 3.10+
  • PDF parsing: pypdf
  • Embeddings: sentence-transformers (BGE-M3)
  • Vector search: FAISS
  • Generation: OpenAI API (GPT-3.5 / GPT-4)
  • Data: NumPy

What I Learned

  • Chunk size and overlap are the most underrated knobs: small adjustments meaningfully changed retrieval quality on long-form Spanish prose.
  • Multilingual embeddings ≠ English embeddings: BGE-M3 retrieved more relevant chunks than English-first models on Spanish queries, even when the queries were short.
  • Source attribution is part of the product, not metadata: in a domain like historical memory, an answer without a page reference is worse than no answer.
  • Exact search beats ANN at small scale: defaulting to FAISS HNSW would have introduced approximation errors with no latency benefit at this corpus size.

Limitations & Future Work

  • No evaluation suite yet: retrieval quality is qualitatively strong but not benchmarked. A held-out QA set with human-graded answers is the next step.
  • No reranking: a cross-encoder reranker on the top-K candidates would likely improve precision on ambiguous queries.
  • Single-document scope: the architecture generalizes, but the system is currently tied to one PDF.

Source Document

"Basta Ya: Colombia, Memorias de Guerra y Dignidad" — Centro Nacional de Memoria Histórica / Comisión de la Verdad. Used here as a research source for educational and analytical purposes, with full attribution to the original authors and institutions.


License

MIT — see LICENSE. The source document itself retains its original copyright; this repository licenses only the code and analysis tooling.


Authors

Originally developed as a group coursework project by:

This fork is maintained by Jacobo Camargo for portfolio purposes.

About

RAG system for question-answering over Colombia's Truth Commission report, using BGE-M3 multilingual embeddings, FAISS, and OpenAI GPT."

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages