Spaces:
Running
Running
File size: 5,506 Bytes
1a93d7a |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 |
"""配置模块,管理API密钥、代理设置和OpenAI客户端配置。
此模块包含以下主要功能:
- OpenAI API配置
- 代理服务器设置
- OpenAI客户端初始化
- API调用工具函数
- GPT响应解析函数
"""
import os
import json
from openai import OpenAI
from typing import List, Dict, Optional, Any, Union, Tuple
# API配置
# 注意:在实际生产环境中,应该从环境变量或配置文件中读取API密钥
# GeoNames API配置
GEONAMES_USERNAME = "demo" # 替换为你的GeoNames用户名
GEONAMES_API_BASE = "http://api.geonames.org"
# OpenAI API配置
# 从环境变量中获取API密钥,如果不存在则使用默认值(仅用于本地开发)
OPENAI_API_KEY = os.environ.get("OPENAI_API_KEY", "")
# 使用的GPT模型版本
GPT_MODEL = "gpt-4.1-mini"
# Proxy Configuration
# 从环境变量中获取代理设置,如果已经设置则不覆盖
if not os.environ.get('https_proxy'):
os.environ['https_proxy'] = os.environ.get('HTTPS_PROXY', '')
if not os.environ.get('http_proxy'):
os.environ['http_proxy'] = os.environ.get('HTTP_PROXY', '')
# Initialize OpenAI client
client = OpenAI(api_key=OPENAI_API_KEY)
def get_completion(messages: List[Dict[str, str]], model: str = GPT_MODEL, temperature: float = 0.5) -> Optional[str]:
"""调用OpenAI API获取回复。
使用配置的OpenAI客户端发送请求并获取回复。支持自定义模型和temperature参数。
Args:
messages (List[Dict[str, str]]): 消息列表,每个消息包含role和content
model (str, optional): 使用的GPT模型名称。默认为配置中的GPT_MODEL
temperature (float, optional): 采样温度,控制输出的随机性。默认为0.2
Returns:
Optional[str]: API返回的文本回复。如果请求失败则返回None
"""
try:
response = client.chat.completions.create(
model=model,
messages=messages,
temperature=temperature
)
return response.choices[0].message.content
except Exception as e:
print(f"Error in API call: {e}")
return None
def extract_json_from_markdown(response: str) -> str:
"""从Markdown代码块中提取JSON内容。
Args:
response (str): 可能包含Markdown代码块的响应文本
Returns:
str: 提取的JSON内容或原始响应
"""
if response and response.strip().startswith('```') and '```' in response:
# 提取代码块内容
code_content = response.split('```', 2)[1]
if code_content.startswith('json'):
code_content = code_content[4:].strip()
response = code_content.strip()
return response
def parse_json_response(response: str, default_value: Any = None) -> Any:
"""解析JSON响应,处理可能的解析错误。
Args:
response (str): JSON格式的响应文本
default_value (Any, optional): 解析失败时返回的默认值
Returns:
Any: 解析后的JSON对象或默认值
"""
if not response:
return default_value
# 首先尝试从Markdown中提取JSON
response = extract_json_from_markdown(response)
try:
return json.loads(response)
except json.JSONDecodeError as e:
print(f"\nWarning: Failed to parse JSON response: {e}")
print(f"Response was: {response[:100]}..." if len(response) > 100 else f"Response was: {response}")
return default_value
def parse_gpt_response(response: str, expected_fields: List[str] = None, field_defaults: Dict[str, Any] = None) -> Dict[str, Any]:
"""解析GPT响应,提取预期字段并应用默认值。
Args:
response (str): GPT响应文本
expected_fields (List[str], optional): 预期的字段列表
field_defaults (Dict[str, Any], optional): 字段默认值字典
Returns:
Dict[str, Any]: 包含所有预期字段的字典
"""
if field_defaults is None:
field_defaults = {}
# 解析JSON响应
result = parse_json_response(response, {})
# 如果没有指定预期字段,直接返回解析结果
if not expected_fields:
return result
# 确保返回所有预期字段
output = {}
for field in expected_fields:
output[field] = result.get(field, field_defaults.get(field))
return output
def parse_nested_json_response(response: str) -> Tuple[Dict[str, Any], bool]:
"""解析可能嵌套的JSON响应。
处理可能嵌套在Markdown代码块中的JSON字符串表示的JSON对象。
Args:
response (str): 可能包含嵌套JSON的响应文本
Returns:
Tuple[Dict[str, Any], bool]: 解析后的JSON对象和是否成功解析的标志
"""
# 首先从Markdown中提取内容
extracted = extract_json_from_markdown(response)
# 尝试解析JSON
try:
result = json.loads(extracted)
# 检查是否是JSON字符串表示的JSON对象
if isinstance(result, dict) and len(result) == 1 and next(iter(result.values())).startswith('{'):
key = next(iter(result.keys()))
try:
nested_json = json.loads(result[key])
return nested_json, True
except json.JSONDecodeError:
pass
return result, True
except json.JSONDecodeError as e:
print(f"\nWarning: Failed to parse JSON response: {e}")
return {}, False
|