Turn natural language into read-only Cypher, validate it with CyVer, and execute it against Neo4j — powered by LiteLLM.
Project description
cyphersmith
cyphersmith turns natural language into read-only Cypher, validates it with CyVer, executes it against Neo4j, and returns the query plus records.
It uses LiteLLM for provider-neutral model access, so the same package works with OpenAI, Azure OpenAI, Anthropic, Gemini, and all other LiteLLM-supported providers.
Install
pip install cyphersmith
Python API
from cyphersmith import CypherGenerator, LLMConfig, Neo4jCredentials
generator = CypherGenerator(
neo4j=Neo4jCredentials(
uri="bolt://localhost:7687",
username="neo4j",
password="password",
database="neo4j",
),
llm=LLMConfig(
model="openai/gpt-4o-mini",
temperature=0,
),
business_context_path="business_context.yaml",
)
result = generator.ask("show top 10 items by a chosen metric")
print(result.cypher)
print(result.records)
CLI
Interactive setup and question loop:
cyphersmith chat --pretty
The interactive command prompts for:
- LLM provider and model
- API key and any provider-specific endpoint values
- Neo4j URI, username, password, and database
- optional business context file path
After setup, keep asking questions at Question>. Type /exit to stop. Each answer prints the generated Cypher query, records, validation details, attempts, and any error.
One-shot command:
cyphersmith ask \
--neo4j-uri bolt://localhost:7687 \
--neo4j-user neo4j \
--neo4j-password password \
--neo4j-database neo4j \
--model openai/gpt-4o-mini \
--business-context business_context.yaml \
"show top 10 items by a chosen metric"
The CLI prints live intermediate progress steps to stderr (context load, schema fetch, generation attempts, safety checks, validation, and execution) with terminal colors for readability. Final structured output stays on stdout.
Use these flags if needed:
--no-progress: disable intermediate step logs--no-color: keep progress logs but disable ANSI colors
The final CLI payload includes cypher, records, validation, attempts, and error.
Multihop Mode
By default ask answers with a single Cypher query (one-shot). Multihop mode is an opt-in agentic loop for questions that need several dependent lookups: a planner LLM breaks the question into sub-questions, each sub-question is turned into Cypher with the same safety/validation machinery, executed against Neo4j, and the results feed back into planning the next sub-question — until the planner declares the question answered or the hop cap is reached.
cyphersmith ask \
--mode multihop \
--max-hops 4 \
--model openai/gpt-4o-mini \
--neo4j-uri bolt://localhost:7687 \
--neo4j-user neo4j \
--neo4j-password password \
"which supplier had the most delayed orders, and which products were affected?"
Flags:
--mode {oneshot,multihop}: answering mode, defaultoneshot(existing behavior is unchanged)--max-hops: maximum sub-queries in multihop mode, default 4--max-records-to-llm: max records per hop fed back to the planner LLM, default 30 (full records always appear in the output)
In cyphersmith chat, switch modes at the prompt with /mode multihop and /mode oneshot.
The multihop payload includes original_query, hops (each with sub_question, reason, cypher, records, validation, attempts, error), a natural-language summary of the final answer, hops_used, stop_reason (planner_final, max_hops, hop_failed, or planner_parse_error), and error. If a hop fails, the loop stops and returns the completed hops plus a summary of what was gathered.
Python API (sync only for now):
result = generator.ask_multihop("which supplier had the most delayed orders?")
print(result.summary)
for hop in result.hops:
print(hop.sub_question, hop.cypher, hop.records)
Environment Variables
Neo4j values can be passed explicitly or read from:
NEO4J_URINEO4J_USERNEO4J_PASSWORDNEO4J_DATABASE
LiteLLM credentials should use the environment variables expected by the provider, such as OPENAI_API_KEY, AZURE_API_KEY, AZURE_API_BASE, or provider-specific equivalents.
Business Context
Pass a .txt, .md, .yaml, .yml, or .json file through business_context_path or --business-context. The content is added to the Cypher generation prompt as business context only; it is not treated as a schema source.
Safety
Generated Cypher is blocked unless it passes both:
- a local read-only keyword/procedure check
- CyVer syntax, schema, and property validation
The package will not execute generated queries containing obvious write operations such as CREATE, MERGE, DELETE, SET, REMOVE, or procedures like CALL db and CALL apoc.
License
MIT
Project details
Release history Release notifications | RSS feed
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 cyphersmith-0.2.0.tar.gz.
File metadata
- Download URL: cyphersmith-0.2.0.tar.gz
- Upload date:
- Size: 31.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cc339542ad504a1524f9aaad450afe757526fbb8af150f490a152620b5915727
|
|
| MD5 |
c1fc3c68f20054d0f717fdbaf2112533
|
|
| BLAKE2b-256 |
ab5093c5a00c0d7f7b27a05650a786d1d32becafb401e58a27019bdabc665fd4
|
File details
Details for the file cyphersmith-0.2.0-py3-none-any.whl.
File metadata
- Download URL: cyphersmith-0.2.0-py3-none-any.whl
- Upload date:
- Size: 28.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
522c59e2e49ff76ea8af7ad7a82071d30f7db7436ee6746f727c8cc68701cf2e
|
|
| MD5 |
247188d2490409734fad6474587023a3
|
|
| BLAKE2b-256 |
02157b80f3d4f36bf560637d53fba37ae6e9c1bda3a0486fea0db3b1a4645509
|