원클릭으로
arkeon-ingest
Initialize a repo as an Arkeon knowledge base and build a knowledge graph from its documents.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Initialize a repo as an Arkeon knowledge base and build a knowledge graph from its documents.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Start the local development environment (embedded Postgres + Meilisearch + API) and run e2e tests.
Build, test, version-bump, and publish the arkeon npm package from main.
Find and create relationships between entities across different spaces in the graph.
Fix a GitHub issue in an isolated worktree, test, commit, and open a PR.
Merge a GitHub PR, watch CI/CD pipeline, and check if publishable packages need a release.
Review docs for staleness after feature work. Compare each doc against the codebase, flag stale content, and update or delete.
| name | arkeon-ingest |
| description | Initialize a repo as an Arkeon knowledge base and build a knowledge graph from its documents. |
| disable-model-invocation | true |
| argument-hint | ["space-name"] |
| allowed-tools | Bash(npx arkeon *, arkeon *, ls *), Read, Glob, Grep, Write, Agent |
Initialize this repository as an Arkeon knowledge base and build a knowledge graph from its documents. Combines setup (space creation, file registration) with parallel extraction (sub-agents process document batches) and post-extraction consolidation.
npx arkeon --version
If this fails, tell the user:
Arkeon CLI is not installed. Run
npm install -g arkeonfirst.
Then stop.
Look for .arkeon/state.json in the repo root.
If it exists: Read it and report the current binding:
This repo is already bound to space {space_name} (
{space_id}) at{api_url}.
Then skip to step 4 (reconcile).
If the user passed --force as part of $ARGUMENTS: Re-initialize anyway (proceed to step 3).
Inspect the repo first. Use Glob to survey file types (**/*.md, **/*.txt, **/*.tex, etc.) and read the README if present.
Determine the space name:
$ARGUMENTS provides a name (not --force), use itRun:
npx arkeon init <space-name>
Parse the JSON output. Report: space name, space ID, API URL.
If the command fails (e.g., stack not running), report the error and suggest arkeon up first.
Check if an "ingestor" profile exists:
npx arkeon auth profiles
If no "ingestor" profile is listed, create one:
npx arkeon auth add ingestor --kind agent
Then ensure it's the active profile:
npx arkeon auth use ingestor
All subsequent commands automatically use the ingestor identity — no manual API key setup needed. The CLI resolves the active profile from .arkeon/state.json and the instance actor registry.
Important: The ingestor owns the space (it created the space during init), so it has full write access. Other actors need an explicit role grant via npx arkeon spaces grant --id {space_id} --actor-id {id} --role editor before they can write to the space. Always use the ingestor profile for ingestion.
Run the diff to see what needs syncing:
npx arkeon diff --json
Parse the JSON output. Based on the results:
New files (added):
npx arkeon add <file1> <file2> ...
Add files in batches if there are many (shell argument length limits). For directories, pass the directory path and arkeon will recurse.
Modified files:
npx arkeon add <modified-file1> <modified-file2> ...
These update the document entity in place (stable entity IDs).
Deleted files:
npx arkeon rm <deleted-file1> <deleted-file2> ...
These remove the document entity and cascade-delete any extracted entities.
Up to date: If the diff shows no changes, report "all documents are current."
Report what happened:
Setup complete.
- Space: {name} (
{id})- Documents: {N} added, {M} updated, {D} removed, {U} unchanged
After setup completes, ask the user:
{N} documents are ready. Start building the knowledge graph?
If the user declines, stop. If they agree (or didn't explicitly decline), proceed.
Before extracting, understand what already exists:
npx arkeon search query --q "*" --space-id {space_id} --limit 50
Note existing entity types, labels, and relationship predicates. This context informs extraction so you create consistent, connected graphs rather than isolated clusters.
If this is a fresh space with only document entities, note that and proceed — you're building from scratch.
Read a sample of the documents (3-5 files) to understand the corpus. Think about:
person, concept, work, event, place, organization. Add domain-specific types as needed (e.g., theorem, species, statute). Don't force types that don't fit — let the content guide you.mentions, authored, influenced_by, part_of, references, argues_for, argues_against, quotes. Add domain-specific predicates as needed.Report your extraction plan to the user before proceeding:
Extraction plan:
- Entity types I'll use: {list}
- Relationship predicates: {list}
- Estimated entities per document: {range}
- Documents to process: {N}
Persist the extraction schema to the space so the server-side pipeline and future runs use the same config:
npx arkeon spaces update {space_id} --properties '{"extraction":{"entity_types":[...your types...],"predicates":[...your predicates...],"label_instructions":"Use full formal names without titles or honorifics. Use official organization names.","context":"Brief description of this document collection."}}'
This is stored in space.properties.extraction and used by both the CLI skill and server-side knowledge pipeline for consistent extraction.
Retrieve all document entities in the space:
npx arkeon spaces list-entities {space_id} --limit 200
Parse the output. Each document has: id, properties.source_file, properties.content.
Using the document list from step 8, group documents into related batches for parallel processing. Batches should cluster documents that share:
Target 3-8 documents per batch. For small corpora (<6 documents), use a single batch.
Report the clustering plan:
Batch plan:
- Batch 1 ({theme}): {file1}, {file2}, ...
- Batch 2 ({theme}): {file3}, {file4}, ...
- ...
For each batch, spawn a sub-agent using the Agent tool. Run all batch agents in parallel (send all Agent tool calls in a single message).
Each sub-agent receives a prompt containing:
The sub-agent prompt must include the full extraction protocol (steps 10a-10f below) and all quality examples. The sub-agent has no memory of this skill's instructions — give it everything it needs to work independently.
Sub-agent failure handling: If a sub-agent fails or returns an error, report which batch failed and which documents were not processed. Do not retry automatically — report to the user and let them decide whether to re-run the failed batch.
For each document in the batch:
npx arkeon relationships list {doc_id} --direction in --predicate extracted_from --limit 1
If results exist, skip. Report: Skipping {source_file} — already ingested.
Before extracting from each document, search the graph aggressively. Read the document content first, identify 4-5 key terms (names, concepts, places), and search for each:
npx arkeon search query --q "{key_term}" --space-id {space_id} --limit 20
For each hit, note the entity ID, label, type, and description. These are your connection targets — you will link to them by ULID instead of creating duplicates.
Read existing entity descriptions carefully. Understanding what's already in the graph is how you build connections rather than isolated clusters.
Read the document content (from the entity's content property or from the file on disk). Identify:
Extraction quality standards:
Every entity description MUST:
BAD entity descriptions (do NOT produce these):
"Smith — person mentioned in the report" (says nothing about who Smith is)"Acme Corp — organization discussed in the filing" (just restates that it appeared)"Project Aurora — referenced in multiple sections" (no information at all)GOOD entity descriptions (aim for these):
"John Smith — lead architect at Acme Corp who designed the distributed caching layer that reduced p99 latency by 40%""Acme Corp — Series B enterprise SaaS company (founded 2019) specializing in real-time data infrastructure for financial services""Project Aurora — internal initiative to migrate Acme's monolith to a service mesh architecture, launched Q2 2024 after the March outage"Every relationship detail MUST:
BAD relationship details (do NOT produce these):
"Smith works at Acme Corp" (for a works_at predicate — this is tautological)"Aurora is part of Acme" (for part_of — adds nothing)"Smith is located in New York" (for located_in — just restates it)GOOD relationship details (aim for these):
"Smith joined Acme Corp in 2021 as a senior engineer, promoted to lead architect after the Aurora migration succeeded" (for works_at)"Aurora was Acme's highest-priority internal initiative, consuming 60% of the platform team's bandwidth for two quarters" (for part_of)"Smith relocated to Acme's New York headquarters in 2022 to lead the East Coast engineering hub" (for located_in)For every entity, provide at minimum:
type — the entity typelabel — a short, canonical namedescription — a 1-3 sentence description providing analytical contextFor every relationship, provide at minimum:
source and target — either @local_ref for new entities or a bare ULID for existing onespredicate — the relationship typedetail — a sentence explaining the specific connection with context that goes beyond the predicateUse the Write tool to create a JSON file with the ops envelope, then submit it:
Write to /tmp/arkeon-ops-{batch}-{doc}.json:
{
"format": "arke.ops/v1",
"defaults": {"upsert_on": ["label", "type"]},
"source": {"entity_id": "{doc_entity_id}"},
"ops": [
{"op": "entity", "ref": "@smith", "type": "person", "label": "John Smith", "description": "Lead architect at Acme Corp who designed the distributed caching layer that reduced p99 latency by 40%"},
{"op": "entity", "ref": "@aurora", "type": "project", "label": "Project Aurora", "description": "Internal initiative to migrate Acme's monolith to a service mesh architecture, launched Q2 2024"},
{"op": "relate", "source": "@smith", "target": "@aurora", "predicate": "leads", "detail": "Smith was appointed technical lead of Aurora after demonstrating the caching optimization proof-of-concept"},
{"op": "relate", "source": "@smith", "target": "01EXISTING_ULID", "predicate": "collaborated_with", "detail": "Smith and Chen co-authored the Aurora architecture RFC, with Smith focusing on the data layer and Chen on service discovery"}
]
}
Then submit:
npx arkeon ingest post-ops --data @/tmp/arkeon-ops-{batch}-{doc}.json
Key rules:
upsert_on: ["label", "type"] prevents duplicates automatically. If an entity with the same label and type already exists in the space, its properties are shallow-merged (new values win) instead of creating a duplicate. This means you do NOT need to search for an entity before creating it — just create it and upsert handles the rest. You still use bare ULIDs when you specifically want to create a relationship to a known existing entity.source.entity_id on the envelope creates extracted_from edges automatically — never create these manually.defaults.space_id is auto-injected by the CLI if configured — you don't need to set it.@local_ref for new entities defined in this batch.read_level or write_level — defaults are applied automatically.action: "created" or action: "updated" for each entity so you can track what happened.After extracting from each document, check if any existing entities (found in step 10b) should have their descriptions enriched with new information from this document.
If the current document reveals new information about an existing entity that isn't in its current description:
ver: npx arkeon entities get {id}npx arkeon entities update {id} --properties '{"description":"enriched text"}' --ver {ver}Version conflict handling: Multiple sub-agents may try to enrich the same entity concurrently. If the update fails with a version conflict (409), re-fetch the entity to get the latest ver and description, re-synthesize incorporating what the other sub-agent added, and retry the update. One retry is sufficient — if it fails again, skip and let consolidation (step 11b) handle it.
This is critical — entity descriptions should grow richer as more documents are processed, not stay frozen at first-extraction.
After each document, report:
{source_file}: {N} entities, {M} relationships created, {E} existing entities enriched.
After the entire batch is done, report a batch summary.
After ALL sub-agents have completed, run a consolidation pass over the full graph. This catches cross-type duplicates and connections that individual sub-agents couldn't see.
Note: same-label+type duplicates within the space are already prevented by upsert_on during extraction. This step only catches cross-type duplicates (e.g., "Atlas" created as both "deity" and "titan") or near-duplicates with slightly different labels.
Search for entities with similar or identical labels across different types:
npx arkeon search query --q "{entity_label}" --space-id {space_id} --limit 20
Look for cross-type duplicates (same entity created under different types by different sub-agents). When found:
npx arkeon entities merge {keep_id} {duplicate_id}
Prefer keeping the entity with the richer description.
For entities that appear across multiple documents (high relationship count), synthesize a comprehensive description drawing on all connected documents:
npx arkeon relationships list {id} --limit 50npx arkeon entities update {id} --properties '{"description":"synthesized text"}' --ver {ver}Search for relationships that span batch boundaries. Look for:
For each discovered connection, create relationship ops:
Write to /tmp/arkeon-ops-consolidation.json:
{
"format": "arke.ops/v1",
"defaults": {},
"ops": [
{"op": "relate", "source": "01ENTITY_A", "target": "01ENTITY_B", "predicate": "collaborated_with", "detail": "Both served on the same committee during 2024, though documented in separate report series"}
]
}
npx arkeon ingest post-ops --data @/tmp/arkeon-ops-consolidation.json
After consolidation, summarize:
Ingest complete.
- Documents processed: {N} of {total}
- Documents skipped (already ingested): {S}
- Batches: {B} (processed in parallel)
- Entities created: {E}
- Relationships created: {R}
- Entities merged (deduplication): {D}
- Entities enriched (cross-document): {X}
- Cross-batch connections: {C}
Run
npx arkeon search query --q "{topic}" --space-id {space_id}to explore the graph.Open the explorer to visualize what was built:
npx arkeon statusand open theexplorer_urlin your browser.