# NER 服务使用指南

本文档介绍 NER（命名实体识别）服务的使用方法。

## 概述

NER 服务提供以下功能：

1. **实体提取**：从文本中识别人名、机构、地点、日期、数值、设备等实体
2. **关系抽取**：从实体间抽取语义关系
3. **自动集成**：文档解析完成后自动触发 NER，将结果保存到图数据库

## 架构

```
文件上传 → 文档解析 → 文本存储 → RAG 索引
                              ↓
                         发布事件
                              ↓
                         NER 监听器
                              ↓
                    调用 Python NER 服务
                              ↓
                    保存到图数据库 (graph_nodes, graph_relations)
```

## 快速开始

### 1. 启动 Python NER 服务

```bash
cd python-services/ner-service

# 安装依赖
pip install -r requirements.txt

# 启动服务
uvicorn app.main:app --host 0.0.0.0 --port 8001 --reload
```

### 2. 验证服务

```bash
# 健康检查
curl http://localhost:8001/health

# 运行端到端测试
./test/test_ner_e2e.sh
```

## API 接口

### Python NER 服务

| 方法 | 路径 | 说明 |
|------|------|------|
| GET | `/health` | 健康检查 |
| POST | `/ner/extract` | 提取实体和关系 |
| POST | `/ner/relations` | 从实体中抽取关系 |

### Java NER 接口

| 方法 | 路径 | 说明 |
|------|------|------|
| POST | `/api/ner/extract` | 提取实体（同步） |
| POST | `/api/ner/extract/async` | 提取实体（异步） |
| POST | `/api/ner/relations` | 提取关系 |
| POST | `/api/ner/document/{documentId}` | 对文档执行 NER 并保存 |
| POST | `/api/ner/document/{documentId}/async` | 异步对文档执行 NER |

### 图数据库接口

| 方法 | 路径 | 说明 |
|------|------|------|
| GET | `/api/graph/documents/{documentId}/nodes` | 获取文档节点 |
| GET | `/api/graph/documents/{documentId}/stats` | 获取图统计 |
| POST | `/api/graph/nodes` | 创建节点 |
| POST | `/api/graph/relations` | 创建关系 |

## 使用示例

### 实体提取

```bash
curl -X POST http://localhost:8001/ner/extract \
  -H "Content-Type: application/json" \
  -d '{
    "documentId": "doc-001",
    "text": "2024年5月15日，成都检测公司完成了环境监测项目。",
    "extractRelations": true
  }'
```

响应：
```json
{
  "documentId": "doc-001",
  "entities": [
    {
      "name": "2024年5月15日",
      "type": "DATE",
      "value": "2024年5月15日",
      "position": {"charStart": 0, "charEnd": 11, "line": 1},
      "confidence": 0.8
    },
    {
      "name": "成都检测公司",
      "type": "ORG",
      "value": "成都检测公司",
      "position": {"charStart": 12, "charEnd": 18, "line": 1},
      "confidence": 0.8
    }
  ],
  "relations": [...],
  "entityCount": 2,
  "relationCount": 1,
  "processingTime": 150,
  "success": true
}
```

### 对文档执行 NER

```bash
curl -X POST "http://localhost:5232/api/ner/document/doc-001?userId=user-001"
```

## 实体类型

| 类型 | 说明 | 示例 |
|------|------|------|
| PERSON | 人名 | 张经理、李总 |
| ORG | 机构 | 成都检测公司 |
| LOC | 地点 | 成都市高新区 |
| DATE | 日期 | 2024年5月15日 |
| NUMBER | 数值 | 50分贝、100万元 |
| DEVICE | 设备 | 噪音检测设备 |
| PROJECT | 项目 | 环境监测项目 |
| TERM | 专业术语 | - |

## 关系类型

| 类型 | 说明 |
|------|------|
| 负责 | 主体负责某事 |
| 属于 | 隶属关系 |
| 位于 | 位置关系 |
| 包含 | 包含关系 |
| 使用 | 使用关系 |
| 检测 | 检测关系 |

## 配置说明

### application.properties

```properties
# NER 自动提取配置
ner.auto-extract.enabled=true

# Python NER 服务配置
ner.python-service.url=http://localhost:8001
ner.python-service.timeout=60000
ner.python-service.max-retries=3
```

### 环境变量

| 变量名 | 说明 | 默认值 |
|--------|------|--------|
| NER_SERVICE_URL | NER 服务地址 | http://localhost:8001 |
| NER_MODEL | NER 模型类型 | rule |
| USE_GPU | 是否使用 GPU | false |

## NER 模型模式

### 1. rule 模式（默认）

基于正则表达式规则的简单 NER，适合开发测试：

- 优点：无需额外依赖，启动快速
- 缺点：准确率有限，仅支持常见实体类型

### 2. spacy 模式

使用 spaCy 中文模型：

```bash
pip install spacy
python -m spacy download zh_core_web_sm
```

### 3. api 模式

调用外部 API（如 DeepSeek/Qwen）进行 NER：

```properties
NER_MODEL=api
API_BASE_URL=https://dashscope.aliyuncs.com/compatible-mode/v1
API_KEY=your-api-key
API_MODEL=qwen-plus
```

## 故障排除

### NER 服务连接失败

1. 确认 NER 服务已启动：`curl http://localhost:8001/health`
2. 检查防火墙设置
3. 检查配置文件中的服务地址

### 实体提取结果为空

1. 确认文本内容不为空
2. 检查文本是否包含可识别的实体
3. 查看 NER 服务日志

### 关系抽取失败

1. 确认至少有 2 个实体
2. 检查实体位置信息是否正确

## 开发计划

- [ ] 集成 spaCy 中文模型
- [ ] 集成 Transformers NER 模型（如 Qwen-NER）
- [ ] 实现 API 模式（DeepSeek/Qwen）
- [ ] 支持自定义实体类型
- [ ] 优化关系抽取准确率
- [ ] 添加实体去重和合并逻辑
