123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146 |
- # coding:utf-8
- import json
- import re
- import requests
- def replace_province_with_code(response_data, mapping_file_path):
- """
- 将 response_data 中条件字段的 '单位' 替换为对应的省份代码。
- 参数:
- response_data (dict): 原始解析结果数据
- mapping_file_path (str): 映射 JSON 文件路径(格式为 代码 -> 省份名称)
- 返回:
- dict: 替换后的 response_data
- """
- # 加载映射表:代码 -> 名称
- with open(mapping_file_path, 'r', encoding='utf-8') as f:
- code_to_name = json.load(f)
- # 构造反向映射:名称 -> 代码
- name_to_code = {v: k for k, v in code_to_name.items()}
- # 获取单位原始值
- unit_name = response_data.get('条件', {}).get('单位', '')
- # 标准化名称(去掉“省”、“市”、“自治区”、“特别行政区”等后缀)
- def normalize_name(name):
- suffixes = ['省', '市', '自治区', '特别行政区']
- for suffix in suffixes:
- if name.endswith(suffix):
- return name.replace(suffix, '')
- return name
- normalized_name = normalize_name(unit_name)
- # 替换单位为代码
- if normalized_name in name_to_code:
- response_data['条件']['单位'] = name_to_code[normalized_name]
- else:
- print(f"⚠️ 未找到“{normalized_name}”对应的代码,保持原值。")
- return response_data
- def extract_valid_json_outside_think(text):
- # 去掉 <think>...</think> 中的内容
- cleaned = re.sub(r'<think>[\s\S]*?</think>', '', text)
- # 尝试从清理后的内容中提取所有可能的 JSON 块(以 { 开头,以 } 结尾)
- brace_stack = []
- json_start = None
- for i, char in enumerate(cleaned):
- if char == '{':
- if not brace_stack:
- json_start = i
- brace_stack.append('{')
- elif char == '}':
- if brace_stack:
- brace_stack.pop()
- if not brace_stack:
- json_str = cleaned[json_start:i + 1]
- try:
- return json.loads(json_str)
- except json.JSONDecodeError:
- continue
- raise ValueError("❌ 无法从 think 外部提取合法 JSON")
- OLLAMA_URL = 'http://192.168.31.210:11434/api/generate'
- model = "deepseek-r1:32b"
- # 提交API的地址
- MATCH_URL = 'http://192.168.31.19:8352/api/kg/match'
- prompt = """
- 现在我要让你在一个或者多个问句中抽取出三元组,其中条件包含:年份、月份、日、省份(问句中有哪些条件就写哪些条件,没有的无需添加到结果中),实体包含:送出电量、送出电量占售电量的比、送出均价、受入电量、送出电量占售电量的比、受入均价。注意:实体在问句中的表示可能不那么准确,请你判断出和我给你实体意思最相近的问句中的实体。
- 问句如下:
- 山东省2023年12月的送电量是多少?
- 输出格式为:
- {
- "问句": 问句,
- "实体": ["送出电量"],
- "条件": {
- "单位":"山东省",
- "年":"2024",
- "月":"1",
- "日":"1"
- }
- }
- 输出结果只显示上述内容,不输出其他任何东西。
- """
- # 2023年送出均价最高的是哪个省?
- # 2022年哪个省的送出平均价格最高?
- # 2024年新疆省的送电量是多少?
- payload = {
- "model": model,
- "prompt": prompt,
- "stream": False
- }
- response = requests.post(OLLAMA_URL, json=payload)
- result = response.json()
- print("完整的 API 返回数据:", result) # 打印整个 API 返回
- print("result['response'] 的值:", result["response"]) # 打印 response 的值
- print("result['response'] 的类型:", type(result["response"])) # 打印 response 的类型
- response_str = result["response"]
- # 解析 JSON
- try:
- response_data = extract_valid_json_outside_think(response_str)
- print("✅ 成功解析 JSON:", json.dumps(response_data, indent=2, ensure_ascii=False))
- print("解析成功:", response_data)
- updated_data = replace_province_with_code(response_data, '省间关系映射.json')
- print(updated_data)
- # 发送 JSON 到新的接口
- match_response = requests.post(MATCH_URL, json=updated_data)
- if match_response.status_code == 200:
- match_result = match_response.json()
- print("成功发送到 match 接口,返回结果:", match_response.json())
- # 提取并检查 match 接口的 'data'
- if match_result.get("code") == 200 and "data" in match_result:
- query_payload = match_result["data"]
- # 发送到 query 接口
- query_url = "http://localhost:5000/query"
- query_response = requests.post(query_url, json=query_payload)
- if query_response.status_code == 200:
- print("成功发送到 query 接口,返回结果:", query_response.json())
- else:
- print("发送到 query 接口失败,状态码:", query_response.status_code)
- print("返回内容:", query_response.text)
- else:
- print("match 接口返回的结果无效或缺少 'data' 字段:", match_result)
- else:
- print("发送到 match 接口失败,状态码:", match_response.status_code)
- print("返回内容:", match_response.text)
- except json.JSONDecodeError as e:
- print("JSON 解析失败:", e)
- print("原始字符串:", repr(response_str))
|