SEOCHO
Ontology-aligned middleware for agentic graph memory.
SEOCHO sits between your agents and your graph database. You define the domain ontology once, then use the same contract to ingest documents, shape graph writes, generate schema-aware queries, and produce answers with traceable evidence.
In one sentence: SEOCHO turns your ontology into the operating contract for graph memory, retrieval, and agent answers.
Under the hood, indexing and query runs emit ontology signals that SEOCHO compiles into reviewable profiles, so an agent picks the right profile before routing, text-to-Cypher, reasoning, or answer synthesis.
flowchart LR
T["Notion / Slack / DataHub / Postgres / Neo4j / LangChain"] --> C["seocho connect"]
C --> D["Documents / JSONL"]
D --> I["SEOCHO index"]
O["Ontology: your schema"] --> I
O --> Q["SEOCHO query"]
I --> G[("Graph store")]
G --> Q
Q --> A["Grounded answer"]
Why Use It
Most agent memory systems start with chunks and prompts. SEOCHO starts with the schema you want the system to respect.
Use SEOCHO when you need:
- document ingestion that writes typed graph facts, not only vector chunks
- answers that follow your ontology instead of drifting into free text
- Cypher/query generation that knows the graph schema it is allowed to use
- a local SDK path for development and a runtime API path for deployment
- visible artifacts, traces, and graph writes that can be inspected later
SEOCHO is not a hosted memory black box. It is a Python SDK and runtime shell for teams that want to own the ontology, graph, and operational evidence.
What You Build
from seocho import Seocho, Ontology, NodeDef, RelDef, Property
ontology = Ontology(
name="work",
nodes={
"Person": NodeDef(properties={"name": Property(str, unique=True)}),
"Company": NodeDef(properties={"name": Property(str, unique=True)}),
},
relationships={
"WORKS_AT": RelDef(source="Person", target="Company"),
},
)
client = Seocho.local(ontology, llm="mara/MiniMax-M2.5")
client.add("Marie Curie worked at the University of Paris.")
print(client.ask("Where did Marie Curie work?"))
Export your provider key first — SEOCHO recommends MARA:
export MARA_API_KEY=.... Prefer another provider? Passllm="openai/gpt-4o"(ordeepseek/…,kimi/…) and export that provider's key instead.
That example creates a local ontology-aware graph memory. The same public facade can later point at a running SEOCHO runtime:
from seocho import Seocho
client = Seocho.remote("http://localhost:8001")
print(client.ask("What do we know about ACME?"))
Five-Minute Quickstart
Install the local SDK path:
uv pip install "seocho[local]"
Create and run a complete sample project:
seocho new hello-seocho
cd hello-seocho
export MARA_API_KEY=...
seocho run --dry-run
seocho run
seocho new writes a tiny ontology, documents, questions, and a runnable
seocho.run.yaml. seocho run indexes the documents into the embedded
LadybugDB graph, asks the questions, and writes runs/<name>-<timestamp>/
with both report.md and report.json.
From a repo checkout, prefix the CLI with uv run — uv resolves the project
environment and syncs dependencies for you, so there is no venv to activate.
If you installed SEOCHO into your own environment instead (uv pip install seocho), drop the prefix and call seocho … directly.
Want a domain-shaped example? The finance-compliance example ingests six short mock filings into an embedded local graph, then asks cross-document questions such as:
- Which regulations is Acme Financial Services subject to?
- What incidents have been reported?
- Which control evidence mitigates the incident?
export MARA_API_KEY=...
uv run python examples/finance-compliance/quickstart.py
Open examples/finance-compliance/ to inspect the ontology, sample documents, and script.
Prefer the smallest possible hello world? Use QUICKSTART.md.
Maintainers should use
Release And Community Operations
for release criteria and the GitHub/Ghost/Discord operating split, including
#seocho-updates, #seocho-project, and seocho-office-hours.
One YAML, one command
Skip Python entirely with a run spec — declare your ontology, documents, and questions in YAML, then run the whole index → query → report flow:
export MARA_API_KEY=...
uv run seocho run examples/run/quickstart.yaml
uv run seocho new hello-seocho writes a runnable project. uv run seocho run --init writes only a commented template for custom projects. To compare N
configurations (models, enforcement modes, agent patterns) in one table,
declare them as variants of a Jinja2 template and run uv run seocho sweep —
see docs/RUN_SPECS.md for templates, sweeps, per-phase
models, and ontology enforcement modes.
Bring data from the tools you already use
Materialize external sources into SEOCHO's normal indexing path:
seocho connect notion --data-source-id "$NOTION_DATA_SOURCE_ID" \
--output .seocho/connectors/notion.jsonl
seocho connect slack --channel "$SLACK_CHANNEL_ID" \
--output .seocho/connectors/slack.jsonl
seocho connect neo4j --database neo4j \
--output .seocho/connectors/neo4j.jsonl
Then set documents.path to that JSONL in seocho.run.yaml. LangChain and
LlamaIndex users can convert their existing Document objects with
seocho.connectors without adding a framework dependency to SEOCHO itself.
See docs/CONNECTORS.md and the copyable
connector starting point.
How SEOCHO Works
SEOCHO has three practical layers:
| Layer | Code | Job |
|---|---|---|
| Ontology | src/seocho/ontology*.py |
Defines node types, relationships, properties, constraints, and governance metadata. |
| Indexing | src/seocho/index/ |
Turns files or text into ontology-shaped graph payloads with validation and provenance. |
| Querying | src/seocho/query/ |
Builds schema-aware Cypher, retrieves graph evidence, and synthesizes answers. |
The runtime layer in runtime/ exposes the same contract over HTTP with policy
checks and workspace_id propagation. The legacy extraction/ package remains
as an active compatibility/batch-service surface while runtime ownership is
being staged into runtime/.
Choose A Mode
| Mode | Command or constructor | Best for |
|---|---|---|
| Local SDK | Seocho.local(ontology) |
First run, notebooks, local development, embedded LadybugDB. |
| Explicit graph backend | Seocho(ontology=..., graph_store=..., llm=...) |
Development against Neo4j/DozerDB or custom stores. |
| HTTP runtime client | Seocho.remote("http://localhost:8001") |
Consuming a running SEOCHO service. |
| Local platform stack | make setup-env && make up |
UI + API + DozerDB on one machine. |
Install choices. SEOCHO standardizes on uv for
project management; the uv pip forms below work in any environment, and pip
is a drop-in if you are not on uv.
| Install (uv) | Use it when |
|---|---|
uv pip install seocho |
You only need the HTTP client. |
uv pip install "seocho[local]" |
You want the local SDK engine, agents, and embedded graph path. |
uv pip install "seocho[ontology]" |
You need offline ontology governance tools. |
uv sync --extra dev (from a clone) |
You are contributing to this repository. |
What The Ontology Controls
| Stage | Effect |
|---|---|
| Ingestion | Entity and relationship types guide extraction. |
| Validation | Graph payloads are checked against schema and constraints. |
| Graph writes | Properties, uniqueness, provenance, and ontology context are recorded. |
| Querying | Cypher generation uses the active ontology and graph schema. |
| Runtime | Semantic artifacts, prompt context, traces, and workspace_id stay aligned. |
This is the core SEOCHO idea: one schema contract should govern what gets written, what gets retrieved, and what an agent is allowed to claim.
The Operating Layer (Governed Agents)
When an agent uses SEOCHO, the schema contract becomes an operating layer: one
Session object through which every subsystem an agent needs is a method, on one
governed path. The economics is the OS one — pay for rigor once at write time
(the ontology fixes each entity's canonical address), so every read is a cheap,
guaranteed, governed lookup.
with client.session("analyst", priority="high") as sess:
node = sess.resolve("Chipotle", label="Company", sector="restaurant") # memory: read-time interning
rows = sess.query("MATCH (n:Company) WHERE n._workspace_id = $workspace_id RETURN n") # scheduling + isolation
agent = sess.agent() # execution: a governed openai-agents Agent
sess.os_stats() # observability; sess.budget / sess.priority = resources
| Subsystem | Method / handle | What the governed path guarantees |
|---|---|---|
| Memory | sess.resolve() / add / ask |
Read-time interning reuses the write-time identity function — an exact, model-free, workspace-scoped address lookup. |
| Scheduling | sess.query() |
A shared admission gate bounds concurrency across all sessions of one layer. |
| Isolation | sess.query() |
The model's workspace_id is pinned server-side; reads that forget the tenant scope fail closed. |
| Execution | sess.agent() |
The agent's only graph access is this governed tool. |
| Resources | sess.budget / sess.priority |
A per-session token budget stops a run with a structured error, never a clipped answer. |
Every control is opt-in on the Seocho(...) constructor and off by default
(max_inflight, token_budget, reserved_for_high, …). Because all graph
access funnels through one call, the safety is structural — a prompt-injected
agent cannot route around it. Runnable offline walkthrough:
examples/agent_designs/os_unified_surface.py.
Design: ADR-0157 (surface),
ADR-0163 (control/data
plane split — where Bolt/LLM protocol optimization lives).
Runtime Stack
Run the local platform:
make setup-env
make up
Default local endpoints:
- UI:
http://localhost:8501 - API docs:
http://localhost:8001/docs - DozerDB browser:
http://localhost:7474
Runtime APIs live in runtime/. Shared SDK behavior lives in src/seocho/.
See docs/RUNTIME_DEPLOYMENT.md for the full
operator guide.
Examples
| Example | What it shows |
|---|---|
| examples/finance-compliance/ | A small end-to-end ontology, sample docs, local graph ingest, and Q&A. |
| examples/quickstart.ipynb | Notebook tour of ontology, indexing, provider setup, and tracing. |
| examples/bring_your_data.ipynb | Pattern for using your own files and ontology. |
| examples/finder/ | FinDER/FIBO tutorials for graph RAG, RDF vs LPG, and private tracing. |
Repository Map
| Path | Purpose |
|---|---|
src/seocho/ |
Python SDK and canonical engine modules. |
runtime/ |
Deployment shell, API wiring, runtime policy, memory service. |
extraction/ |
Active extraction service and compatibility shims. |
examples/ |
Runnable examples, notebooks, and small datasets. |
docs/ |
Architecture, workflow, runtime, and user guides. |
tests/seocho/ |
SDK and engine regression tests. |
extraction/tests/ |
Runtime/extraction compatibility tests. |
website/ |
Tracked Astro/Starlight docs site. |
For contributor placement rules, read docs/REPOSITORY_LAYOUT.md and docs/MODULE_OWNERSHIP_MAP.md.
Learn More
Same order as the docs onboarding path, top to bottom:
| Need | Start here |
|---|---|
| Why SEOCHO exists | docs/WHY_SEOCHO.md |
| First run | QUICKSTART.md |
| Beginner walkthrough | docs/BEGINNER_GUIDE.md |
| Python SDK details | docs/PYTHON_INTERFACE_QUICKSTART.md |
| Bring your own data | docs/APPLY_YOUR_DATA.md |
| Connect Notion, Slack, DataHub, Postgres, Neo4j/DozerDB, LangChain, or LlamaIndex | docs/CONNECTORS.md, examples/connectors/ |
| File/artifact locations | docs/FILES_AND_ARTIFACTS.md |
| Architecture overview | docs/ARCHITECTURE.md |
| Runtime internals | docs/RUNTIME_ARCHITECTURE.md |
| Query internals | docs/QUERY_ARCHITECTURE.md |
| Runtime deployment | docs/RUNTIME_DEPLOYMENT.md |
| Contributing | CONTRIBUTING.md |
| Maintainer workflow | docs/WORKFLOW.md |
| Issue and task system | docs/ISSUE_TASK_SYSTEM.md |
| Full docs site | seocho.blog |
FIBO Upstream Governance
SEOCHO keeps the official EDM Council FIBO repository as a pinned source
snapshot under third_party/fibo. Runtime code should not read the full FIBO
OWL/RDF tree directly; use compiled governance artifacts instead.
git submodule update --init --recursive
uv run python scripts/ontology/compile_fibo_snapshot.py \
--source third_party/fibo \
--curated-yaml-dir examples/finder/datasets/fibo_modules \
--modules BE,FBC,FND,SEC \
--out outputs/semantic_artifacts/fibo/latest
The compiler emits:
manifest.json— upstream commit, imports, module/resource counts, snapshot hashcatalog.json— runtime selector label/definition/IRI indexcompatibility_report.json— official FIBO vs SEOCHO curated LPG slice alignmentartifact_index.json— source snapshot vs runtime artifact contract
FIBO updates should be promoted only after compatibility review and benchmark gates over FinDER/private finance cases. Heavy OWL reasoning remains an offline governance concern; request paths consume the compiled catalog/artifact.
Development
git clone git@github.com:tteon/seocho.git
cd seocho
uv sync --extra dev
uv run python -m pytest tests/seocho/ -q
Before submitting broader changes, run:
bash scripts/ci/run_basic_ci.sh
License
MIT - see LICENSE.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file seocho-0.6.0.tar.gz.
File metadata
- Download URL: seocho-0.6.0.tar.gz
- Upload date:
- Size: 1.0 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.10.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b35a4220d80d0d41703aeedbea1d26a80d05e0db2700d58d854d707e893ba0c6
|
|
| MD5 |
03a00e272959dde2d816b384ceb1a0f3
|
|
| BLAKE2b-256 |
eb498b5c1c43d4974acb1a29cff6f1510db2f89fa0239cdb682588b35ce2c8ac
|
File details
Details for the file seocho-0.6.0-py3-none-any.whl.
File metadata
- Download URL: seocho-0.6.0-py3-none-any.whl
- Upload date:
- Size: 1.1 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.10.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6c5b0d15bd3d2e566176cdbfe3874d4319c58777217ccb3de65cedf4cae54e29
|
|
| MD5 |
be31b2ba9fc2977f31957aae8e897c85
|
|
| BLAKE2b-256 |
5985cb941aebc3380da7ed6874b5d38019b37e126e28a3c4b07b548119593f88
|