通过知识图谱解决LLM在提取评价维度时的幻觉问题

发布于 2025-10-16  1 次阅读


一、项目目标

我们希望实现这样一个自动化流程:

  1. 用户提交一段产品描述文本
  2. LLM 自动识别该文本对应的产品类别(如“手机”)。
  3. 系统查询 Neo4j 知识图谱,找到该类别下的评价维度(如电池、屏幕、CPU 等)。
  4. LLM 根据这些维度,对文本中涉及的维度进行情感判定(正向/负向/中立)。
  5. 最后结果写回 Neo4j,形成可视化、可追溯的分析图谱。

二、系统架构

┌────────────────────────┐
│           用户输入文本             │
└────────────────────────┘
              │
              ▼
┌───────────────────────┐
│          LLM 产品识别模块               │
│ → 输出:产品类别(如手机)     │
└───────────────────────┘
              │
              ▼
┌────────────────────────┐
│           Neo4j 图谱查询模块         │
│ → 输出:类别对应的维度及别名列表       │
└────────────────────────┘
              │
              ▼
┌───────────────────────┐
│         LLM 维度情感分析模块         │
│ → 输出:每个维度的情感极性、证据       │
└───────────────────────┘
              │
              ▼
┌───────────────────────┐
│           Neo4j 图谱写回模块       │
│ → 形成“Doc-维度”情感关系网络       │
└───────────────────────┘


三、Neo4j 环境部署

1. docker-compose.yml

services:
neo4j:
  image: neo4j:latest
  container_name: neo4j
  volumes:
    - ./neo4j/logs:/logs
    - ./neo4j/config:/config
    - ./neo4j/data:/data
    - ./neo4j/plugins:/plugins
    - ./neo4j/import:/import
  environment:
    - NEO4J_AUTH=neo4j/your_password
    - NEO4J_PLUGINS=["apoc"]
  ports:
    - "7474:7474"
    - "7687:7687"
  restart: always

2. 启动

mkdir -p neo4j/{logs,config,data,plugins,import}
docker compose up -d

访问:http://localhost:7474


四、图谱建模

节点与关系

类型标签示例说明
产品类别Category手机产品类型
评价维度Dimension电池容量、屏幕各评价维度
别名词汇Alias电池、续航维度同义词
文本Doc用户评论文本被分析的语料

关系定义:

  • (Category)-[:HAS_DIMENSION]->(Dimension)
  • (Dimension)-[:HAS_ALIAS]->(Alias)
  • (Doc)-[:MENTIONS {sentiment,score,evidence}]->(Dimension)

初始化数据示例

MERGE (c:Category {name:'手机'});

UNWIND [
 '电池容量','续航','屏幕','摄像头','CPU型号',
 '散热','充电速度','信号','做工','重量'
] AS dim
MERGE (d:Dimension {name:dim})
MERGE (c)-[:HAS_DIMENSION]->(d);

MATCH (d:Dimension {name:'电池容量'})
MERGE (d)-[:HAS_ALIAS]->(:Alias {name:'电池'})
MERGE (d)-[:HAS_ALIAS]->(:Alias {name:'续航'});

五、LLM 提示词设计

1. 类别识别 Prompt

你是一个产品文本分类器。给你一段中文文本,请判断它描述的主要产品类别,且从以下候选中选择最合适的一类:
["手机","笔记本电脑","平板","耳机","智能手表","相机","家用路由器","显示器","其他"]
只输出 JSON:
{"category":"<候选之一>","confidence":0.0-1.0,"rationale":"一句话理由"}

2. 维度情感分析 Prompt

给定一段产品文本和一组评价维度,请识别涉及到的维度、情感极性(positive|negative|neutral),
并抽取原文短句作为 evidence。仅返回 JSON 数组:
[
{"dimension":"屏幕","sentiment":"negative","score":-0.4,"evidence":"屏幕亮度在户外略差"}
]

六、Python 示例:数据流

from neo4j import GraphDatabase
import json

def analyze_text(text, llm, kg):
   # 1. LLM识别产品类别
   cat = llm.detect_category(text)
   dims = kg.get_dimensions(cat["category"])
   
   # 2. LLM情感分析
   result = llm.analyze_sentiment(text, dims)
   
   # 3. 写入Neo4j
   kg.write_mentions(text, result)
   return result

七、查询与可视化

查询维度情感平均分

MATCH (:Category {name:'手机'})-[:HAS_DIMENSION]->(d)<-[r:MENTIONS]-(:Doc)
RETURN d.name AS dimension, avg(r.score) AS avgScore, count(r) AS mentions
ORDER BY avgScore DESC;

查询负面样本

MATCH (d:Dimension {name:'电池容量'})<-[r:MENTIONS]-(doc:Doc)
WHERE r.sentiment='negative'
RETURN doc.id, r.evidence, r.score;