Change references to handwriting, expand options for LLMs

This commit is contained in:
Jim Lancaster
2026-06-23 19:13:24 -05:00
parent d0626c7653
commit fdf931796e
4 changed files with 30 additions and 22 deletions
+1 -1
View File
@@ -236,7 +236,7 @@ Control:
Risk:
- transcription quality varies by handwriting and image quality
- transcription quality varies by document type, handwriting legibility, and image quality
Control:
+1 -1
View File
@@ -1,4 +1,4 @@
## Handwriting Transcription System
## Document Transcription System
This project is a production application for transcribing and preserving historical family documents. It is intentionally designed for personal-scale use, with a simplicity-first architecture that is easy to operate and easy to extend.
+26 -19
View File
@@ -1,14 +1,14 @@
## MVP Definition: Historical Document Transcription System
### 1. MVP Objective
Deliver the thinnest possible end-to-end vertical slice — a user uploads an image of a handwritten document, the system transcribes it via an AI provider, and the user reads the resulting transcript — with just enough persistence and structure to validate the core value proposition: *can AI-driven transcription, guided by curated prompts, produce useful verbatim transcripts of historical family documents?*
Deliver the thinnest possible end-to-end vertical slice — a user uploads an image of a document, the system transcribes it via a configurable AI provider, and the user reads the resulting transcript — with just enough persistence and structure to validate the core value proposition: *can AI-driven transcription, guided by curated prompts, produce useful verbatim transcripts of historical family documents?*
The MVP deliberately defers full-text search, export, revision history, MongoDB, timeline assembly, and multi-provider routing. These are additive features that don't need validation before the core transcription loop is proven.
The MVP deliberately defers full-text search, export, revision history, MongoDB, and timeline assembly. These are additive features that don't need validation before the core transcription loop is proven.
---
### 2. Core User Story
*As a family historian, I can upload a photo of a handwritten letter, wait for it to be transcribed, and read the verbatim transcript — so I can evaluate whether this system will work for my thousands of documents.*
*As a family historian, I can upload a photo of a historical document, wait for it to be transcribed, and read the verbatim transcript — so I can evaluate whether this system will work for my thousands of documents.*
---
@@ -47,12 +47,12 @@ The MVP deliberately defers full-text search, export, revision history, MongoDB,
* An in-process background worker (Python asyncio task or BackgroundTasks) that:
1. Picks up queued jobs.
2. Transitions status to processing.
3. Sends the image + the curated Markdown prompt to an AI vision model (OpenAI API — already a dependency).
3. Sends the image + the curated Markdown prompt to an AI vision model via the configured provider (OpenRouter or Gemini).
4. On success: saves the transcript text, transitions to transcribed.
5. On failure: saves the error detail, transitions to failed.
#### Feature 3: Transcription Prompt (Markdown Asset)
* A single Markdown file (prompts/transcribe_handwriting.md) encoding the verbatim transcription rules from Intent.md (the Document Issues table, scholarly guidelines, etc.).
* A single Markdown file (prompts/transcribe_document.md) encoding the verbatim transcription rules from Intent.md (the Document Issues table, scholarly guidelines, etc.).
* The worker reads this file at invocation time and injects it as the system/user prompt.
#### Feature 4: Job Status & Transcript Viewer (UI)
@@ -71,8 +71,10 @@ The MVP deliberately defers full-text search, export, revision history, MongoDB,
#### Feature 6: Centralized Configuration
* A single config.py (or Pydantic BaseSettings) loading:
* OPENAI_API_KEY (required)
* OPENAI_MODEL (default: gpt-4o)
* PROVIDER (default: openrouter; options: openrouter, gemini)
* PROVIDER_API_KEY (required)
* PROVIDER_MODEL (default: provider-appropriate default)
* PROVIDER_BASE_URL (default: provider-appropriate default; overridable)
* DATABASE_URL (default: sqlite:///./transcription.db)
* UPLOAD_DIR (default: ./uploads)
* PROMPT_DIR (default: ./prompts)
@@ -94,10 +96,10 @@ The MVP deliberately defers full-text search, export, revision history, MongoDB,
│ │ (upload, job lifecycle) │ │
│ └─────┬─────────────┬───────┘ │
│ │ │ │
│ ┌─────▼─────┐ ┌─────▼─────────────┐
│ ┌─────▼─────┐ ┌─────▼───────────────┐ │
│ │ SQLite DB │ │ Background Worker │ │
│ │ (SQLModel)│ │ OpenAI Vision
│ └───────────┘ └───────────────────┘
│ │ (SQLModel)│ │ → AI Vision Provider│
│ └───────────┘ └─────────────────────┘ │
│ │ │
│ ┌─────▼──────┐ │
│ │ prompts/ │ │
@@ -114,18 +116,23 @@ The MVP deliberately defers full-text search, export, revision history, MongoDB,
project-root/
├── docs/ # (existing)
├── prompts/
│ └── transcribe_handwriting.md # curated transcription prompt
│ └── transcribe_document.md # curated transcription prompt
├── src/
│ └── handwriting/
│ └── transcription/
│ ├── __init__.py
│ ├── app.py # FastAPI + NiceGUI app entrypoint
│ ├── config.py # Pydantic BaseSettings
│ ├── models.py # SQLModel: Document, Job, Transcript
│ ├── db.py # engine, session, create_all
│ ├── providers/
│ │ ├── __init__.py
│ │ ├── base.py # provider interface (transcribe contract)
│ │ ├── openrouter.py # OpenRouter via openai client
│ │ └── gemini.py # Google Gemini
│ ├── services/
│ │ ├── __init__.py
│ │ ├── upload.py # save file + create records
│ │ └── transcription.py # call AI provider, update job
│ │ └── transcription.py # call provider, update job
│ ├── worker.py # background job loop
│ └── ui/
│ ├── __init__.py
@@ -144,8 +151,8 @@ project-root/
#### 7. MVP Validation Criteria
The MVP is considered validated when:
1. ✅ A user can upload an image of a handwritten document through the browser.
2. ✅ The system asynchronously sends the image to OpenAI's vision model with the curated prompt.
1. ✅ A user can upload an image of a document through the browser.
2. ✅ The system asynchronously sends the image to the configured AI vision model with the curated prompt.
3. ✅ The transcript (or failure reason) is persisted and visible in the UI.
4. ✅ The transcription follows verbatim scholarly rules defined in Intent.md (spot-checked by the user on real family documents).
5. ✅ The transcription prompt is stored as a standalone Markdown file and can be edited without code changes.
@@ -158,7 +165,7 @@ These are the real unknowns this MVP exists to resolve:
| # | Question | How We Learn |
| --- | --- | --- |
| 1 | Is AI transcription quality good enough for this handwriting corpus? | User reviews 2050 real transcriptions against originals. |
| 1 | Is AI transcription quality good enough for this document corpus? | User reviews 2050 real transcriptions against originals. |
| 2 | Does the verbatim prompt produce scholarly-quality output, or does it need major rework? | Compare output to the Document Issues table rules in Intent.md. |
| 3 | What document types are hardest (old cursive, faded ink, pencil, postcards)? | Track which uploads produce failed or low-quality results. |
| 4 | Is single-image upload sufficient, or is batch upload needed early? | User friction during real scanning sessions. |
@@ -184,10 +191,10 @@ Recommended build order for the MVP (each step produces a testable increment):
| Step | Deliverable | Validates |
| --- | --- | --- |
| 1 | config.py + models.py + db.py — data layer with SQLite | Schema and config foundation |
| 2 | prompts/transcribe_handwriting.md — curated prompt from Intent.md | Prompt asset pattern |
| 3 | services/transcription.py — call OpenAI vision API with prompt + image | Core AI integration |
| 2 | prompts/transcribe_document.md — curated prompt from Intent.md | Prompt asset pattern |
| 3 | services/transcription.py + providers/ — call AI vision provider with prompt + image | Core AI integration |
| 4 | services/upload.py + worker.py — upload handling + background job loop | End-to-end pipeline (CLI-testable) |
| 5 | ui/upload_page.py + ui/jobs_page.py — NiceGUI pages | User-facing interface |
| 6 | tests/ — unit + integration tests Automated verification |
This MVP is deliberately narrow: **one prompt, one provider, one user, one image at a time, SQLite, no containers**. Every omission is intentional — the goal is to get real family documents through the transcription pipeline as fast as possible and let the quality of the output guide every subsequent decision.
This MVP is deliberately narrow: **one prompt, one configurable provider, one user, one image at a time, SQLite, no containers**. Every omission is intentional — the goal is to get real family documents through the transcription pipeline as fast as possible and let the quality of the output guide every subsequent decision.
+1
View File
@@ -5,6 +5,7 @@ description = "Add your description here"
readme = "README.md"
requires-python = ">=3.12"
dependencies = [
"google-genai>=1.0.0",
"openai>=2.43.0",
"pydantic>=2.13.4",
]