# NER Service

命名实体识别（NER）服务，提供实体提取和关系抽取功能。

## 功能特性

- 实体提取：从文本中识别人名、机构、地点、日期、数值、设备等实体
- 关系抽取：从实体间抽取语义关系
- 多模式支持：
  - **rule**：基于规则的简单 NER（开发测试用，速度快但准确率低）
  - **ollama**：使用本地 Ollama LLM（推荐生产环境，准确率高）
  - **api**：使用远程 API（如百炼、DeepSeek）
- 长文本自动分块处理

## 快速开始

### 1. 安装依赖

```bash
cd python-services/ner-service
pip install -r requirements.txt
```

### 2. 配置环境

```bash
# 复制配置文件
cp .env.example .env

# 编辑配置（选择 NER 模式）
vim .env
```

### 3. 启动服务

```bash
# 规则模式（默认，用于开发测试）
NER_MODEL=rule uvicorn app.main:app --host 0.0.0.0 --port 8001

# Ollama LLM 模式（推荐生产环境）
NER_MODEL=ollama OLLAMA_MODEL=qwen2.5:7b uvicorn app.main:app --host 0.0.0.0 --port 8001
```

### 4. 确保 Ollama 服务可用（如使用 ollama 模式）

```bash
# 安装 Ollama（如未安装）
curl -fsSL https://ollama.com/install.sh | sh

# 拉取推荐模型
ollama pull qwen2.5:7b

# 确认服务运行
curl http://localhost:11434/api/tags
```

## API 接口

### 健康检查

```
GET /health
```

### 实体提取

```
POST /ner/extract
Content-Type: application/json

{
  "documentId": "doc-001",
  "text": "待提取的文本内容...",
  "entityTypes": ["PERSON", "ORG", "LOC"],  // 可选
  "extractRelations": true
}
```

### 关系抽取

```
POST /ner/relations
Content-Type: application/json

{
  "documentId": "doc-001",
  "text": "原始文本",
  "entities": [...]  // 已提取的实体列表
}
```

## 实体类型

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

## 关系类型

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

## 配置说明

### 基础配置

| 配置项 | 说明 | 默认值 |
|--------|------|--------|
| NER_MODEL | NER 模型类型 (rule/ollama/api) | rule |
| LOG_LEVEL | 日志级别 | INFO |
| MAX_TEXT_LENGTH | 最大文本长度 | 50000 |

### Ollama 模式配置

| 配置项 | 说明 | 默认值 |
|--------|------|--------|
| OLLAMA_URL | Ollama 服务地址 | http://localhost:11434 |
| OLLAMA_MODEL | 使用的模型 | qwen2.5:7b |
| OLLAMA_TIMEOUT | 请求超时（秒） | 120 |
| CHUNK_SIZE | 分块大小（字符） | 2000 |
| CHUNK_OVERLAP | 分块重叠（字符） | 200 |

### 推荐模型

| 模型 | 大小 | 中文能力 | 特点 | 推荐场景 |
|------|------|----------|------|----------|
| **zeffmuks/universal-ner** | ~4.2GB | ⭐⭐⭐ | NER 专用，速度快 | **首选** |
| qwen2.5:7b | ~4.7GB | ⭐⭐⭐⭐⭐ | 通用 LLM，中文强 | 需要复杂理解 |
| qwen2.5:14b | ~9GB | ⭐⭐⭐⭐⭐ | 更强的通用能力 | 显存充足时 |

**UniversalNER vs 通用 LLM**:
- UniversalNER: 专为 NER 优化，输出简洁，速度快
- Qwen: 通用能力强，可输出详细信息（如位置），但较慢

## 测试

```bash
# 运行测试
pytest tests/ -v

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

## 开发计划

- [x] 基于规则的 NER
- [x] Ollama LLM 模式（支持长文本分块）
- [ ] 集成 spaCy 中文模型
- [ ] 集成 Transformers NER 模型
- [ ] 实现远程 API 模式（百炼）
- [ ] 优化关系抽取准确率
