Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Ant Group knowledge graph engine with SPG and KAG framework
.claude/skills/brycewang-stanford-openspg-guide/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-02 | ✗→✓ | ▲ Improved | -8% | 0% |
| case-03 | ✗→✓ | ▲ Improved | 16% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 94% | 0% |
| case-09 | ✗→✓ | ▲ Improved | -2% | 0% |
| case-10 | ✗→✓ | ▲ Improved | -40% | 0% |
OpenSPG is Ant Group's open-source knowledge graph engine based on the Semantic-enhanced Programmable Graph (SPG) framework. It combines property graphs with semantic reasoning, enabling knowledge extraction, representation, reasoning, and question answering. The KAG (Knowledge Augmented Generation) module integrates with LLMs for RAG over knowledge graphs. Suited for building domain-specific knowledge bases for research.
bash# Docker deployment git clone https://github.com/OpenSPG/openspg.git cd openspg docker-compose up -d # Python SDK pip install openspg # Access KG Studio at http://localhost:8887
SPG Framework
├── Schema Layer (define types and relations)
│ ├── Entity types (Person, Paper, Concept)
│ ├── Properties (typed, constrained)
│ └── Relations (directed, typed edges)
├── Knowledge Layer (populate with data)
│ ├── Entity extraction (NER + linking)
│ ├── Relation extraction
│ └── Property filling
├── Reasoning Layer (infer new knowledge)
│ ├── Rule-based reasoning
│ ├── Statistical reasoning
│ └── LLM-augmented reasoning
└── Application Layer (query and use)
├── Graph queries (SPARQL-like)
├── Question answering
└── Knowledge-augmented generationpythonfrom openspg import Schema, EntityType, RelationType # Define a research knowledge graph schema schema = Schema("research_kg") # Entity types paper = EntityType("Paper", properties={ "title": "Text", "abstract": "Text", "year": "Integer", "venue": "Text", "doi": "Text", "citation_count": "Integer", }) author = EntityType("Author", properties={ "name": "Text", "affiliation": "Text", "h_index": "Integer", }) concept = EntityType("Concept", properties={ "name": "Text", "definition": "Text", "domain": "Text", }) # Relations schema.add_relation(RelationType( "authored_by", source=paper, target=author )) schema.add_relation(RelationType( "cites", source=paper, target=paper )) schema.add_relation(RelationType( "discusses", source=paper, target=concept )) schema.add_relation(RelationType( "related_to", source=concept, target=concept )) schema.deploy()
pythonfrom openspg import KnowledgeBuilder builder = KnowledgeBuilder(schema="research_kg") # Add entities builder.add_entity("Paper", { "title": "Attention Is All You Need", "year": 2017, "venue": "NeurIPS", "doi": "10.48550/arXiv.1706.03762", }) # Automatic extraction from text builder.extract_from_text( "Vaswani et al. proposed the Transformer architecture " "which uses self-attention mechanisms to replace " "recurrence. The model achieved state-of-the-art on " "WMT 2014 English-to-German translation.", entity_types=["Paper", "Author", "Concept"], relation_types=["authored_by", "discusses"], ) # Batch import from structured data builder.import_csv( "papers.csv", entity_type="Paper", column_mapping={"title": "title", "year": "year"}, ) builder.commit()
pythonfrom openspg.kag import KAGPipeline kag = KAGPipeline( knowledge_graph="research_kg", llm_provider="anthropic", ) # Question answering over knowledge graph answer = kag.ask( "What are the key papers on attention mechanisms " "and how are they related?" ) print(answer.text) for source in answer.sources: print(f" [{source.type}] {source.name}: {source.evidence}") # The KAG pipeline: # 1. Parses question to identify relevant entities/relations # 2. Queries knowledge graph for subgraph # 3. Augments LLM context with structured knowledge # 4. Generates grounded answer with provenance
pythonfrom openspg import GraphQuery gq = GraphQuery("research_kg") # Find papers by concept papers = gq.query(""" MATCH (p:Paper)-[:discusses]->(c:Concept) WHERE c.name = 'self-attention' RETURN p.title, p.year, p.citation_count ORDER BY p.citation_count DESC LIMIT 10 """) # Find co-author network coauthors = gq.query(""" MATCH (a1:Author)<-[:authored_by]-(p:Paper) -[:authored_by]->(a2:Author) WHERE a1.name = 'Ashish Vaswani' RETURN DISTINCT a2.name, COUNT(p) as papers ORDER BY papers DESC """) # Citation chain chain = gq.query(""" MATCH path = (p1:Paper)-[:cites*1..3]->(p2:Paper) WHERE p1.title CONTAINS 'GPT-4' RETURN path LIMIT 20 """)
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→fail | 18,445 | 41,990 | +128% | 1 | 1 | 0% | 3,692 | 3,366 | -9% | 0 | 0 | — |
case-02 | fail→pass | 49,890 | 40,432 | -19% | 1 | 1 | 0% | 3,746 | 3,433 | -8% | 0 | 0 | — |
case-03 | fail→pass | 51,961 | 15,491 | -70% | 1 | 1 | 0% | 3,311 | 3,850 | +16% | 0 | 0 | — |
case-04 | pass→pass | 15,779 | 21,306 | +35% | 1 | 1 | 0% | 3,565 | 4,880 | +37% | 0 | 0 | — |
case-05 | pass→pass | 22,026 | 12,319 | -44% | 1 | 1 | 0% | 3,078 | 3,978 | +29% | 0 | 0 | — |
case-06 | pass→pass | 16,220 | 12,607 | -22% | 1 | 1 | 0% | 2,743 | 4,089 | +49% | 0 | 0 | — |
case-07 | fail→pass | 35,151 | 1,975 | -94% | 1 | 1 | 0% | 907 | 1,756 | +94% | 0 | 0 | — |
case-08 | pass→pass | 11,704 | 12,122 | +4% | 1 | 1 | 0% | 2,079 | 3,618 | +74% | 0 | 0 | — |
case-09 | fail→pass | 11,139 | 3,139 | -72% | 1 | 1 | 0% | 2,031 | 1,982 | -2% | 0 | 0 | — |
case-10 | fail→pass | 16,973 | 3,872 | -77% | 1 | 1 | 0% | 3,247 | 1,944 | -40% | 0 | 0 | — |
case-11 | pass→pass | 11,884 | 2,772 | -77% | 1 | 1 | 0% | 2,002 | 1,907 | -5% | 0 | 0 | — |
case-12 | fail→pass | 20,868 | 12,336 | -41% | 1 | 1 | 0% | 3,153 | 3,757 | +19% | 0 | 0 | — |
case-13 | fail→pass | 16,878 | 5,500 | -67% | 1 | 1 | 0% | 2,638 | 2,176 | -18% | 0 | 0 | — |
case-14 | fail→pass | 14,703 | 10,918 | -26% | 1 | 1 | 0% | 2,690 | 3,690 | +37% | 0 | 0 | — |
case-15 | fail→pass | 7,453 | 10,849 | +46% | 1 | 1 | 0% | 1,322 | 2,615 | +98% | 0 | 0 | — |
case-16 | fail→fail | 8,355 | 7,083 | -15% | 1 | 1 | 0% | 1,415 | 2,597 | +84% | 0 | 0 | — |
case-17 | fail→pass | 10,550 | 3,803 | -64% | 1 | 1 | 0% | 1,506 | 1,976 | +31% | 0 | 0 | — |
case-18 | pass→pass | 9,721 | 2,518 | -74% | 1 | 1 | 0% | 1,640 | 1,690 | +3% | 0 | 0 | — |
case-19 | fail→pass | 9,616 | 2,215 | -77% | 1 | 1 | 0% | 1,642 | 1,785 | +9% | 0 | 0 | — |
case-20 | pass→pass | 16,006 | 16,385 | +2% | 1 | 1 | 0% | 2,584 | 4,186 | +62% | 0 | 0 | — |
case-21 | fail→pass | 7,334 | 1,782 | -76% | 1 | 1 | 0% | 1,101 | 1,734 | +57% | 0 | 0 | — |
case-22 | pass→pass | 11,908 | 11,804 | -1% | 1 | 1 | 0% | 1,760 | 3,636 | +107% | 0 | 0 | — |
case-23 | fail→pass | 12,768 | 2,724 | -79% | 1 | 1 | 0% | 2,259 | 1,963 | -13% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 23 cases were attempted. The headline lift of +57 percentage points is the difference between those two pass rates over the 23 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.