A local-first semantic topology visualization prototype that turns long-form writing into an interactive 3D structure.
Article Shape analyzes a Markdown or plain-text article with real embedding vectors, builds a Mapper-style semantic graph, and renders the result as an interactive Three.js visualization. The project is designed for exploring the structure of writing: cohesion, topic drift, semantic clusters, cross-section resonance, and the overall “shape” of an article.
The prototype combines:
- Local embeddings via Ollama
qwen3-embedding:4b - Cosine-distance semantic geometry over article slices
- Mapper-inspired topological graph construction
- Classical MDS projection for deterministic 3D layout
- Three.js semantic ink cloud rendering
- Interactive interpretation layers for nodes, edges, growth animation, article DNA cards, and protein-shape analogy
This is not a text-to-image effect. The visualization is generated from actual semantic vectors and graph structure.
Most writing tools show text as a linear document. Article Shape explores a different question:
What if an article could be inspected as a semantic object?
A coherent essay should form a connected, legible structure. A scattered draft may show isolated clusters, weak bridges, abrupt branches, or overloaded regions. Article Shape makes these structural properties visible and explorable.
Potential use cases include:
- diagnosing structure in long essays, product narratives, speeches, or research notes;
- comparing coherence between different drafts;
- finding paragraphs that drift away from the main argument;
- creating visual artifacts for editorial review, presentations, or demos;
- experimenting with topology-based interfaces for writing tools.
The backend calls a local Ollama embedding model and uses the returned vector space as the basis for all downstream analysis.
Text slices → qwen3-embedding:4b → 2560-dimensional vectors
No random projection or handcrafted pseudo-embedding is used for the semantic stage.
The server builds a graph from the article’s semantic distance matrix:
Text / Markdown
→ sentence-aware adaptive slicing
→ local embedding
→ cosine distance matrix
→ eccentricity filter
→ overlapping interval cover
→ local DBSCAN clustering
→ shared-slice graph edges
→ graph metrics and 3D coordinates
The graph exposes clusters, relations, isolates, and structural loops.
A pure-Python Classical MDS implementation projects semantic distance into a stable 3D coordinate system. This keeps the visual layout reproducible and independent of browser-side randomness.
The main visual layer is a dense point-cloud / ink-field representation:
- local semantic density controls particle concentration;
- eccentricity controls color tier and visual emphasis;
- article order generates the main narrative flow line;
- Mapper edges appear as cross-section resonance lines;
- isolated or peripheral clusters become visually recognizable outliers.
The frontend includes:
- hover explanations for nodes and edges;
- “line x-ray” mode showing source paragraphs shared by an edge;
- cloud / line-mode switching;
- pause / resume rotation;
- growth animation along reading order;
- “article DNA” card export;
- protein-shape analogy panel based on sequence-shape signatures.
By default, the project runs locally with no cloud key required. Optional LLM commentary can be enabled through an OpenAI-compatible endpoint, but real credentials are intentionally kept out of the repository.
Use llm_config.example.json as a template and create your own local-only llm_config.json.
┌──────────────────────────┐
│ Browser UI │
│ Three.js / Interaction │
└─────────────┬────────────┘
│ HTTP
┌─────────────▼────────────┐
│ Python Server │
│ Static files + JSON API │
└─────────────┬────────────┘
│
┌─────────────▼────────────┐
│ Semantic Analysis Core │
│ slicing / embedding / │
│ Mapper / MDS / metrics │
└─────────────┬────────────┘
│
┌─────────────▼────────────┐
│ Local Ollama │
│ qwen3-embedding:4b │
└──────────────────────────┘
Main files:
| File | Purpose |
|---|---|
server.py |
local HTTP server, text slicing, embedding calls, Mapper graph, MDS, API responses |
src/main.js |
Three.js renderer, UI interactions, card export, hover explanations |
shape_descriptor.py |
sequence-shape descriptors and weighted distance utilities |
build_protein_db.py |
builds the reference protein-shape database |
build_article_sig_stats.py |
builds article signature statistics for cross-domain comparison |
src/proteins_db.json |
bundled reference protein-shape data |
src/article_sig_stats.json |
bundled article signature statistics |
- Python 3
- Node.js and npm
- Ollama running locally
- Ollama model:
qwen3-embedding:4b
Install the embedding model if needed:
ollama pull qwen3-embedding:4bnpm install
python3 server.pyOpen:
http://127.0.0.1:5173/
Run a basic smoke test:
npm run smokeThis checks Python syntax for the server and JavaScript syntax for the frontend.
Analyze an article and return graph data, metrics, 3D coordinates, and optional commentary.
Request:
{
"text": "# Title\nArticle body...",
"enableCommentary": false
}Response includes:
slices: adaptive text slices;nodes: semantic clusters;edges: shared-slice relations;metrics: graph metrics such as node count, edge count, isolates, and β₁;proteinMatch: nearest reference protein-shape matches when applicable;durationMs: analysis duration.
Generate or retrieve explanatory text for the already-computed graph. This endpoint is intentionally separated from /api/shape so the 3D visualization can render immediately while commentary is generated asynchronously.
- Embedding is local by default and uses Ollama.
.embed_cache/is generated locally and ignored by Git.node_modules/is generated bynpm installand ignored by Git.__pycache__/is generated by Python and ignored by Git.- Real API keys should never be committed. Use
llm_config.example.jsononly as a template.
This is a research prototype, not a production writing platform.
Known constraints:
- the default embedding endpoint assumes Ollama is running at
127.0.0.1:11434; - long documents are adaptively merged to keep the slice budget manageable;
- commentary quality depends on the optional external LLM configuration;
- the protein analogy is a shape-signature comparison, not a biological equivalence claim;
- visual interpretation should be treated as an exploratory aid, not an objective writing score.
This repository intentionally includes only the source code and small reference JSON assets required to run the prototype.
Excluded from Git:
- real
llm_config.json; - local embedding cache;
- dependency folders;
- generated Python cache;
- videos, music, app bundles, logs, and other local working assets.
Before publishing, the repository was scanned for high-confidence secrets and local absolute paths.
This project is open sourced under the MIT License.