Appearance
OpenSPG 开发教程
目录
1. 项目简介
1.1 什么是OpenSPG?
OpenSPG (Open Semantic-enhanced Programmable Graph) 是蚂蚁集团与OpenKG联合推出的开源知识图谱引擎,基于SPG框架研发。它结合了多年金融领域知识图谱构建与应用的业务经验。
1.2 核心特性
- 语义增强的属性图:融合LPG结构性与RDF语义性
- 知识构建框架:支持结构化和非结构化数据的知识转换
- 逻辑规则推理:提供KGDSL(知识图谱领域专用语言)
- 可编程框架KNext:组件化、流程化的图谱能力
- 云适配层Cloudext:可插拔的图存储、搜索引擎等基础设施
1.3 应用场景
- 企业供应链知识图谱
- 风险挖掘与反欺诈
- 医疗知识图谱
- 知识增强生成(KAG)与大语言模型结合
1.4 技术栈
| 技术类别 | 技术选型 |
|---|---|
| 开发语言 | Java 8, Scala 2.11.12 |
| 构建工具 | Maven 3+ |
| Web框架 | Spring Boot 2.7.8, SOFABoot 3.17.0 |
| 数据访问 | MyBatis 3.5.2 |
| 图数据库 | Neo4j 4.4.7, TuGraph 1.4.1 |
| 搜索引擎 | Elasticsearch, Neo4j |
| 缓存 | Redis |
| 对象存储 | MinIO, Aliyun OSS |
| DSL解析 | ANTLR4 4.8 |
2. 系统架构
2.1 整体架构
┌─────────────────────────────────────────────────────────────┐
│ OpenSPG Engine │
├─────────────────────────────────────────────────────────────┤
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Schema │ │ Builder │ │ Reasoner │ │ KNext │ │
│ │ 模型定义 │ │ 知识构建 │ │ 逻辑推理 │ │ 可编程框架│ │
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
├─────────────────────────────────────────────────────────────┤
│ Cloud Adaptation Layer │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ GraphStore│ │ Search │ │ Cache │ │ Storage │ │
│ │ 图存储适配 │ │ 搜索适配 │ │ 缓存适配 │ │ 对象存储 │ │
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
├─────────────────────────────────────────────────────────────┤
│ Infrastructure │
│ Neo4j / TuGraph | Elasticsearch | Redis | MinIO │
└─────────────────────────────────────────────────────────────┘2.2 模块结构
openspg/
├── server/ # REST API服务层
│ ├── api/ # HTTP接口定义
│ ├── biz/ # 业务逻辑层
│ ├── core/ # 核心服务
│ ├── common/ # 公共模块
│ ├── infra/ # 基础设施(数据访问)
│ └── arks/ # 应用启动
├── reasoner/ # 推理引擎
│ ├── lube-api/ # 抽象接口
│ ├── lube-logical/ # 逻辑查询计划
│ ├── lube-physical/ # 物理执行计划
│ ├── kgdsl-parser/ # KGDSL解析器
│ ├── runner/ # 执行器
│ ├── warehouse/ # 图仓库
│ └── catalog/ # Schema目录
├── builder/ # 知识构建框架
│ ├── core/ # 核心执行引擎
│ ├── model/ # 数据模型
│ └── runner/ # 本地执行器
├── cloudext/ # 云适配层
│ ├── interface/ # 抽象接口
│ └── impl/ # 具体实现
└── common/ # 公共工具类2.3 核心概念
SPG类型体系
SPGType (所有类型的基类)
├── EntityType # 实体类型(如:人物、组织)
├── ConceptType # 概念类型(如:行业分类)
├── EventType # 事件类型(如:交易事件)
├── StandardType # 标准类型(如:实体归一化)
└── BasicType # 基础类型(如:Text、Integer)谓词(Predicate)
- Property(属性):实体的属性,如人物的年龄、姓名
- Relation(关系):实体之间的关系,如人物-工作于-组织
3. 环境搭建
3.1 前置要求
- Java: JDK 1.8+
- Maven: 3.0+
- MySQL: 5.7+(用于元数据存储)
- Neo4j: 4.4.7或TuGraph 1.4.1(图数据库)
- Python: 3.10+(可选,用于NLP处理)
3.2 快速启动
步骤1:克隆代码
bash
git clone https://github.com/OpenSPG/openspg.git
cd openspg步骤2:配置数据库
创建MySQL数据库:
sql
CREATE DATABASE openspg CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;步骤3:配置应用
编辑配置文件 server/arks/sofaboot/src/main/resources/config/application-default.properties:
properties
# 服务器配置
server.port=8887
# MySQL配置
server.repository.impl.jdbc.host=127.0.0.1
server.repository.impl.jdbc.port=3306
server.repository.impl.jdbc.username=root
server.repository.impl.jdbc.password=your_password
# 图数据库配置(Neo4j)
cloudext.graphstore.url=neo4j://localhost:7687?user=neo4j&password=your_neo4j_password&database=neo4j
# 搜索引擎配置
cloudext.searchengine.url=neo4j://localhost:7687?user=neo4j&password=your_neo4j_password&database=neo4j
# Python配置(可选)
python.exec=/usr/bin/python3
python.paths=/usr/lib/python3.10/site-packages/步骤4:构建项目
bash
mvn clean install -DskipTests步骤5:启动服务
bash
cd server/arks/sofaboot
mvn spring-boot:run服务启动后,访问 http://localhost:8887 验证服务是否正常运行。
3.3 Docker部署(推荐)
使用Docker Compose快速部署完整环境:
bash
# 启动所有服务(MySQL、Neo4j、OpenSPG)
docker-compose up -d4. 核心模块详解
4.1 Schema模块(语义建模)
Schema模块负责定义知识图谱的语义结构。
主要功能
- 定义SPG类型(实体、概念、事件等)
- 定义属性和关系
- Schema版本管理和演化
- 语义约束和规则定义
核心类
BaseSPGType: 所有SPG类型的基类EntityType: 实体类型定义Property: 属性定义Relation: 关系定义SchemaDraft: Schema草稿(用于批量修改)
代码示例
java
// 创建一个实体类型
EntityType personType = new EntityType(
new BasicInfo(
new SPGTypeIdentifier("default", "Person"),
"人物",
"表示现实中的人物"
),
ParentTypeInfo.THING,
properties, // 属性列表
relations, // 关系列表
null
);
// 添加属性
Property nameProperty = new Property(
new BasicInfo(
new PredicateIdentifier("name"),
"姓名",
"人物的姓名"
),
null,
new SPGTypeRef(BasicType.TEXT),
false, // 是否多值
new PropertyAdvancedConfig()
.setIndexType(IndexTypeEnum.TEXT)
);4.2 Builder模块(知识构建)
Builder模块负责从数据源构建知识图谱。
架构
数据源 → 读取器 → 处理器 → 写入器 → 图存储
↓ ↓ ↓ ↓ ↓
CSV Source Python Sink Neo4j
JSON Reader Processor Writer TuGraph
DB核心组件
SourceReader: 数据源读取器
- CSVReader
- JSONReader
- DatabaseReader
Processor: 数据处理器
- EntityLinkingProcessor(实体链接)
- ConceptNormalizationProcessor(概念标准化)
- EntityNormalizationProcessor(实体归一化)
- PythonProcessor(Python自定义处理)
SinkWriter: 数据写入器
- GraphStoreWriter
- Neo4jWriter
工作流程
- 定义Schema: 先定义知识图谱的Schema
- 配置数据源: 配置CSV、JSON或数据库连接
- 定义处理流程: 配置ETL处理器链
- 执行构建: 提交构建任务
- 监控进度: 查看构建状态和日志
4.3 Reasoner模块(逻辑推理)
Reasoner模块提供基于逻辑规则的推理能力。
三层架构
KGDSL层: 知识图谱领域专用语言
- 解析DSL语句
- 语义验证
逻辑层: 逻辑查询计划
- PatternScan(模式扫描)
- LinkedExpand(链接扩展)
- Filter(过滤)
- Project(投影)
- Aggregate(聚合)
物理层: 物理执行计划
- Unfold/Fold(展开/折叠)
- Join(连接)
- 与图存储交互
KGDSL示例
kgdsl
// 查询:找出在某公司工作的所有员工
Define (s:Person)-[p:workAt]->(o:Company)/o.name='阿里巴巴'
Rule: employees = s
// 查询:通过多跳关系推理
Define (p1:Person)-[:friendOf]->(p2:Person)-[:friendOf]->(p3:Person)
Rule: potentialFriends = (p1, p3)4.4 Cloudext模块(云适配层)
Cloudext提供可插拔的基础设施适配。
抽象接口
java
// 图存储接口
public interface LPGDataQueryService {
List<LPGRecord> queryRecord(BaseLPGRecordQuery query);
}
public interface LPGDataManipulationService {
void insert(LPGRecordStruct record);
void update(LPGRecordStruct record);
void delete(LPGRecordQuery query);
}实现适配器
| 功能 | 接口 | 实现 |
|---|---|---|
| 图存储 | LPGGraphStore | Neo4jAdapter, TuGraphAdapter |
| 搜索引擎 | SearchEngine | ElasticsearchAdapter, Neo4jAdapter |
| 缓存 | Cache | RedisAdapter |
| 对象存储 | ObjectStorage | MinIOAdapter, OSSAdapter |
5. API接口说明
5.1 Schema管理接口
5.1.1 创建/修改Schema
接口: POST /public/v1/schema/alterSchema
请求参数:
json
{
"projectId": 1,
"schemaDraft": {
"alterSpgTypes": [
{
"name": "Person",
"nameZh": "人物",
"spgTypeEnum": "ENTITY_TYPE",
"alterOperation": "CREATE",
"properties": [
{
"name": "name",
"nameZh": "姓名",
"objectTypeRef": {
"name": "Text"
},
"alterOperation": "CREATE"
}
],
"relations": [
{
"name": "workAt",
"nameZh": "工作于",
"objectTypeRef": {
"name": "Company"
},
"alterOperation": "CREATE"
}
]
}
]
}
}响应:
json
{
"success": true,
"data": true
}5.1.2 查询项目Schema
接口: GET /public/v1/schema/queryProjectSchema?projectId=1
响应:
json
{
"success": true,
"data": {
"projectId": 1,
"spgTypes": [
{
"name": "Person",
"nameZh": "人物",
"properties": [...],
"relations": [...]
}
]
}
}5.1.3 查询SPG类型
接口: GET /public/v1/schema/querySpgType?name=Person
5.2 查询接口
5.2.1 查询SPG类型实例
接口: POST /public/v1/query/spgType
请求参数:
json
{
"projectId": 1,
"spgTypeName": "Person",
"conditions": [
{
"property": "name",
"operator": "EQUALS",
"value": "张三"
}
],
"limit": 10
}响应:
json
{
"success": true,
"data": [
{
"id": "Person_001",
"type": "Person",
"properties": {
"name": "张三",
"age": 30
},
"relations": [...]
}
]
}5.3 知识构建接口
5.3.1 提交构建任务
接口: POST /public/v1/builder/kag/submit
请求参数:
json
{
"projectId": 1,
"workerNum": 1,
"command": "python build_script.py",
"userNumber": "user123"
}响应:
json
{
"success": true,
"data": {
"id": 100,
"jobName": "KAG_COMMAND_user123_2025_01_15_10_30_00",
"status": "RUNNING",
"taskId": 1001
}
}5.3.2 查询构建任务状态
接口: GET /public/v1/builder/getById?id=100
响应:
json
{
"success": true,
"data": {
"id": 100,
"jobName": "KAG_COMMAND_user123_2025_01_15_10_30_00",
"status": "SUCCESS",
"startTime": "2025-01-15 10:30:00",
"endTime": "2025-01-15 10:35:00"
}
}5.3.3 搜索构建任务
接口: POST /public/v1/builder/search
5.4 推理接口
接口: POST /public/v1/reason/execute
请求参数:
json
{
"projectId": 1,
"kgdsl": "Define (s:Person)-[p:friendOf]->(o:Person) Rule: result = s",
"parameters": {}
}5.5 搜索接口
5.5.1 实体搜索
接口: POST /public/v1/search/entity
请求参数:
json
{
"projectId": 1,
"keyword": "张三",
"spgTypeNames": ["Person"],
"limit": 10
}5.5.2 图搜索
接口: POST /public/v1/search/graph
6. 使用示例
6.1 完整示例:构建企业知识图谱
步骤1:定义Schema
java
// 1. 定义Company实体类型
EntityType companyType = new EntityType(
new BasicInfo(
new SPGTypeIdentifier("enterprise", "Company"),
"公司",
"企业组织"
),
ParentTypeInfo.THING,
Arrays.asList(
createProperty("name", "公司名称", BasicType.TEXT, IndexTypeEnum.TEXT),
createProperty("establishDate", "成立日期", BasicType.TEXT, IndexTypeEnum.TEXT),
createProperty("industry", "所属行业", BasicType.TEXT, IndexTypeEnum.TEXT)
),
null,
null
);
// 2. 定义Person实体类型
EntityType personType = new EntityType(
new BasicInfo(
new SPGTypeIdentifier("enterprise", "Person"),
"人物",
"自然人"
),
ParentTypeInfo.THING,
Arrays.asList(
createProperty("name", "姓名", BasicType.TEXT, IndexTypeEnum.TEXT),
createProperty("age", "年龄", BasicType.INTEGER, IndexTypeEnum.EXACT)
),
Arrays.asList(
createRelation("workAt", "工作于", companyType.toRef())
),
null
);
// 3. 提交Schema
SchemaAlterRequest request = new SchemaAlterRequest();
request.setProjectId(1L);
SchemaDraft draft = new SchemaDraft();
draft.setAlterSpgTypes(Arrays.asList(companyType, personType));
request.setSchemaDraft(draft);
schemaManager.alterSchema(request);步骤2:准备数据
创建CSV文件 companies.csv:
csv
id,name,establishDate,industry
C001,阿里巴巴,1999-09-09,互联网
C002,腾讯,1998-11-11,互联网创建CSV文件 persons.csv:
csv
id,name,age,companyId
P001,张三,30,C001
P002,李四,28,C002步骤3:构建知识
python
# build_script.py
from knext.builder import KnowledgeBuilder
# 初始化构建器
builder = KnowledgeBuilder(project_id=1)
# 加载公司数据
builder.load_csv('companies.csv', 'Company', {
'id': 'id',
'name': 'name',
'establishDate': 'establishDate',
'industry': 'industry'
})
# 加载人员数据
builder.load_csv('persons.csv', 'Person', {
'id': 'id',
'name': 'name',
'age': 'age'
})
# 构建关系
builder.create_relation('Person', 'workAt', 'Company', {
'from_id_field': 'id',
'to_id_field': 'companyId'
})
# 执行构建
builder.execute()步骤4:查询知识
java
// 查询在阿里巴巴工作的员工
SPGTypeQueryRequest queryRequest = new SPGTypeQueryRequest();
queryRequest.setProjectId(1L);
queryRequest.setSpgTypeName("Person");
queryRequest.setConditions(Arrays.asList(
new QueryCondition("workAt.name", "EQUALS", "阿里巴巴")
));
List<SPGTypeInstance> result = queryManager.query(queryRequest);6.2 示例:使用KGDSL推理
java
// 推理:找出可能认识的人(通过共同朋友)
String kgdsl = """
Define (p1:Person)-[:friendOf]->(mutual:Person)-[:friendOf]->(p2:Person)
Constraint {
p1.id != p2.id
}
Rule: potentialFriend = (p1, p2, mutual)
""";
ReasoningRequest request = new ReasoningRequest();
request.setProjectId(1L);
request.setKgdsl(kgdsl);
ReasoningResult result = reasonerManager.reason(request);6.3 示例:实体搜索
java
// 全文搜索人物
SearchRequest searchRequest = new SearchRequest();
searchRequest.setProjectId(1L);
searchRequest.setKeyword("张三");
searchRequest.setSpgTypeNames(Arrays.asList("Person"));
searchRequest.setLimit(10);
SearchResponse response = searchManager.search(searchRequest);7. 开发指南
7.1 扩展自定义数据源
实现SourceReader接口
java
public class CustomSourceReader implements SourceReader {
@Override
public void init(Map<String, Object> config) {
// 初始化配置
}
@Override
public List<Record> read() {
// 读取数据并返回记录列表
List<Record> records = new ArrayList<>();
// ... 实现数据读取逻辑
return records;
}
@Override
public void close() {
// 关闭资源
}
}注册自定义Reader
java
@Component
public class CustomReaderFactory implements SourceReaderFactory {
@Override
public String getType() {
return "CUSTOM";
}
@Override
public SourceReader create(Map<String, Object> config) {
return new CustomSourceReader();
}
}7.2 扩展自定义图存储
实现GraphStore接口
java
public class CustomGraphStoreAdapter implements LPGGraphStore {
@Override
public void init(String connectionUrl) {
// 初始化连接
}
@Override
public List<LPGRecord> query(BaseLPGRecordQuery query) {
// 实现查询逻辑
return null;
}
@Override
public void insert(LPGRecordStruct record) {
// 实现插入逻辑
}
@Override
public void update(LPGRecordStruct record) {
// 实现更新逻辑
}
@Override
public void delete(LPGRecordQuery query) {
// 实现删除逻辑
}
}注册适配器
在 application.properties 中配置:
properties
cloudext.graphstore.driver=com.yourcompany.CustomGraphStoreAdapter
cloudext.graphstore.url=custom://localhost:1234?param=value7.3 开发自定义Processor
python
# custom_processor.py
from knext.builder.processor import BaseProcessor
class CustomEntityProcessor(BaseProcessor):
def process(self, record):
"""
处理单条记录
Args:
record: 输入记录
Returns:
处理后的记录
"""
# 实现自定义处理逻辑
# 例如:实体链接、NLP处理等
entity_name = record.get('name')
# 调用NLP模型进行处理
processed_name = self.normalize_entity(entity_name)
record['normalized_name'] = processed_name
return record
def normalize_entity(self, name):
# 实现实体归一化逻辑
return name.strip().upper()7.4 项目结构最佳实践
your-kg-project/
├── schema/ # Schema定义
│ ├── entity_types/
│ │ ├── person.json
│ │ └── company.json
│ └── schema_draft.json
├── data/ # 数据文件
│ ├── raw/ # 原始数据
│ ├── processed/ # 处理后数据
│ └── mappings/ # 映射配置
├── builders/ # 构建脚本
│ ├── extract.py
│ ├── transform.py
│ └── load.py
├── reasoners/ # 推理规则
│ └── rules.kgdsl
├── processors/ # 自定义处理器
│ └── custom_processor.py
└── config/ # 配置文件
└── builder_config.json8. 常见问题
8.1 部署相关
Q: 如何切换图数据库从Neo4j到TuGraph?
A: 修改配置文件中的 cloudext.graphstore.url:
properties
# Neo4j
cloudext.graphstore.url=neo4j://host:7687?user=neo4j&password=pwd&database=neo4j
# TuGraph
cloudext.graphstore.url=tugraph://host:7687?user=admin&password=pwd&database=defaultQ: 如何配置分布式部署?
A: OpenSPG支持通过调度器进行分布式任务调度:
properties
# 使用外部调度器(如Kubernetes)
scheduler.handler.type=k8s
scheduler.metadata.store.type=mysql8.2 性能相关
Q: 如何优化大规模数据的构建性能?
A:
- 增加并行度:
workerNum参数设置更大值 - 使用批量写入:配置
batchSize - 启用缓存:配置Redis缓存
- 分片处理:将大文件拆分成多个小文件
json
{
"workerNum": 10,
"batchSize": 1000,
"enableCache": true
}Q: 查询性能慢怎么办?
A:
- 为常用属性添加索引
- 使用合适的IndexType(EXACT, TEXT, VECTOR等)
- 优化KGDSL查询语句
- 启用查询缓存
8.3 Schema相关
Q: 如何修改已有的Schema?
A: 使用 AlterOperation:
java
Property property = existingProperty;
property.setAlterOperation(AlterOperationEnum.UPDATE);
EntityType entityType = existingEntityType;
entityType.setAlterOperation(AlterOperationEnum.UPDATE);Q: 支持哪些AlterOperation?
A:
CREATE: 创建新的类型/属性/关系UPDATE: 更新已有的DELETE: 删除已有的
8.4 数据构建相关
Q: 支持哪些数据源格式?
A:
- CSV文件
- JSON文件
- 关系数据库(MySQL, PostgreSQL等)
- Hive表
- ODPS(阿里云MaxCompute)
- 自定义数据源(通过扩展接口)
Q: 如何处理脏数据?
A: 在Processor中实现数据清洗逻辑:
python
class DataCleanProcessor(BaseProcessor):
def process(self, record):
# 过滤空值
if not record.get('name'):
return None
# 数据标准化
record['name'] = record['name'].strip()
return record8.5 推理相关
Q: KGDSL语法在哪里查看?
A: 参考文档:
- OpenSPG用户手册 - KGDSL章节
- KGDSL语法文件:
reasoner/kgdsl-parser/src/main/antlr4/KGDSL.g4
Q: 如何调试推理规则?
A:
- 使用推理规则解释功能
- 查看执行计划
- 启用详细日志
properties
logging.level.com.antgroup.openspg.reasoner=DEBUG8.6 集成相关
Q: 如何与大语言模型(LLM)集成?
A: OpenSPG提供KAG(Knowledge Augmented Generation)能力:
python
from knext.kag import KAGEngine
# 初始化KAG引擎
kag = KAGEngine(project_id=1, llm_config={
'model': 'gpt-4',
'api_key': 'your-api-key'
})
# 知识增强查询
result = kag.query("阿里巴巴的创始人是谁?")Q: 支持哪些向量数据库?
A: 通过IndexType.VECTOR支持:
- Neo4j Vector Index
- Elasticsearch Vector Search
- 自定义向量数据库(通过扩展接口)
附录
A. 参考资源
- 官方文档: https://openspg.yuque.com/ndx6g9/docs
- GitHub仓库: https://github.com/OpenSPG/openspg
- 官方网站: https://openspg.github.io/v2
- SPG白皮书: https://openspg.github.io/v2/blog/design_philosophy/white_paper/openspg
B. 示例项目
- 企业供应链图谱:https://openspg.yuque.com/ndx6g9/docs/dq9ptys5u5dvh0ia
- 黑产挖掘图谱:https://openspg.yuque.com/ndx6g9/docs/xq9fwzuqr272smno
- 医疗知识图谱:https://openspg.yuque.com/ndx6g9/docs/bo7b9kwhkl6zynsh
C. 社区支持
- Issue跟踪: https://github.com/OpenSPG/openspg/issues
- 讨论区: https://github.com/OpenSPG/openspg/discussions
D. 贡献指南
查看贡献指南:https://openspg.yuque.com/ndx6g9/docs/yv8rahc3dewb1gy8
E. 引用
如果您在研究中使用OpenSPG,请引用:
bibtex
@article{liang2024kag,
title={KAG: Boosting LLMs in Professional Domains via Knowledge Augmented Generation},
author={Liang, Lei and Sun, Mengshu and Gui, Zhengke and Zhu, Zhongshu and Jiang, Zhouyu and Zhong, Ling and Zhao, Peilong and Bo, Zhongpu and Yang, Jin and others},
journal={arXiv preprint arXiv:2409.13731},
year={2024}
}版本信息
- 文档版本: 1.0
- OpenSPG版本: 0.8
- 最后更新: 2025-12-13
许可证
本项目采用 Apache License 2.0 开源协议。