title: GraphEmbed CLI Tool Specification
version: 1.0.0
description: "A Rust-based CLI tool for generating text embeddings and
managing knowledge graphs"
GraphEmbed CLI Tool
GraphEmbed CLI is a command-line application written in Rust that
integrates text embedding generation with knowledge graph management. It
allows users to create or import knowledge graphs, generate or ingest
vector embeddings for text data, and manipulate the graph's entities and
relationships. The tool supports standard graph data formats (JSON-LD,
RDF/Turtle, CSV) and offers querying and basic visualization
capabilities. This document provides an overview of the tool's features,
usage instructions, workflow, examples, and references to relevant
resources.
Instructions
Installation & Setup: To install GraphEmbed, ensure you have Rust
installed (for source builds) or use a prebuilt binary if provided. You
can compile from source via Cargo:
$ cargo install graphembed-cli
This will download and build the CLI. After installation, the command
graphembed should be available. For help on any command, run
graphembed help or graphembed <command> --help.
Command Structure: GraphEmbed uses subcommands for different
functionalities. General usage follows:
graphembed <command> [OPTIONS] [ARGS...]
Key commands include:
embed -- Generate embeddings from input text using a chosen model.
import -- Load a knowledge graph from a file (JSON-LD, Turtle, RDF,
or CSV).
export -- Save the current knowledge graph to a file in a specified
format.
add-entity -- Create a new entity (node) in the graph.
add-rel -- Create a relationship (edge) between two entities.
update -- Modify an existing entity or relationship.
delete -- Remove an entity or relationship from the graph.
query -- Query the graph for specific patterns or run a SPARQL query
(if supported).
visualize -- Generate a simple visual representation of the graph.
Embedding Generation: The embed command produces a numerical
vector (embedding) from a given text input. By default, GraphEmbed
leverages Rust-compatible NLP models (Transformer-based) for embeddings.
You may specify an embedding model with -m/--model. For example,
all-MiniLM-L6-v2 (a popular SentenceTransformer model) can be used if
available. Under the hood, the tool uses Hugging Face Transformers
via Rust libraries to compute embeddings. This means you can use
pre-trained models like BERT, MiniLM, etc., without needing Python. The
first time you request a particular model, the tool will download the
model weights if not already present. Ensure you have an internet
connection for model downloads or pre-download the model files. If no
model is specified, a default small embedding model is used.
- Model backends: GraphEmbed supports multiple backend frameworks for
embeddings. It can use Rust-BERT (which wraps PyTorch models with
the
tch crate) for many Hugging Face models, or an ONNX Runtime
backend for sentence transformers if compiled with the onnx feature
(using the ort crate). You can choose the backend via features or
CLI flags (e.g., --backend torch vs --backend onnx). The tool
ensures that generating an embedding requires only the text input --
the output is a vector of floats printed to stdout or saved to a file
if specified.
Ingesting Precomputed Vectors: In addition to generating embeddings,
you can ingest precomputed embedding vectors into the system. The
import command will automatically detect if a given file is an
embedding file based on format (for example, a CSV of vectors or a JSON
array). Alternatively, a dedicated subcommand ingest-vec may be
provided (check graphembed help for the exact name if available).
Typically, you would prepare a CSV where each line contains an entity
identifier and a list of numerical components of the embedding.
GraphEmbed will read this and attach each vector to the corresponding
entity in the knowledge graph (creating the entity if it doesn't exist).
For example, a CSV with header entity_id,dim1,dim2,... can be
ingested. Ensure that the entity identifiers match those used in the
graph (case-sensitive). After ingestion, the embedding becomes a
property of the entity in the graph (accessible for querying or
similarity operations in future versions).
Knowledge Graph Import/Export: The import and export commands
handle reading from or writing to various knowledge graph formats: -
JSON-LD (.jsonld) -- A JSON-based linked data format. The tool can
parse JSON-LD files to create the internal graph. It will interpret
@context, @id, and other JSON-LD keywords properly, so imported data
retains semantic meaning. When exporting to JSON-LD, GraphEmbed will
produce a context and list of triples in JSON-LD structure. -
RDF/Turtle (.ttl or .rdf) -- The Turtle syntax (and generic RDF/XML
if .rdf is provided) is supported. Import will parse triples and build
the graph accordingly. Export will write out triples with prefixes and
IRIs as needed in Turtle format. - CSV (.csv) -- For simplicity,
GraphEmbed expects CSV files to represent triples or edges. Each row
should contain at least three columns: subject, predicate, object
(optionally a fourth for a literal type or language tag if needed). A
header row can be present with names like subject,predicate,object. If
no header is present, the tool assumes each line is a triple in order.
CSV import is useful for quickly loading edge lists or simple knowledge
graphs from spreadsheets. Exporting to CSV will produce a triple list in
a similar fashion (one triple per line). - The import command tries to
auto-detect format from file extension. You can override by specifying
--format jsonld|turtle|csv|rdf if needed. The tool uses robust parsers
under the hood (e.g., an RDF library for Turtle/JSON-LD) and will report
any parse errors with line numbers for easier debugging of file format
issues.
Entities and Relationships (CRUD): GraphEmbed maintains an internal
graph data structure where entities are nodes identified by unique
IDs or IRIs, and relationships are edges (typically labeled with a
predicate/property name). Using CLI commands, you can create, update,
and delete these: - Creating Entities: Use add-entity with a
unique identifier or label. For RDF-based graphs, this might create a
new URI (you can specify a CURIE or a full URI with --id, or let the
tool generate a blank node or namespaced URI). You can also attach
initial data like a type or properties via options. For example,
graphembed add-entity "Alice" --type Person might create an entity
with label "Alice" of type Person. - Creating Relationships: Use
add-rel (or add-relationship) specifying a subject, predicate, and
object. For instance, graphembed add-rel "Alice" "knows" "Bob" would
add a relationship stating Alice knows Bob. Under the hood, if "Alice"
and "Bob" are label identifiers for entities, the tool will map them to
their internal IDs (or create them if they didn't exist). Predicates can
be given as simple labels or as full URIs; the tool may map common
relation names to a default vocabulary or allow a --uri option to
specify an exact property URI. - Updating: The update command
allows changing an entity's attributes or a relationship's
predicate/target. For example, you might update an entity's name, or
attach a new attribute (like adding an age property to a Person). In
an RDF graph context, updating might just mean adding or replacing
certain triples. The CLI might provide flags like
--set-property name="Alice A." or similar to modify data.
Relationships could be updated by referencing them (e.g., by an ID or by
the subject-predicate-object triple pattern). - Deleting: Use
delete with an identifier. You can delete an entity (which will also
remove any relationships involving it) or delete a specific relationship
by providing its triple components. For example,
graphembed delete entity "Alice" removes the entity Alice, while
graphembed delete rel "Alice" "knows" "Bob" removes only that edge.
The tool will prompt for confirmation if multiple triples are affected
(or you can use --force for non-interactive deletion).
Querying the Graph: The query command lets you retrieve
information from the knowledge graph. By default, GraphEmbed supports
simple pattern queries and, if compiled with the SPARQL feature, full
SPARQL queries: - Pattern queries: You can query by providing partial
triple patterns. For example, graphembed query "Alice -> ?p -> ?o"
could list all predicates and objects that Alice is connected to. Using
? indicates a wildcard (variable) for any matching node or value.
Similarly, ?s -> knows -> Bob would find all subjects that have a
"knows" relationship to Bob. - SPARQL queries: If the tool is built
with SPARQL support (using an embedded engine), you can supply a SPARQL
query string:
graphembed query "SELECT ?friend WHERE { <Alice> <knows> ?friend }".
The query should be enclosed in quotes. Results will be printed in a
simple table format or as JSON, depending on flags (e.g.,
--format csv|json for result output). Keep in mind that full SPARQL
support may require an additional dependency and can be toggled via a
feature flag at compile time. If SPARQL is not available, the tool will
inform you or fall back to basic queries. - Performance: For larger
graphs, consider using indexing or persistent storage. GraphEmbed
primarily holds the graph in memory. If you need to run complex queries
on very large datasets, integration with a dedicated graph database
(like an external SPARQL endpoint or property graph DB) might be
preferable. However, for moderate-sized knowledge graphs, the built-in
query should suffice.
Visualization: The visualize command produces a human-readable
graph representation. This can help you quickly understand the structure
of the knowledge graph: - By default, visualize will output a Graphviz
DOT format text to stdout or to a file (if -o graph.dot is specified).
You can then use Graphviz tools (e.g.,
dot -Tpng graph.dot -o graph.png) to generate an image. If Graphviz is
installed, you might also use a convenience flag like --png to
directly produce an image file. - The visualization simplifies node and
edge labels for clarity. Each entity will appear as a node (often
labeled by its name or ID), and each relationship appears as an arrow
with the predicate label. Literal values attached to entities (like a
name or other data) might appear as separate nodes or annotations. - For
a very large graph, you can limit the visualization to a subgraph (e.g.,
--focus Alice to show Alice and directly connected nodes only). This
prevents an overly cluttered diagram. Alternatively, use query commands
to filter what you visualize. - Example: if you run
graphembed visualize -o family.dot, and your graph contains people and
family relationships, the resulting DOT file can be rendered to show a
network of those individuals connected by edges like "parentOf",
"siblingOf", etc. This gives a quick insight without manually reading
triples or JSON.
General Guidelines: When using GraphEmbed: - Naming Conventions:
Entities can be referenced by labels or IDs. If your data is RDF-based,
consider using consistent prefixes (you can set a default base URI via a
config or environment variable). For example, if you have a base
http://example.com/ns#, an entity with label Alice might be expanded
to <http://example.com/ns#Alice>. The CLI tries to manage this
transparently. Avoid using spaces in identifiers unless you quote them
properly in the shell. - File Handling: Always specify the correct
file paths for import/export. The tool will not overwrite an existing
file on export unless --overwrite is provided. On import, the graph in
memory is appended to by default; use --clear before import if you
want to replace the current graph. - Memory and Performance:
GraphEmbed loads entire files into memory. Very large knowledge graphs
(e.g., millions of triples) might cause high memory usage. In such
cases, consider splitting data or using an external database. For
embeddings, generating vectors is computationally intensive; model
loading happens once per session for reuse, but each embed call will
use CPU (or GPU if supported by the backend) to compute the vector.
Batch embedding is supported via an input file or pipe to avoid
reloading the model repeatedly. - Extensibility: The CLI is designed
to be extensible. You can configure it to use different embedding models
or graph stores by editing a config file (usually
~/.graphembed/config.toml) or using environment variables. For
example, GRAPHEMBED_MODEL_DIR can point to a directory of local models
to avoid downloads. Future plugins might allow custom relationship types
or integration with external vector databases for similarity search.
Workflow
Using GraphEmbed involves a series of steps from setup to results. Below
is a typical workflow for setting up the tool and utilizing its
features:
- Setup and Installation: Install the GraphEmbed CLI tool using
Cargo or download the binary. Ensure that all dependencies (Rust
standard libraries, any needed system libraries for ML like Intel
MKL if using CPU acceleration for embeddings) are in place. For
example, on Linux you might need
libtorch if using the Torch
backend, but the Rust crate typically includes it or downloads it
automatically.
- Initialize a Knowledge Graph: Start a new knowledge graph or
import an existing one. For a new graph, you can skip directly to
adding entities. To import, run
graphembed import data.jsonld
(replace with your file). Verify that the CLI reports the number of
triples or nodes loaded. If you have multiple files, import them one
by one (the graph will accumulate data).
- Generate or Ingest Embeddings: If you have text data that needs
embeddings, use the
embed command. For a single piece of text:
graphembed embed "Your text here..." > vec.json. This will output
the embedding vector (e.g., as a JSON array or a space-separated
list). For batch processing, you could pass a file:
graphembed embed --input texts.txt --output vectors.csv. This
reads multiple lines of text from texts.txt and writes
corresponding vectors (one per line) to a CSV. If you already have
embeddings (from Python or another source), prepare them in a CSV or
JSON format and use graphembed import vectors.csv to ingest. After
this step, your graph may have entities with associated embedding
vectors.
- Add Entities and Relationships: Use
add-entity and add-rel
commands to build or extend your knowledge graph. For instance,
after importing base data, you might want to add a new entity that
wasn't in the original file:
graphembed add-entity "Carol" --type Person. Then link Carol to
existing entities: graphembed add-rel "Carol" "knows" "Alice".
Continue to use add commands for any new knowledge you want to
capture. Each operation will update the in-memory graph and confirm
the addition.
- Update and Delete Operations: If you discover mistakes or need
to change the graph, use
update or delete. For example, if
Carol's name was misspelled,
graphembed update entity "Coral" --rename "Carol" (or similar)
could fix it. To remove a relationship,
graphembed delete rel "Carol" "knows" "Alice" will delete that
edge. Always double-check with a query or visualize after
modifications to ensure the graph is in the desired state.
- Query the Graph: Now that your graph is populated and possibly
enriched with embeddings, retrieve information using queries. For
example, to find all friends of Alice:
graphembed query "Alice -> knows -> ?friend". The tool will output
matches, e.g., "friend = Bob, Carol". If SPARQL is enabled and you
prefer that, use a full SPARQL query for more complex patterns or
filtering. At this stage, you could also perform semantic similarity
by combining embeddings and structure: while GraphEmbed doesn't
directly do vector similarity queries in this version, you can
manually take two entity embeddings (via embed or from stored
data) and compute cosine similarity using an external tool or a
small script.
- Visualize (Optional): For a quick visual check of part of the
graph, run
graphembed visualize --focus Alice -o subgraph.dot.
This generates a DOT file for Alice and her neighbors. Run Graphviz
or an online DOT viewer to see the graph image. This step helps in
presentations or just sanity-checking the relationships.
- Export the Graph: Once you are satisfied with the graph's
content, save it. Use
graphembed export -f turtle -o output.ttl to
get a Turtle file or -f jsonld for JSON-LD. The exported file can
be shared, loaded into other tools, or kept as a persistent store of
the knowledge graph. If your workflow is iterative, you might export
after each session as a backup.
- Re-running and Automation: The above steps can be repeated or
scripted. Because GraphEmbed is a CLI, you can include it in shell
scripts or integrate with other processes. For example, you could
have a nightly job that regenerates embeddings for new text and
updates a knowledge graph, using a series of
graphembed commands
in sequence. The tool's output is designed to be parseable (CSV,
JSON, or plain text options for commands) so it can fit into larger
data pipelines.
By following this workflow, you can build a rich knowledge graph that
combines symbolic relationships with vector-based semantic information,
all from the command line. Adjust the steps as needed for your specific
use case (for instance, skip embedding generation if you only need the
graph structure, or vice versa).
Examples
Below are several usage examples demonstrating GraphEmbed's CLI commands
and their outputs. These examples assume you have a graph about people
and their relationships, as well as some textual data to embed.
- Generating a Text Embedding: Use the
embed command with a model
to convert text into an embedding vector.
- $ graphembed embed -m all-MiniLM-L6-v2 "Rust is a systems programming language."
[0.102, 0.340, -0.215, ..., 0.877]
Output: A JSON-like array of floating-point numbers is printed to
stdout (here truncated for brevity). Each number represents a
dimension in the embedding space (e.g., 384 dimensions for MiniLM).
You can redirect this output to a file or parse it in a script. If the
model isn't specified, the default model's embedding is returned. The
first run may take a moment to load the model; subsequent calls will
be faster.
- Importing a Knowledge Graph from JSON-LD: Suppose you have a file
people.jsonld that contains persons and relationships in JSON-LD
format.
- $ graphembed import people.jsonld
Loaded graph with 50 entities, 120 relationships.
Output: The tool confirms the number of entities and relationships
loaded. Internally, each
@id in JSON-LD becomes an entity node, and
each relationship (triple) is stored. If the JSON-LD had context
definitions for terms like "name" or "knows", those are preserved.
After import, the graph is ready for queries or edits.
- Exporting the Graph to Turtle: To save the current graph as an RDF
Turtle file:
$ graphembed export -f turtle -o people.ttl
Exported graph to people.ttl (120 triples).
Output: The graph is written to people.ttl. The CLI reports the
count of triples. In the Turtle file, you'll find prefix declarations
(if any) followed by triples such as:
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
@prefix ex: <http://example.com/ns#> .
ex:Alice foaf:knows ex:Bob, ex:Carol ;
foaf:name "Alice" .
This indicates Alice knows Bob and Carol, and has a name "Alice". The
export format is interoperable with other RDF tools.
- Adding Entities and Relationships via CLI: If you want to extend
the graph with new data:
- $ graphembed add-entity "Dave" --type Person --id ex:Dave
Created entity 'Dave' (ex:Dave) of type Person.
$ graphembed add-rel "Dave" "knows" "Alice"
Added relationship: Dave --knows--> Alice
Output: The first command adds a new entity named "Dave". We
explicitly provided an ID
ex:Dave in the example (using a prefix
ex defined perhaps from the imported data). The tool confirms
creation. The second command adds a relationship indicating Dave knows
Alice. The CLI confirms the edge addition in a readable format. If
"Alice" was not already in the graph, it would either create a new
node or warn; in this case Alice exists from prior data.
- Updating an Entity's Property: You can add or change properties on
an entity. For example:
- $ graphembed update entity "Dave" --set "age=30"
Updated entity 'Dave': set age = "30"^^http://www.w3.org/2001/XMLSchema#integer.
Output: This sets Dave's age to 30 (the CLI infers it as an integer
literal in RDF terms). The confirmation shows the RDF literal with
datatype. If the property didn't exist, it's added; if it existed,
it's updated to the new value. You could similarly update a
relationship (e.g., change its predicate or qualifiers) with the
appropriate syntax.
- Deleting a Relationship: Remove an edge from the graph:
- $ graphembed delete rel "Dave" "knows" "Alice"
Relationship 'Dave knows Alice' deleted.
Output: The specified triple is removed. If there were multiple
triples with Dave as subject and Alice as object under different
predicates, only the one with predicate "knows" is removed. Deleting
an entity (with
delete entity) would remove all triples involving
that entity.
- Querying for Connections: Retrieve information with a simple
query.
$ graphembed query "Alice -> knows -> ?who"
Alice knows Bob
Alice knows Carol
Alice knows Dave
Output: The query finds all ?who such that Alice knows them. The
results list each matching triple (subject Alice, predicate knows,
object being each result). In this case, Alice knows Bob, Carol, and
Dave. The output format is a straightforward listing; you can add
--format csv to get:
Alice,knows,Bob
Alice,knows,Carol
Alice,knows,Dave
which might be easier for scripts to parse. For more complex querying,
you could enable SPARQL and do something like:
$ graphembed query "SELECT ?p ?o WHERE { ex:Alice ?p ?o }"
resulting in a table of all predicates and objects for Alice.
- Visualizing a Subgraph: To generate a quick visualization, focus
on a subset of the graph.
$ graphembed visualize --focus Alice -o alice.dot && dot -Tpng alice.dot -o alice.png
Output: The first part outputs a DOT file centered on Alice. Suppose
Alice is connected to Bob, Carol, and Dave as in our graph. The DOT
file will contain nodes for each person and arrows labeled "knows"
pointing out of Alice to the others. After running Graphviz (dot),
the resulting alice.png might show something like: Alice → Bob,
Alice → Carol, Alice → Dave (with arrows). Each node might be labeled
with the person's name, and additional properties (like age) could
appear as annotations or separate nodes depending on the visualization
mode. This provides a quick visual check that our data is correct
(e.g., we see Dave connected to Alice as expected from the earlier
commands).
These examples illustrate typical interactions with GraphEmbed. By
combining these commands, you can script complex operations -- for
instance, automatically embedding new text data and inserting it into
the graph, or exporting subsets of the graph for different audiences.
The CLI's consistent format and use of standard data representations
make it a flexible tool in a larger pipeline.
References
- Rust-BERT (HF Transformers in Rust): rust-bert
crate -- A Rust library that
provides ready-to-use NLP transformer models (BERT, DistilBERT, etc.)
and pipelines for tasks like embeddings, using the
tch (PyTorch)
backend. Enables generating sentence embeddings with pre-trained
Hugging Face models in Rust.
- Sentence Transformers in Rust: sbert
crate -- A community port of
SentenceTransformers to Rust, built on rust-bert and tch. Supports
popular sentence embedding models for semantic search. This can be
used as an alternative embedding generation backend in GraphEmbed.
- ONNX Runtime for Rust: ort crate
-- Rust bindings for ONNX Runtime, allowing high-performance inference
of ONNX models. Useful for running SentenceTransformer models exported
to ONNX, often yielding faster or lighter-weight embedding generation.
GraphEmbed can leverage this for embedding if configured with the onnx
feature.
- Hugging Face Candle: candle
library -- A minimalist Rust
deep learning framework by Hugging Face. Candle enables running
transformer models fully in Rust (no Python). It's an alternative
backend that GraphEmbed could use for embedding generation, especially
in offline or WASM scenarios.
- Knowledge Graph RDF Toolkit (Sophia): Sophia
crate -- A comprehensive toolkit for
RDF and Linked Data in Rust. Supports parsing and writing of multiple
RDF serialization formats (Turtle, N-Triples, JSON-LD via an
extension) and provides in-memory graph management. GraphEmbed uses
libraries like Sophia to handle JSON-LD and Turtle import/export and
may use its graph interfaces for manipulating triples.
- RDF Graph Library: rdf (RDF.rs) --
A Rust framework for RDF graphs. It provides data structures for
triples, graph storage, Turtle parsing, and basic SPARQL querying.
This or similar libraries serve as the foundation for GraphEmbed's
knowledge graph representation and querying capabilities.
- Oxigraph (SPARQL Database): Oxigraph
project -- An efficient Rust graph
database with full SPARQL 1.1 support and persistent storage based on
RocksDB. While GraphEmbed is in-memory, Oxigraph demonstrates how
SPARQL queries and persistence can be achieved in Rust. GraphEmbed's
optional SPARQL querying is inspired by Oxigraph, and advanced users
might use Oxigraph directly for heavy-duty query needs.
- Graph Visualization: Graphviz DOT
crate -- A Rust library for
generating Graphviz DOT graph descriptions. GraphEmbed uses this or a
similar output method (potentially via
petgraph's dot exporters) to
produce visualizable graph representations. The DOT format can be
rendered by Graphviz tools to images.
- CLI Argument Parser: Clap crate
-- A widely used Rust library for parsing command-line arguments.
GraphEmbed employs Clap to define subcommands (
embed, import,
etc.), options (like --model, --format), and help messages,
ensuring a consistent and user-friendly CLI interface.
- JSON-LD Processing: json-ld
crate -- A Rust implementation for
JSON-LD parsing and serialization. This is used under the hood to
correctly handle JSON-LD context and linking semantics when importing
or exporting JSON-LD files in GraphEmbed.
Each of these resources contributes to GraphEmbed's functionality. For
further information, refer to the respective documentation of these
crates. By building on established libraries, GraphEmbed ensures
reliability and leverages community support for tasks like machine
learning inference and semantic data handling.
1---2name: rust-embedding3description: ------------------------------------------------------------------------4---5
6------------------------------------------------------------------------
7
8title: GraphEmbed CLI Tool Specification\
9version: 1.0.0\
10description: \"A Rust-based CLI tool for generating text embeddings and
11managing knowledge graphs\"
12
13------------------------------------------------------------------------
14
15# GraphEmbed CLI Tool
16
17GraphEmbed CLI is a command-line application written in Rust that
18integrates text embedding generation with knowledge graph management. It
19allows users to create or import knowledge graphs, generate or ingest
20vector embeddings for text data, and manipulate the graph's entities and
21relationships. The tool supports standard graph data formats (JSON-LD,
22RDF/Turtle, CSV) and offers querying and basic visualization
23capabilities. This document provides an overview of the tool's features,
24usage instructions, workflow, examples, and references to relevant
25resources.
26
27## Instructions
28
29**Installation & Setup:** To install GraphEmbed, ensure you have Rust
30installed (for source builds) or use a prebuilt binary if provided. You
31can compile from source via Cargo:
32
33 $ cargo install graphembed-cli
34
35This will download and build the CLI. After installation, the command
36`graphembed` should be available. For help on any command, run
37`graphembed help` or `graphembed <command> --help`.
38
39**Command Structure:** GraphEmbed uses subcommands for different
40functionalities. General usage follows:
41
42 graphembed <command> [OPTIONS] [ARGS...]
43
44Key commands include:
45
46- `embed` -- Generate embeddings from input text using a chosen model.
47- `import` -- Load a knowledge graph from a file (JSON-LD, Turtle, RDF,
48 or CSV).
49- `export` -- Save the current knowledge graph to a file in a specified
50 format.
51- `add-entity` -- Create a new entity (node) in the graph.
52- `add-rel` -- Create a relationship (edge) between two entities.
53- `update` -- Modify an existing entity or relationship.
54- `delete` -- Remove an entity or relationship from the graph.
55- `query` -- Query the graph for specific patterns or run a SPARQL query
56 (if supported).
57- `visualize` -- Generate a simple visual representation of the graph.
58
59**Embedding Generation:** The `embed` command produces a numerical
60vector (embedding) from a given text input. By default, GraphEmbed
61leverages Rust-compatible NLP models (Transformer-based) for embeddings.
62You may specify an embedding model with `-m/--model`. For example,
63`all-MiniLM-L6-v2` (a popular SentenceTransformer model) can be used if
64available. Under the hood, the tool uses **Hugging Face Transformers**
65via Rust libraries to compute embeddings. This means you can use
66pre-trained models like BERT, MiniLM, etc., without needing Python. The
67first time you request a particular model, the tool will download the
68model weights if not already present. Ensure you have an internet
69connection for model downloads or pre-download the model files. If no
70model is specified, a default small embedding model is used.
71
72- *Model backends:* GraphEmbed supports multiple backend frameworks for
73 embeddings. It can use **Rust-BERT** (which wraps PyTorch models with
74 the `tch` crate) for many Hugging Face models, or an **ONNX Runtime**
75 backend for sentence transformers if compiled with the `onnx` feature
76 (using the `ort` crate). You can choose the backend via features or
77 CLI flags (e.g., `--backend torch` vs `--backend onnx`). The tool
78 ensures that generating an embedding requires only the text input --
79 the output is a vector of floats printed to stdout or saved to a file
80 if specified.
81
82**Ingesting Precomputed Vectors:** In addition to generating embeddings,
83you can ingest precomputed embedding vectors into the system. The
84`import` command will automatically detect if a given file is an
85embedding file based on format (for example, a CSV of vectors or a JSON
86array). Alternatively, a dedicated subcommand `ingest-vec` may be
87provided (check `graphembed help` for the exact name if available).
88Typically, you would prepare a CSV where each line contains an entity
89identifier and a list of numerical components of the embedding.
90GraphEmbed will read this and attach each vector to the corresponding
91entity in the knowledge graph (creating the entity if it doesn't exist).
92For example, a CSV with header `entity_id,dim1,dim2,...` can be
93ingested. Ensure that the entity identifiers match those used in the
94graph (case-sensitive). After ingestion, the embedding becomes a
95property of the entity in the graph (accessible for querying or
96similarity operations in future versions).
97
98**Knowledge Graph Import/Export:** The `import` and `export` commands
99handle reading from or writing to various knowledge graph formats: -
100**JSON-LD (.jsonld)** -- A JSON-based linked data format. The tool can
101parse JSON-LD files to create the internal graph. It will interpret
102`@context`, `@id`, and other JSON-LD keywords properly, so imported data
103retains semantic meaning. When exporting to JSON-LD, GraphEmbed will
104produce a context and list of triples in JSON-LD structure. -
105**RDF/Turtle (.ttl or .rdf)** -- The Turtle syntax (and generic RDF/XML
106if `.rdf` is provided) is supported. Import will parse triples and build
107the graph accordingly. Export will write out triples with prefixes and
108IRIs as needed in Turtle format. - **CSV (.csv)** -- For simplicity,
109GraphEmbed expects CSV files to represent triples or edges. Each row
110should contain at least three columns: subject, predicate, object
111(optionally a fourth for a literal type or language tag if needed). A
112header row can be present with names like `subject,predicate,object`. If
113no header is present, the tool assumes each line is a triple in order.
114CSV import is useful for quickly loading edge lists or simple knowledge
115graphs from spreadsheets. Exporting to CSV will produce a triple list in
116a similar fashion (one triple per line). - The import command tries to
117auto-detect format from file extension. You can override by specifying
118`--format jsonld|turtle|csv|rdf` if needed. The tool uses robust parsers
119under the hood (e.g., an RDF library for Turtle/JSON-LD) and will report
120any parse errors with line numbers for easier debugging of file format
121issues.
122
123**Entities and Relationships (CRUD):** GraphEmbed maintains an internal
124graph data structure where **entities** are nodes identified by unique
125IDs or IRIs, and **relationships** are edges (typically labeled with a
126predicate/property name). Using CLI commands, you can **create, update,
127and delete** these: - **Creating Entities:** Use `add-entity` with a
128unique identifier or label. For RDF-based graphs, this might create a
129new URI (you can specify a CURIE or a full URI with `--id`, or let the
130tool generate a blank node or namespaced URI). You can also attach
131initial data like a type or properties via options. For example,
132`graphembed add-entity "Alice" --type Person` might create an entity
133with label "Alice" of type Person. - **Creating Relationships:** Use
134`add-rel` (or `add-relationship`) specifying a subject, predicate, and
135object. For instance, `graphembed add-rel "Alice" "knows" "Bob"` would
136add a relationship stating Alice knows Bob. Under the hood, if "Alice"
137and "Bob" are label identifiers for entities, the tool will map them to
138their internal IDs (or create them if they didn't exist). Predicates can
139be given as simple labels or as full URIs; the tool may map common
140relation names to a default vocabulary or allow a `--uri` option to
141specify an exact property URI. - **Updating:** The `update` command
142allows changing an entity's attributes or a relationship's
143predicate/target. For example, you might update an entity's name, or
144attach a new attribute (like adding an `age` property to a Person). In
145an RDF graph context, updating might just mean adding or replacing
146certain triples. The CLI might provide flags like
147`--set-property name="Alice A."` or similar to modify data.
148Relationships could be updated by referencing them (e.g., by an ID or by
149the subject-predicate-object triple pattern). - **Deleting:** Use
150`delete` with an identifier. You can delete an entity (which will also
151remove any relationships involving it) or delete a specific relationship
152by providing its triple components. For example,
153`graphembed delete entity "Alice"` removes the entity Alice, while
154`graphembed delete rel "Alice" "knows" "Bob"` removes only that edge.
155The tool will prompt for confirmation if multiple triples are affected
156(or you can use `--force` for non-interactive deletion).
157
158**Querying the Graph:** The `query` command lets you retrieve
159information from the knowledge graph. By default, GraphEmbed supports
160simple pattern queries and, if compiled with the SPARQL feature, full
161SPARQL queries: - *Pattern queries:* You can query by providing partial
162triple patterns. For example, `graphembed query "Alice -> ?p -> ?o"`
163could list all predicates and objects that Alice is connected to. Using
164`?` indicates a wildcard (variable) for any matching node or value.
165Similarly, `?s -> knows -> Bob` would find all subjects that have a
166\"knows\" relationship to Bob. - *SPARQL queries:* If the tool is built
167with SPARQL support (using an embedded engine), you can supply a SPARQL
168query string:
169`graphembed query "SELECT ?friend WHERE { <Alice> <knows> ?friend }"`.
170The query should be enclosed in quotes. Results will be printed in a
171simple table format or as JSON, depending on flags (e.g.,
172`--format csv|json` for result output). Keep in mind that full SPARQL
173support may require an additional dependency and can be toggled via a
174feature flag at compile time. If SPARQL is not available, the tool will
175inform you or fall back to basic queries. - *Performance:* For larger
176graphs, consider using indexing or persistent storage. GraphEmbed
177primarily holds the graph in memory. If you need to run complex queries
178on very large datasets, integration with a dedicated graph database
179(like an external SPARQL endpoint or property graph DB) might be
180preferable. However, for moderate-sized knowledge graphs, the built-in
181query should suffice.
182
183**Visualization:** The `visualize` command produces a human-readable
184graph representation. This can help you quickly understand the structure
185of the knowledge graph: - By default, `visualize` will output a Graphviz
186DOT format text to stdout or to a file (if `-o graph.dot` is specified).
187You can then use Graphviz tools (e.g.,
188`dot -Tpng graph.dot -o graph.png`) to generate an image. If Graphviz is
189installed, you might also use a convenience flag like `--png` to
190directly produce an image file. - The visualization simplifies node and
191edge labels for clarity. Each entity will appear as a node (often
192labeled by its name or ID), and each relationship appears as an arrow
193with the predicate label. Literal values attached to entities (like a
194name or other data) might appear as separate nodes or annotations. - For
195a very large graph, you can limit the visualization to a subgraph (e.g.,
196`--focus Alice` to show Alice and directly connected nodes only). This
197prevents an overly cluttered diagram. Alternatively, use query commands
198to filter what you visualize. - **Example:** if you run
199`graphembed visualize -o family.dot`, and your graph contains people and
200family relationships, the resulting DOT file can be rendered to show a
201network of those individuals connected by edges like \"parentOf\",
202\"siblingOf\", etc. This gives a quick insight without manually reading
203triples or JSON.
204
205**General Guidelines:** When using GraphEmbed: - **Naming Conventions:**
206Entities can be referenced by labels or IDs. If your data is RDF-based,
207consider using consistent prefixes (you can set a default base URI via a
208config or environment variable). For example, if you have a base
209`http://example.com/ns#`, an entity with label `Alice` might be expanded
210to `<http://example.com/ns#Alice>`. The CLI tries to manage this
211transparently. Avoid using spaces in identifiers unless you quote them
212properly in the shell. - **File Handling:** Always specify the correct
213file paths for import/export. The tool will not overwrite an existing
214file on export unless `--overwrite` is provided. On import, the graph in
215memory is appended to by default; use `--clear` before import if you
216want to replace the current graph. - **Memory and Performance:**
217GraphEmbed loads entire files into memory. Very large knowledge graphs
218(e.g., millions of triples) might cause high memory usage. In such
219cases, consider splitting data or using an external database. For
220embeddings, generating vectors is computationally intensive; model
221loading happens once per session for reuse, but each `embed` call will
222use CPU (or GPU if supported by the backend) to compute the vector.
223Batch embedding is supported via an input file or pipe to avoid
224reloading the model repeatedly. - **Extensibility:** The CLI is designed
225to be extensible. You can configure it to use different embedding models
226or graph stores by editing a config file (usually
227`~/.graphembed/config.toml`) or using environment variables. For
228example, `GRAPHEMBED_MODEL_DIR` can point to a directory of local models
229to avoid downloads. Future plugins might allow custom relationship types
230or integration with external vector databases for similarity search.
231
232## Workflow
233
234Using GraphEmbed involves a series of steps from setup to results. Below
235is a typical workflow for setting up the tool and utilizing its
236features:
237
2381. **Setup and Installation:** Install the GraphEmbed CLI tool using
239 Cargo or download the binary. Ensure that all dependencies (Rust
240 standard libraries, any needed system libraries for ML like Intel
241 MKL if using CPU acceleration for embeddings) are in place. For
242 example, on Linux you might need `libtorch` if using the Torch
243 backend, but the Rust crate typically includes it or downloads it
244 automatically.
2452. **Initialize a Knowledge Graph:** Start a new knowledge graph or
246 import an existing one. For a new graph, you can skip directly to
247 adding entities. To import, run `graphembed import data.jsonld`
248 (replace with your file). Verify that the CLI reports the number of
249 triples or nodes loaded. If you have multiple files, import them one
250 by one (the graph will accumulate data).
2513. **Generate or Ingest Embeddings:** If you have text data that needs
252 embeddings, use the `embed` command. For a single piece of text:
253 `graphembed embed "Your text here..." > vec.json`. This will output
254 the embedding vector (e.g., as a JSON array or a space-separated
255 list). For batch processing, you could pass a file:
256 `graphembed embed --input texts.txt --output vectors.csv`. This
257 reads multiple lines of text from `texts.txt` and writes
258 corresponding vectors (one per line) to a CSV. If you already have
259 embeddings (from Python or another source), prepare them in a CSV or
260 JSON format and use `graphembed import vectors.csv` to ingest. After
261 this step, your graph may have entities with associated embedding
262 vectors.
2634. **Add Entities and Relationships:** Use `add-entity` and `add-rel`
264 commands to build or extend your knowledge graph. For instance,
265 after importing base data, you might want to add a new entity that
266 wasn't in the original file:
267 `graphembed add-entity "Carol" --type Person`. Then link Carol to
268 existing entities: `graphembed add-rel "Carol" "knows" "Alice"`.
269 Continue to use add commands for any new knowledge you want to
270 capture. Each operation will update the in-memory graph and confirm
271 the addition.
2725. **Update and Delete Operations:** If you discover mistakes or need
273 to change the graph, use `update` or `delete`. For example, if
274 Carol's name was misspelled,
275 `graphembed update entity "Coral" --rename "Carol"` (or similar)
276 could fix it. To remove a relationship,
277 `graphembed delete rel "Carol" "knows" "Alice"` will delete that
278 edge. Always double-check with a query or visualize after
279 modifications to ensure the graph is in the desired state.
2806. **Query the Graph:** Now that your graph is populated and possibly
281 enriched with embeddings, retrieve information using queries. For
282 example, to find all friends of Alice:
283 `graphembed query "Alice -> knows -> ?friend"`. The tool will output
284 matches, e.g., "friend = Bob, Carol". If SPARQL is enabled and you
285 prefer that, use a full SPARQL query for more complex patterns or
286 filtering. At this stage, you could also perform semantic similarity
287 by combining embeddings and structure: while GraphEmbed doesn't
288 directly do vector similarity queries in this version, you can
289 manually take two entity embeddings (via `embed` or from stored
290 data) and compute cosine similarity using an external tool or a
291 small script.
2927. **Visualize (Optional):** For a quick visual check of part of the
293 graph, run `graphembed visualize --focus Alice -o subgraph.dot`.
294 This generates a DOT file for Alice and her neighbors. Run Graphviz
295 or an online DOT viewer to see the graph image. This step helps in
296 presentations or just sanity-checking the relationships.
2978. **Export the Graph:** Once you are satisfied with the graph's
298 content, save it. Use `graphembed export -f turtle -o output.ttl` to
299 get a Turtle file or `-f jsonld` for JSON-LD. The exported file can
300 be shared, loaded into other tools, or kept as a persistent store of
301 the knowledge graph. If your workflow is iterative, you might export
302 after each session as a backup.
3039. **Re-running and Automation:** The above steps can be repeated or
304 scripted. Because GraphEmbed is a CLI, you can include it in shell
305 scripts or integrate with other processes. For example, you could
306 have a nightly job that regenerates embeddings for new text and
307 updates a knowledge graph, using a series of `graphembed` commands
308 in sequence. The tool's output is designed to be parseable (CSV,
309 JSON, or plain text options for commands) so it can fit into larger
310 data pipelines.
311
312By following this workflow, you can build a rich knowledge graph that
313combines symbolic relationships with vector-based semantic information,
314all from the command line. Adjust the steps as needed for your specific
315use case (for instance, skip embedding generation if you only need the
316graph structure, or vice versa).
317
318## Examples
319
320Below are several usage examples demonstrating GraphEmbed's CLI commands
321and their outputs. These examples assume you have a graph about people
322and their relationships, as well as some textual data to embed.
323
324- **Generating a Text Embedding:** Use the `embed` command with a model
325 to convert text into an embedding vector.
326
327<!-- -->
328
329- $ graphembed embed -m all-MiniLM-L6-v2 "Rust is a systems programming language."
330 [0.102, 0.340, -0.215, ..., 0.877]
331
332 *Output:* A JSON-like array of floating-point numbers is printed to
333 stdout (here truncated for brevity). Each number represents a
334 dimension in the embedding space (e.g., 384 dimensions for MiniLM).
335 You can redirect this output to a file or parse it in a script. If the
336 model isn't specified, the default model's embedding is returned. The
337 first run may take a moment to load the model; subsequent calls will
338 be faster.
339
340<!-- -->
341
342- **Importing a Knowledge Graph from JSON-LD:** Suppose you have a file
343 `people.jsonld` that contains persons and relationships in JSON-LD
344 format.
345
346<!-- -->
347
348- $ graphembed import people.jsonld
349 Loaded graph with 50 entities, 120 relationships.
350
351 *Output:* The tool confirms the number of entities and relationships
352 loaded. Internally, each `@id` in JSON-LD becomes an entity node, and
353 each relationship (triple) is stored. If the JSON-LD had context
354 definitions for terms like "name" or "knows", those are preserved.
355 After import, the graph is ready for queries or edits.
356
357<!-- -->
358
359- **Exporting the Graph to Turtle:** To save the current graph as an RDF
360 Turtle file:
361
362<!-- -->
363
364- $ graphembed export -f turtle -o people.ttl
365 Exported graph to people.ttl (120 triples).
366
367 *Output:* The graph is written to `people.ttl`. The CLI reports the
368 count of triples. In the Turtle file, you'll find prefix declarations
369 (if any) followed by triples such as:
370
371 @prefix foaf: <http://xmlns.com/foaf/0.1/> .
372 @prefix ex: <http://example.com/ns#> .
373
374 ex:Alice foaf:knows ex:Bob, ex:Carol ;
375 foaf:name "Alice" .
376
377 This indicates Alice knows Bob and Carol, and has a name "Alice". The
378 export format is interoperable with other RDF tools.
379
380<!-- -->
381
382- **Adding Entities and Relationships via CLI:** If you want to extend
383 the graph with new data:
384
385<!-- -->
386
387- $ graphembed add-entity "Dave" --type Person --id ex:Dave
388 Created entity 'Dave' (ex:Dave) of type Person.
389
390 $ graphembed add-rel "Dave" "knows" "Alice"
391 Added relationship: Dave --knows--> Alice
392
393 *Output:* The first command adds a new entity named "Dave". We
394 explicitly provided an ID `ex:Dave` in the example (using a prefix
395 `ex` defined perhaps from the imported data). The tool confirms
396 creation. The second command adds a relationship indicating Dave knows
397 Alice. The CLI confirms the edge addition in a readable format. If
398 "Alice" was not already in the graph, it would either create a new
399 node or warn; in this case Alice exists from prior data.
400
401<!-- -->
402
403- **Updating an Entity's Property:** You can add or change properties on
404 an entity. For example:
405
406<!-- -->
407
408- $ graphembed update entity "Dave" --set "age=30"
409 Updated entity 'Dave': set age = "30"^^<http://www.w3.org/2001/XMLSchema#integer>.
410
411 *Output:* This sets Dave's age to 30 (the CLI infers it as an integer
412 literal in RDF terms). The confirmation shows the RDF literal with
413 datatype. If the property didn't exist, it's added; if it existed,
414 it's updated to the new value. You could similarly update a
415 relationship (e.g., change its predicate or qualifiers) with the
416 appropriate syntax.
417
418<!-- -->
419
420- **Deleting a Relationship:** Remove an edge from the graph:
421
422<!-- -->
423
424- $ graphembed delete rel "Dave" "knows" "Alice"
425 Relationship 'Dave knows Alice' deleted.
426
427 *Output:* The specified triple is removed. If there were multiple
428 triples with Dave as subject and Alice as object under different
429 predicates, only the one with predicate "knows" is removed. Deleting
430 an entity (with `delete entity`) would remove all triples involving
431 that entity.
432
433<!-- -->
434
435- **Querying for Connections:** Retrieve information with a simple
436 query.
437
438<!-- -->
439
440- $ graphembed query "Alice -> knows -> ?who"
441 Alice knows Bob
442 Alice knows Carol
443 Alice knows Dave
444
445 *Output:* The query finds all `?who` such that Alice *knows* them. The
446 results list each matching triple (subject Alice, predicate knows,
447 object being each result). In this case, Alice knows Bob, Carol, and
448 Dave. The output format is a straightforward listing; you can add
449 `--format csv` to get:
450
451 Alice,knows,Bob
452 Alice,knows,Carol
453 Alice,knows,Dave
454
455 which might be easier for scripts to parse. For more complex querying,
456 you could enable SPARQL and do something like:
457
458 $ graphembed query "SELECT ?p ?o WHERE { ex:Alice ?p ?o }"
459
460 resulting in a table of all predicates and objects for Alice.
461
462<!-- -->
463
464- **Visualizing a Subgraph:** To generate a quick visualization, focus
465 on a subset of the graph.
466
467<!-- -->
468
469- $ graphembed visualize --focus Alice -o alice.dot && dot -Tpng alice.dot -o alice.png
470
471 *Output:* The first part outputs a DOT file centered on Alice. Suppose
472 Alice is connected to Bob, Carol, and Dave as in our graph. The DOT
473 file will contain nodes for each person and arrows labeled \"knows\"
474 pointing out of Alice to the others. After running Graphviz (`dot`),
475 the resulting `alice.png` might show something like: Alice → Bob,
476 Alice → Carol, Alice → Dave (with arrows). Each node might be labeled
477 with the person's name, and additional properties (like age) could
478 appear as annotations or separate nodes depending on the visualization
479 mode. This provides a quick visual check that our data is correct
480 (e.g., we see Dave connected to Alice as expected from the earlier
481 commands).
482
483These examples illustrate typical interactions with GraphEmbed. By
484combining these commands, you can script complex operations -- for
485instance, automatically embedding new text data and inserting it into
486the graph, or exporting subsets of the graph for different audiences.
487The CLI's consistent format and use of standard data representations
488make it a flexible tool in a larger pipeline.
489
490## References
491
492- **Rust-BERT (HF Transformers in Rust):** [rust-bert
493 crate](https://crates.io/crates/rust-bert) -- A Rust library that
494 provides ready-to-use NLP transformer models (BERT, DistilBERT, etc.)
495 and pipelines for tasks like embeddings, using the `tch` (PyTorch)
496 backend. Enables generating sentence embeddings with pre-trained
497 Hugging Face models in Rust.
498- **Sentence Transformers in Rust:** [sbert
499 crate](https://crates.io/crates/sbert) -- A community port of
500 SentenceTransformers to Rust, built on rust-bert and tch. Supports
501 popular sentence embedding models for semantic search. This can be
502 used as an alternative embedding generation backend in GraphEmbed.
503- **ONNX Runtime for Rust:** [ort crate](https://crates.io/crates/ort)
504 -- Rust bindings for ONNX Runtime, allowing high-performance inference
505 of ONNX models. Useful for running SentenceTransformer models exported
506 to ONNX, often yielding faster or lighter-weight embedding generation.
507 GraphEmbed can leverage this for embedding if configured with the onnx
508 feature.
509- **Hugging Face Candle:** [candle
510 library](https://github.com/huggingface/candle) -- A minimalist Rust
511 deep learning framework by Hugging Face. Candle enables running
512 transformer models fully in Rust (no Python). It's an alternative
513 backend that GraphEmbed could use for embedding generation, especially
514 in offline or WASM scenarios.
515- **Knowledge Graph RDF Toolkit (Sophia):** [Sophia
516 crate](https://crates.io/crates/sophia) -- A comprehensive toolkit for
517 RDF and Linked Data in Rust. Supports parsing and writing of multiple
518 RDF serialization formats (Turtle, N-Triples, JSON-LD via an
519 extension) and provides in-memory graph management. GraphEmbed uses
520 libraries like Sophia to handle JSON-LD and Turtle import/export and
521 may use its graph interfaces for manipulating triples.
522- **RDF Graph Library:** [rdf (RDF.rs)](https://crates.io/crates/rdf) --
523 A Rust framework for RDF graphs. It provides data structures for
524 triples, graph storage, Turtle parsing, and basic SPARQL querying.
525 This or similar libraries serve as the foundation for GraphEmbed's
526 knowledge graph representation and querying capabilities.
527- **Oxigraph (SPARQL Database):** [Oxigraph
528 project](https://crates.io/crates/oxigraph) -- An efficient Rust graph
529 database with full SPARQL 1.1 support and persistent storage based on
530 RocksDB. While GraphEmbed is in-memory, Oxigraph demonstrates how
531 SPARQL queries and persistence can be achieved in Rust. GraphEmbed's
532 optional SPARQL querying is inspired by Oxigraph, and advanced users
533 might use Oxigraph directly for heavy-duty query needs.
534- **Graph Visualization:** [Graphviz DOT
535 crate](https://crates.io/crates/graphviz) -- A Rust library for
536 generating Graphviz DOT graph descriptions. GraphEmbed uses this or a
537 similar output method (potentially via `petgraph`'s dot exporters) to
538 produce visualizable graph representations. The DOT format can be
539 rendered by Graphviz tools to images.
540- **CLI Argument Parser:** [Clap crate](https://crates.io/crates/clap)
541 -- A widely used Rust library for parsing command-line arguments.
542 GraphEmbed employs Clap to define subcommands (`embed`, `import`,
543 etc.), options (like `--model`, `--format`), and help messages,
544 ensuring a consistent and user-friendly CLI interface.
545- **JSON-LD Processing:** [json-ld
546 crate](https://crates.io/crates/json_ld) -- A Rust implementation for
547 JSON-LD parsing and serialization. This is used under the hood to
548 correctly handle JSON-LD context and linking semantics when importing
549 or exporting JSON-LD files in GraphEmbed.
550
551Each of these resources contributes to GraphEmbed's functionality. For
552further information, refer to the respective documentation of these
553crates. By building on established libraries, GraphEmbed ensures
554reliability and leverages community support for tasks like machine
555learning inference and semantic data handling.
556
557------------------------------------------------------------------------