This commit is contained in:
HuangHai
2026-01-17 10:52:13 +08:00
parent 552f3238d3
commit 24380767a4
9 changed files with 240 additions and 61 deletions

View File

@@ -1144,40 +1144,89 @@ class ReadImageKit:
# 寻找按钮坐标任务
button_task = asyncio.create_task(ReadImageKit.find_all_time_button_coordinate(image_url_or_path, device_info))
prompt = (
"仅输出JSON对象(不含任何说明文字)。"
"任务1:识别图片中充电站的完整名称(full_station_name)。"
f"提示:列表中看到的名称可能是截断的(例如“{station_name}”),请在图片上方找到最匹配的完整名称。"
"任务2:识别充电站的详细地址(address)。"
"寻找规则:地址通常紧跟在场站名称下方,或者在‘距离’图标(定位小图表)附近,或者在带有‘导航’按钮的同一行。"
"返回包含 full_station_name 和 address 字段的JSON对象,例如 {\"full_station_name\": \"完整名称\", \"address\": \"详细地址\"}。"
"如果找不到,对应字段返回空字符串。"
"严格返回纯JSON格式。"
)
prompt = (
"仅输出JSON对象(不含任何说明文字)。"
"任务1:识别图片中充电站的完整名称(full_station_name)。"
f"提示:列表中看到的名称可能是截断的(例如“{station_name}”),请在图片上方找到最匹配的完整名称。"
"任务2:识别充电站的详细地址(address)。"
"寻找规则:地址通常紧跟在场站名称下方,或者在“距离”图标(定位小图标)附近,或者在带有“导航”按钮的同一行。"
"若地址跨多行,请合并为一行返回,不要省略。"
"返回包含 full_station_name 和 address 字段的JSON对象,例如 {\"full_station_name\": \"完整名称\", \"address\": \"详细地址\"}。"
"如果图片中能看到任何疑似地址的文字(如街道名、路名、园区名),请尽量提取出来并填入 address,而不是返回空字符串。"
"实在无法确定时,对应字段返回空字符串。"
"严格返回纯JSON格式。"
)
result = {}
try:
resp = await ReadImageKit._client.chat.completions.create(
model=VL_MODEL_NAME,
timeout=30,
messages=[
{
"role": "user",
"content": [
{"type": "image_url", "image_url": img_input},
{"type": "text", "text": json.dumps(device_info, ensure_ascii=False)},
{"type": "text", "text": prompt},
],
},
],
)
content = resp.choices[0].message.content or ""
raw = ReadImageKit._extract_json(content)
result = json.loads(raw)
except Exception as e:
logger.error(f"解析地址失败 ({station_name}): {e}")
# 首次结果兜底与必要时的重试
if not isinstance(result, dict):
result = {}
full_name = str(result.get("full_station_name") or "").strip()
address = str(result.get("address") or "").strip()
if not full_name and not address:
try:
logger.info(f"地址首次解析为空,针对场站“{station_name}”进行重试。")
retry_prompt = (
"仅输出JSON对象(不含任何说明文字)。"
"请再次仔细查找图片中的充电站名称和详细地址,尽量不要返回空字符串。"
"即便地址不完整,也请返回你能看到的主要关键信息(如道路名、园区名、街道名等)。"
"返回格式仍为 {\"full_station_name\": \"完整名称或列表中的截断名称\", \"address\": \"尽量完整的详细地址\"}。"
"严格返回纯JSON格式。"
)
resp = await ReadImageKit._client.chat.completions.create(
model=VL_MODEL_NAME,
timeout=30,
messages=[
{
"role": "user",
"content": [
{"type": "image_url", "image_url": img_input},
{"type": "text", "text": json.dumps(device_info, ensure_ascii=False)},
{"type": "text", "text": retry_prompt},
],
},
],
)
content = resp.choices[0].message.content or ""
raw = ReadImageKit._extract_json(content)
retry_result = json.loads(raw)
if isinstance(retry_result, dict):
result = retry_result
full_name = str(result.get("full_station_name") or "").strip()
address = str(result.get("address") or "").strip()
except Exception as e:
logger.error(f"地址重试解析失败 ({station_name}): {e}")
# 最终兜底:至少回填一个名称,避免 None
if not full_name:
result["full_station_name"] = station_name or ""
if "address" not in result:
result["address"] = address
result = {}
try:
resp = await ReadImageKit._client.chat.completions.create(
model=VL_MODEL_NAME,
timeout=30,
messages=[
{
"role": "user",
"content": [
{"type": "image_url", "image_url": img_input},
{"type": "text", "text": json.dumps(device_info, ensure_ascii=False)},
{"type": "text", "text": prompt},
],
},
],
)
content = resp.choices[0].message.content or ""
raw = ReadImageKit._extract_json(content)
result = json.loads(raw)
except Exception as e:
logger.error(f"解析地址失败 ({station_name}): {e}")
# 合并按钮坐标
# 合并按钮坐标
try:
button_result = await button_task
if button_result: