知识图谱
夜月AI应用平台 的知识图谱模块基于 Neo4j 构建,通过 LLM 自动提取实体和关系,构建智能知识网络,支持图遍历检索和1跳邻居扩展。
核心特性
- LLM实体关系提取:自动从文本中提取实体和关系
- HanLP中文分词:精准的中文分词支持
- 文档分块处理:可配置分块大小和重叠
- 实体去重:置信度评分,避免重复实体
- 图遍历检索:支持1跳邻居扩展
- 文档片段集成:检索结果关联原始文档
工作流程
mermaid
graph TD
A[文档上传] --> B[文档分块]
B --> C[实体提取]
C --> D[关系提取]
D --> E[实体去重]
E --> F[存入Neo4j]
G[用户查询] --> H[关键词提取]
H --> I[图遍历检索]
F --> I
I --> J[1跳邻居扩展]
J --> K[上下文构建]
K --> L[LLM生成回答]实体提取
LLM提取
使用LLM从文本中自动提取实体:
java
@Entity
public class KGEntity {
@Id
private Long id;
private String name; // 实体名称
private String type; // 实体类型(人物、地点、组织等)
private String description; // 实体描述
private Double confidence; // 置信度
private Map<String, Object> properties; // 额外属性
}实体类型
- PERSON - 人物
- ORGANIZATION - 组织
- LOCATION - 地点
- EVENT - 事件
- CONCEPT - 概念
- TECHNOLOGY - 技术
- PRODUCT - 产品
关系提取
java
@Entity
public class KGRelation {
@Id
private Long id;
private Long sourceId; // 源实体ID
private Long targetId; // 目标实体ID
private String type; // 关系类型
private String description; // 关系描述
private Double confidence; // 置信度
}关系类型
- WORKS_FOR - 工作于
- LOCATED_IN - 位于
- PART_OF - 属于
- CREATED_BY - 创建者
- USES - 使用
- RELATED_TO - 相关
- DEPENDS_ON - 依赖
文档处理
文档分块
yaml
kg:
chunking:
chunk-size: 1000 # 分块大小
chunk-overlap: 100 # 重叠大小HanLP中文分词
使用HanLP进行精准的中文分词:
java
@Service
public class ChineseTokenizerService {
public List<String> tokenize(String text) {
// HanLP分词
List<Term> terms = HanLP.segment(text);
return terms.stream()
.map(term -> term.word)
.collect(Collectors.toList());
}
}图遍历检索
1跳邻居扩展
从匹配的实体出发,扩展1跳邻居:
cypher
MATCH (e:Entity)-[r]-(neighbor:Entity)
WHERE e.name = $entityName
RETURN e, r, neighbor
LIMIT 10多跳遍历
支持多跳关系遍历:
cypher
MATCH path = (start:Entity)-[*1..3]-(end:Entity)
WHERE start.name = $startEntity
AND end.name = $endEntity
RETURN path使用场景
知识网络构建
java
// 上传文档构建知识图谱
kgService.buildFromDocument(documentId);
// 查询实体
KGEntity entity = kgService.findEntity("Nitemoon");
// 查询关系
List<KGRelation> relations = kgService.findRelations(entity.getId());智能问答
java
// 基于知识图谱的问答
KGQueryResult result = kgService.query(
"夜月AI应用平台 有哪些核心功能?"
);
// 获取答案
String answer = result.getAnswer();
List<KGEntity> entities = result.getEntities();
List<KGRelation> relations = result.getRelations();关系分析
java
// 分析实体关系
EntityNetwork network = kgService.analyzeRelations("人工智能");
// 获取关系图
Map<KGEntity, List<KGRelation>> graph = network.getGraph();代码示例
创建知识图谱
java
@Service
public class KnowledgeGraphService {
public KnowledgeGraph create(String name, String description) {
KnowledgeGraph kg = new KnowledgeGraph();
kg.setName(name);
kg.setDescription(description);
return kgRepository.save(kg);
}
}实体提取
java
@Service
public class EntityExtractionService {
public List<KGEntity> extractEntities(String text) {
// 使用LLM提取实体
String prompt = String.format(
"从以下文本中提取实体,返回JSON格式:\n%s",
text
);
String response = llmService.generate(prompt);
return parseEntities(response);
}
}关系提取
java
@Service
public class RelationExtractionService {
public List<KGRelation> extractRelations(String text, List<KGEntity> entities) {
// 使用LLM提取关系
String prompt = String.format(
"基于以下文本和实体,提取实体间关系:\n\n文本:%s\n\n实体:%s",
text,
JSON.toJSONString(entities)
);
String response = llmService.generate(prompt);
return parseRelations(response);
}
}图遍历查询
java
@Service
public class GraphTraversalService {
public List<KGEntity> findNeighbors(Long entityId, int hops) {
String cypher = String.format(
"MATCH (e:Entity)-[*1..%d]-(neighbor:Entity) " +
"WHERE id(e) = $entityId " +
"RETURN DISTINCT neighbor",
hops
);
return neo4jTemplate.findAll(cypher, Map.of("entityId", entityId));
}
}最佳实践
- 合理设置分块大小:根据文档类型调整,技术文档可以大一些
- 实体去重:使用置信度评分,合并相似实体
- 定期更新:知识图谱需要定期更新以保持时效性
- 监控质量:定期评估实体和关系的准确性
- 优化查询:为常用查询创建索引