结合高德地图API和通义千问大语言模型,能够将自然语言地址智能解析为结构化数据,并提供地图定位功能。
- 智能地址解析: 将自然语言地址解析为结构化字段(城市、区县、兴趣点、门牌号等)
- 多源数据融合: 结合高德地图API和通义千问模型,提供高精度的地址匹配
- Web界面: 提供友好的Web界面进行地址解析和结果展示
- RESTful API: 支持API调用,便于集成到
- 地图定位: 集成高德地图,可视化显示解析结果
- 私有化地址库:支持私有化地址库功能,支持地图点选地址录入,支持多标签管理,召回时优选选取
- Docker部署: 支持Docker容器化部署
AddrResolver/
├── app.py # Flask Web 入口
├── resolver.py # 地址解析主流程
├── config.py # 环境变量与日志配置
├── requirements.txt # Python 依赖
├── Dockerfile
├── docker-compose.yml
├── address.db # 示例地址库
├── .env # 环境变量示例
├── docs/
│ └── address_resolver.md
├── func/
│ ├── amap_call.py # 高德 API 封装
│ ├── qwen_call.py # 通义千问调用
│ └── struct_llm_call.py # 结构化 LLM 调用
├── lora/
│ ├── bio2sft.py
│ ├── build_sft_from_adm.py
│ └── … # SFT 训练脚本与数据
├── prompts/
│ └── struct_prompt.md # LLM 提示词
├── static/
│ └── swagger/ # OpenAPI 文档
├── templates/
│ ├── index.html
│ └── address.html
├── test/
│ ├── test_address_db.py
│ ├── test_address_resolver.py
│ └── test_address_resolver_real.py
├── util/
│ ├── address_db.py
│ ├── geo.py
│ └── similarity.py
└── tcl/
├── address.db
└── data_validation_1.ipynb
flowchart TD
%% ----------- 阶段1:优先召回 -----------
subgraph Phase1[阶段1:优先召回]
direction LR
A[📥 输入自然语言地址]:::input --> LDB[📚 本地地址库召回]:::proc
LDB -- 命中 --> OUT1[📤 返回结构化结果]:::output
%% 召回失败 → 高德查询
LDB -- 未命中 --> AMAP[🗺️ 调用高德接口查询]:::api
AMAP --> TOP1[四级行政区划相同 + POI高度相似]:::proc
TOP1 -- 是 --> OUT1[📤 返回结果]:::output
end
Phase1 -- 未命中 --> Phase2
%% ----------- 阶段2:地址大模型结解析 -----------
subgraph Phase2[阶段2:地址大模型结构化解析]
B[Qwen3 LORA + HF TGI]:::llm -->|结构化字段| B1[行政区划]:::field
B --> B2[道路 + 功能区]:::field
B --> B3[POI]:::field
B --> B4[建筑层级]:::field
B --> B5[辅助信息]:::field
B --> B6[杂项]:::field
end
Phase2 -.-> Phase3
%% ----------- 阶段3:高德API精确搜索 -----------
subgraph Phase3[阶段3:高德API精确搜索]
direction LR
D1[D+AP 组合搜索]:::proc
D1 --> G1[高德输入提示API<br>/v3/assistant/inputtips]:::api
G1 --> C1{结果≥3个?}:::cond
C1 -- 是 --> RES[📤 返回候选POI]:::output
C1 -- 否 --> D2[仅AP字段搜索]:::proc
D2 --> G1
end
Phase3 -- 没有候选结果 --> Phase4
Phase3 -.-> Phase5
%% ----------- 阶段4:周边搜索 Fallback -----------
subgraph Phase4[阶段4:周边搜索 Fallback]
direction LR
P1[锚点定位]:::proc
P1 --> G2[高德地理编码API<br>/v3/geocode/geo]:::api
P2[关键词提取 U+AP+I]:::proc
G2 --> G3[高德周边搜索API<br>/v3/place/around]:::api
P2 --> G3
G3 -- 存在I字段 --> L1[通义千问匹配候选POI]:::llm
G3 -- 无I字段 --> R2[候选POI结果]:::output
L1 --> R2
end
Phase4 -.-> Phase5
%% ----------- 阶段5:智能匹配算法 -----------
subgraph Phase5[阶段5:智能匹配算法]
SIM[重点语义单元相似度]:::algo --> CALC[最终得分]:::calc
LOC[空间辅助得分]:::algo --> CALC
end
Phase5 -.-> Phase6
%% ----------- 阶段6:结果优化 -----------
subgraph Phase6[阶段6:结果优化]
direction LR
DEDUP[POI ID去重]:::proc --> REGEOCODE[高德逆地理编码API<br>/v3/geocode/regeo]:::api
REGEOCODE --> PERF[性能监控&耗时记录]:::proc
PERF --> OUT2[📤 输出最终结构化结果]:::output
end
%% ----------- 样式定义 -----------
classDef input fill:#e3f2fd,stroke:#2196f3,stroke-width:2px,color:#222;
classDef llm fill:#e8f5e9,stroke:#388e3c,stroke-width:2px,color:#222;
classDef field fill:#fffde7,stroke:#fbc02d,stroke-width:1.5px,color:#555;
classDef proc fill:#f1f8e9,stroke:#689f38,stroke-width:1.5px,color:#222;
classDef api fill:#fff3e0,stroke:#ff9800,stroke-width:1.5px,color:#222;
classDef cond fill:#ffe0b2,stroke:#fb8c00,stroke-width:1.5px,color:#a67404;
classDef output fill:#ede7f6,stroke:#7e57c2,stroke-width:2px,color:#2d1457;
classDef algo fill:#fce4ec,stroke:#e91e63,stroke-width:1.5px,color:#c2185b;
classDef calc fill:#ede7f6,stroke:#8e24aa,stroke-width:2px,color:#222;
本项目使用了CCKS2021中文地址要素解析数据集的《中文地址要素解析标注规范》,具体如下:
- 行政区划层级
prov:省级行政区(省/自治区/直辖市)。city:地级行政区(地级市/地区/自治州)。district:县级行政区(市辖区/县级市/县)。town:乡级行政区(镇/街道/乡)。community:社区/行政村/自然村。village_group:村内的“组/队/社”(数字编号)。
- 功能区与道路体系
devzone:各类开发区/产业园/度假区等功能区。road:有正式名称的道路(路/街/巷/弄/隧道/高架等;步行街/商业街默认按 road)。roadno:路号(道路门牌号)。intersection:道路路口/出入口(与road必同时出现)。
- POI 层级
poi:兴趣点(小区/园区/大厦/商铺等)。subpoi:子兴趣点/分区/期/门/苑等。
- 建筑层级(自上而下)
houseno:楼栋/幢/号楼;农村门牌也归此。cellno:单元(含“甲乙丙丁/东西/一单元”等)。floorno:楼层/层。roomno:房号/户号/商铺号等。detail:楼栋/单元/楼层/房间层级不明的整体串(如12-3-1001)。
- 辅助定位信息
assist:普通辅助词(如“附近”等定性描述/提示词)。distance:带数量单位的距离(米/千米/“几十米”等)。direction:方位词(如“东/东北”等,文档在示例中使用)。
- 杂项
redundant:非地址要素/冗余内容(人名、电话、邮编、配送提示、连接词“与”等;标点也归此)。others:规范未覆盖但确属地址元素的内容(如山/岛等;港澳台地址可整体记为others)。
-
LoRA 训练
参见lora/readme.md,按照数据准备(bio2sft.py/build_sft_from_adm.py)→ 合并生成train.jsonl→ 运行train_hf_qlora.py的流程完成指令微调。默认脚本针对 Qwen3-8B,建议使用两张 24GB GPU(或更高配置),训练产物保存在outputs/qwen3_8b_addr_qlora/,核心训练语料来自 CCKS2021中文地址要素解析数据集。 -
模型下载
-
构建结构化推理容器
func/struct_llm_call.py对接 HuggingFace TGI 的/generate接口,可将合并后的模型挂载到官方镜像:docker run --gpus all --shm-size 1g -p 8080:80 \ -v $(pwd)/outputs/qwen3_8b_addr_merged:/data \ ghcr.io/huggingface/text-generation-inference:latest \ --model-id /data \ --dtype bfloat16 \ --num-shard 2 \ --max-input-tokens 2048 --max-total-tokens 2304服务启动后可通过
curl http://127.0.0.1:8080/health或运行python lora/infer.py "上海市徐汇区佳安公寓宛平南路0001号楼"验证 XML 标签输出是否正常。 -
更新环境变量
修改根目录.env,保证键名与代码一致:AMAP_KEY=高德Web服务密钥 AMAP_WEB_KEY=高德JS SDK密钥 LLM_API_KEY=阿里云百炼API密钥 QWEN_MODEL=qwen3-8b STRUCT_LLM_URL=http://127.0.0.1:8080 STRUCT_LLM_TOKEN=如需鉴权则填写Bearer Token,否则留空
若旧环境中使用了
STRUCT_LLM等变量名,请同步改为STRUCT_LLM_URL,避免推理阶段读取失败。
系统集成了以下4个高德地图API接口:
| API接口 | 接口地址 | 主要功能 | 使用场景 |
|---|---|---|---|
| 输入提示API | /v3/assistant/inputtips |
模糊搜索POI,支持城市限定 | 精确搜索阶段,使用D+AP字段组合搜索 |
| 地理编码API | /v3/geocode/geo |
将地址文本转换为经纬度坐标 | 周边搜索的锚点定位 |
| 逆地理编码API | /v3/geocode/regeo |
将经纬度坐标转换为详细地址信息 | 补充POI的乡镇街道等详细信息 |
| 周边搜索API | /v3/place/around |
以指定坐标为中心搜索周边POI | Fallback阶段,当精确搜索无结果时使用 |
- 使用
D + AP字段组合作为搜索关键词 - 调用高德输入提示API进行精确匹配
- 如果结果少于3个,则使用
AP字段单独搜索
当精确搜索无结果时,系统启动周边搜索:
- 锚点定位: 使用高德地理编码API,优先使用
AP字段,失败则使用D字段 - 关键词提取: 从
U、AP、I字段中提取搜索关键词 - 周边搜索: 调用高德周边搜索API,以锚点为中心,使用提取的关键词搜索周边POI
- 大模型辅助: 当存在辅助信息(
I字段)时,调用通义千问判断各候选POI的匹配程度
系统使用多维度相似度计算:
- 文本相似度 (70%权重): 基于分词和关键词重叠率
- 空间辅助得分 (30%权重): 基于大模型对辅助信息的理解
最终得分 = 0.7 × 文本相似度 + 0.3 × 空间辅助得分
- 自动去重:基于POI ID合并搜索结果
- 逆地理编码:使用高德逆地理编码API补充乡镇街道等详细信息
- 性能监控:记录处理耗时
系统返回的JSON对象包含以下字段:
| 字段 | 类型 | 说明 |
|---|---|---|
id |
string | POI的唯一标识符 |
name |
string | POI名称 |
address |
string | POI详细地址 |
location |
string | 经纬度坐标(经度,纬度) |
regeo |
object | 逆地理编码信息(乡镇街道等) |
similarity |
float | 文本相似度得分(0-100) |
auxiliary |
float | 空间辅助得分(0-100) |
score |
float | 最终匹配得分(0-100) |
duration |
float | 处理耗时(秒) |
- Python 3.10+
- Docker (可选,用于容器化部署)
git clone <repository-url>
cd AddrResolverpip install -r requirements.txt复制配置文件模板并填入您的API密钥:
cp config.ini.sample config.ini编辑 config.ini 文件:
[key]
amap_key = 您的高德地图API密钥
llm_api_key = 您的阿里云百炼API密钥
qwen_model = qwen-turbo-2025-04-28获取API密钥:
python app.py访问 http://localhost:5000 即可使用Web界面。
docker build -t scisaga/addr-resolver:latest .docker push scisaga/addr-resolver:latest- 设置环境变量(创建
.env文件):
AMAP_KEY=高德地图API密钥
LLM_API_KEY=阿里云百炼API密钥
QWEN_MODEL=qwen-turbo-2025-04-28- 启动服务:
docker compose up -d --pull always- 访问应用:
打开浏览器访问 http://localhost:5000
- 在输入框中输入需要解析的地址
- 点击"解析"按钮
- 系统将返回结构化的解析结果和地图定位
GET /api/resolve?addr=地址文本示例:
curl "http://localhost:5000/api/resolve?addr=浙江宁波市慈溪市长河镇长河镇云海村陆家路南3号"响应示例:
{
"id": "B0FFJQXXXX",
"name": "云海村南3号",
"address": "浙江省宁波市慈溪市长河镇云海村陆家路南3号",
"location": "121.594637,29.725989",
"regeo": {
"country": "中国",
"province": "浙江省",
"city": "宁波市",
"district": "慈溪市",
"township": "长河镇"
},
"similarity": 85.6,
"auxiliary": 0.0,
"score": 59.9,
"duration": 2.34
}| 变量名 | 说明 | 默认值 |
|---|---|---|
AMAP_KEY |
高德地图API密钥 | 从config.ini读取 |
LLM_API_KEY |
阿里云百炼API密钥 | 从config.ini读取 |
QWEN_MODEL |
通义千问模型名称 | qwen-turbo-2025-04-28 |
日志文件保存在 logs/ 目录下:
address_resolver.log- 地址解析相关日志
项目包含测试文件:
# 运行单元测试
python test_address_resolver.py
# 运行真实场景测试
python test_address_resolver_real.py欢迎提交Issue和Pull Request来改进这个项目。
本项目采用MIT许可证。