kg-gen: Extracting Knowledge Graphs from Plain Text with a Model You Choose
[NeurIPS '25] Knowledge Graph Generation from Any Text
At a glance
- What is it?
- kg-gen is a Python library that turns text into entity and relation triples, with chunking, clustering and graph aggregation handled by the library rather than by you. It is a thin orchestration layer over LiteLLM and DSPy, which is both its main selling point and the source of its main cost.
- Who is it for?
- Adopt kg-gen if you already have a model endpoint you trust and you want triples, not a graph database: the library stops at entities, edges and relations, and the README shows no persistence layer. Do not adopt it if you need a deterministic pipeline, because every extraction is a language model call and the output is only as stable as the model behind it.
- Can I use it commercially?
- Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
- Is it still maintained?
- Yes. The repository last received commits 175 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The gap kg-gen fills: triples out of unstructured prose
Most text-to-graph tooling asks you to commit to a schema first. kg-gen inverts that. You hand it a string or a list of chat messages, and it returns three sets: entities, edges (the relation labels themselves, such as 'is mother of'), and relations, which are the ordered triples of subject, edge and object. That last distinction matters and is easy to miss. The library reports the vocabulary of relations separately from the instances of them, so you can inspect what kinds of edges the model produced before you look at which pairs it connected. The README's first example is three sentences about a family and comes back with four entities and three edge labels. The stated use cases are retrieval-augmented generation, synthetic graph data for training and testing, structuring text into a graph, and analysing relationships between concepts. The intended user is a Python developer with an API key or a local model server, not an analyst working in a notebook UI.
LiteLLM and DSPy do the work, which defines the cost model
kg-gen does not ship a model. Model calls are routed through LiteLLM, so the model string follows LiteLLM's provider conventions, and the README gives three concrete forms: openai/gpt-5, gemini/gemini-2.5-flash and ollama_chat/deepseek-r1:14b. Structured output generation is handled by DSPy. The practical consequence is that extraction quality tracks whatever model you point at it, and so does latency and spend. A local Ollama model keeps text on your machine and costs nothing per call, but the README makes no claim about how its output compares to a hosted frontier model. A hosted model gives you a stronger extractor at a per-call price, and for a long document with chunking enabled you are paying per chunk. There is no caching layer described in the material, so re-running a pipeline re-runs the calls. A custom endpoint is supported through a base_url argument, with the repository pointing to tests/test_custom_api_base.py as the example.
Chunking, clustering and aggregation as separate operations
The interesting part of the API is that these are distinct steps rather than one opaque call. In the large-text example, generate() takes chunk_size=5000 and cluster=True, and the result includes entity_clusters and edge_clusters alongside the raw sets. Those cluster maps are where the library earns its keep: 'neural networks', 'neural nets' and 'NN' collapse under one key, and edge labels like 'is a type of' and 'is a kind of' collapse under 'is type of'. Without that step, a graph built from a real document is mostly duplicate nodes under different surface forms. Aggregation is separate again. You generate graphs from two texts independently, call kg.aggregate([graph_a, graph_b]) to union them, and optionally call kg.cluster() on the combined result with a context string. The README's worked example shows 'Joe' and 'Joseph' merging into one entity after clustering, which is exactly the case a naive union would get wrong. Note that clustering is optional at every stage, and the README does not state which similarity method is used for it.
Install, run and verify: the commands the README gives
From PyPI: pip install kg-gen. From source: clone the repository and run pip install -e '.[dev]'. The README names python tests/test_basic.py, run from the root directory, as the way to confirm the install works, and notes that it produces tests/test_basic.html as a visualisation. Visualisation is also exposed as a static method, KGGen.visualize(graph, output_path, open_in_browser=True). Construction takes model, temperature and api_key, with the example using model='openai/gpt-4o' and temperature=0.0. The api_key argument is described as optional if the key is already in the environment or you are using a local model. There is a second entry point for agents: pip install kg-gen followed by kggen mcp starts an MCP server, and the README lists Claude Desktop and custom MCP clients as intended consumers. Benchmark instructions live under experiments/MINE, and the repository has shipped MINE evaluation releases, including one comparing Scikit Learn against Faiss for deduplication, which tells you the deduplication step has been reworked at least once.
Where kg-gen is the wrong tool
The output is a language model's reading of your text, and nothing in the material suggests a confidence score, a provenance span, or a validation pass attached to individual triples. If you need to trace a relation back to the sentence that produced it, the README does not show that capability. The family example is a good illustration of the ceiling: the model returns 'is brother of' and 'is father of' as separate edge labels rather than normalising them into a single schema, and it is clustering, an optional step, that cleans that up afterwards. Expect a two-pass pipeline if you care about consistency. The library also stops at the graph structure. There is no mention of writing to Neo4j, RDF, or any graph store, so persistence is your problem. Cost is the other boundary. Chunked extraction over a large corpus multiplies model calls by chunk count, and because there is no described caching, an iterative workflow that re-generates the same document repeatedly will pay repeatedly. Finally, the repository's licence is not stated in the supplied material, which is a real blocker for anyone shipping this inside a commercial product until they check it.
How it differs from LangChain's LLMGraphTransformer
The closest well-known comparison is LangChain's LLMGraphTransformer, which also uses a language model to produce graph documents from text. The difference is where the work sits. LLMGraphTransformer is a component inside LangChain's wider ecosystem, so it inherits that framework's abstractions, its document loaders and its graph store integrations, and it expects you to bring a LangChain chat model. kg-gen is standalone and narrower. It takes a string or a list of message dicts, returns plain Python sets and tuples, and routes models through LiteLLM instead of LangChain. If you are already building on LangChain and want your extracted graph written straight into a supported store, the transformer fits your existing wiring better. If you want a small dependency that returns data structures you can inspect and post-process yourself, kg-gen's surface is smaller. The trade is integration on one side and control on the other, and kg-gen's cluster and aggregate steps are the part you would otherwise have to write yourself.
Maintenance surface and what the release history implies
The last push recorded is 2026-03-24, and the three listed releases are all evaluation artefacts rather than library versions: expanded MINE evaluations, a MINE deduplication comparison of Scikit Learn against Faiss, and a WikiQA KGGen dataset release. That pattern suggests active benchmark work alongside the library, and it also suggests the deduplication path has changed implementation at least once. For an adopter, that is a signal to pin a version rather than track main. The dependency surface is the real maintenance cost: LiteLLM and DSPy both move quickly, and kg-gen's behaviour is coupled to how those two handle provider routing and structured output. A breaking change upstream can change your extraction results without any change to your own code. The licence is unstated in the supplied material, so the first thing to resolve before any commercial use is the licence file in the repository. Nothing here is legal advice; read the licence yourself.
Editorial conclusion
Adopt kg-gen if you already have a model endpoint you trust and you want triples, not a graph database: the library stops at entities, edges and relations, and the README shows no persistence layer. Do not adopt it if you need a deterministic pipeline, because every extraction is a language model call and the output is only as stable as the model behind it. Before committing, verify three things in the repository: the licence, which the supplied material does not state; the current state of the tests/ directory, which the README points to as the way to try the library; and whether the MCP server in mcp/ matches the client you intend to use.
Community notes