Spaces:
Running
Running
feat: Add support for GPT-5.3 Chat Latest model in configuration and reasoning parameters
Browse files- config/environments/default.yaml +5 -1
- config/models.py +3 -1
- examples/gpt5_3_chat_latest_example.py +216 -0
- main.py +3 -0
config/environments/default.yaml
CHANGED
|
@@ -45,9 +45,11 @@ models:
|
|
| 45 |
# Generation Models
|
| 46 |
generation:
|
| 47 |
openai:
|
|
|
|
|
|
|
|
|
|
| 48 |
- name: "gpt-5.2"
|
| 49 |
display_name: "GPT-5.2"
|
| 50 |
-
default: true
|
| 51 |
- name: "gpt-5-mini"
|
| 52 |
display_name: "GPT-5 Mini"
|
| 53 |
- name: "gpt-4.1"
|
|
@@ -79,6 +81,8 @@ models:
|
|
| 79 |
# Analysis Models
|
| 80 |
analysis:
|
| 81 |
openai:
|
|
|
|
|
|
|
| 82 |
- name: "gpt-5.2"
|
| 83 |
display_name: "GPT-5.2"
|
| 84 |
- name: "gpt-5-mini"
|
|
|
|
| 45 |
# Generation Models
|
| 46 |
generation:
|
| 47 |
openai:
|
| 48 |
+
- name: "gpt-5.3-chat-latest"
|
| 49 |
+
display_name: "GPT-5.3 Chat Latest"
|
| 50 |
+
default: true
|
| 51 |
- name: "gpt-5.2"
|
| 52 |
display_name: "GPT-5.2"
|
|
|
|
| 53 |
- name: "gpt-5-mini"
|
| 54 |
display_name: "GPT-5 Mini"
|
| 55 |
- name: "gpt-4.1"
|
|
|
|
| 81 |
# Analysis Models
|
| 82 |
analysis:
|
| 83 |
openai:
|
| 84 |
+
- name: "gpt-5.3-chat-latest"
|
| 85 |
+
display_name: "GPT-5.3 Chat Latest"
|
| 86 |
- name: "gpt-5.2"
|
| 87 |
display_name: "GPT-5.2"
|
| 88 |
- name: "gpt-5-mini"
|
config/models.py
CHANGED
|
@@ -69,7 +69,9 @@ class ModelRegistry:
|
|
| 69 |
# Generic fine-tuned model
|
| 70 |
return 'GPT4o_FT'
|
| 71 |
|
| 72 |
-
if model_name == 'gpt-5.
|
|
|
|
|
|
|
| 73 |
return 'GPT5_2'
|
| 74 |
elif model_name == 'gpt-5-mini':
|
| 75 |
return 'GPT5_MINI'
|
|
|
|
| 69 |
# Generic fine-tuned model
|
| 70 |
return 'GPT4o_FT'
|
| 71 |
|
| 72 |
+
if model_name == 'gpt-5.3-chat-latest':
|
| 73 |
+
return 'GPT5_3_CHAT_LATEST'
|
| 74 |
+
elif model_name == 'gpt-5.2':
|
| 75 |
return 'GPT5_2'
|
| 76 |
elif model_name == 'gpt-5-mini':
|
| 77 |
return 'GPT5_MINI'
|
examples/gpt5_3_chat_latest_example.py
ADDED
|
@@ -0,0 +1,216 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
Приклад та тест використання GPT-5.3-chat-latest в проєкті Legal Position AI Analyzer
|
| 3 |
+
|
| 4 |
+
Параметри моделі:
|
| 5 |
+
- reasoning_effort: "low", "medium", "high"
|
| 6 |
+
- verbosity: "low", "medium", "high"
|
| 7 |
+
- store: False (не зберігати в історії OpenAI)
|
| 8 |
+
"""
|
| 9 |
+
|
| 10 |
+
import os
|
| 11 |
+
import sys
|
| 12 |
+
from openai import OpenAI
|
| 13 |
+
|
| 14 |
+
# Ініціалізація клієнта OpenAI
|
| 15 |
+
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
|
| 16 |
+
|
| 17 |
+
MODEL_NAME = "gpt-5.3-chat-latest"
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
def test_basic_connection():
|
| 21 |
+
"""Простий тест підключення до моделі."""
|
| 22 |
+
print(f"Тест підключення до {MODEL_NAME}...")
|
| 23 |
+
|
| 24 |
+
# NOTE: gpt-5.3-chat-latest supports only reasoning_effort="medium"
|
| 25 |
+
response = client.chat.completions.create(
|
| 26 |
+
model=MODEL_NAME,
|
| 27 |
+
messages=[
|
| 28 |
+
{"role": "developer", "content": "Ти - правовий асистент."},
|
| 29 |
+
{"role": "user", "content": "Дай коротке визначення правової позиції суду (1-2 речення)."}
|
| 30 |
+
],
|
| 31 |
+
reasoning_effort="medium",
|
| 32 |
+
verbosity="medium",
|
| 33 |
+
store=False,
|
| 34 |
+
max_completion_tokens=256
|
| 35 |
+
)
|
| 36 |
+
|
| 37 |
+
content = response.choices[0].message.content
|
| 38 |
+
print(f"Відповідь: {content}")
|
| 39 |
+
print(f"Використано токенів: {response.usage.total_tokens}")
|
| 40 |
+
return content
|
| 41 |
+
|
| 42 |
+
|
| 43 |
+
def generate_legal_position(
|
| 44 |
+
court_decision_text: str,
|
| 45 |
+
reasoning_effort: str = "medium",
|
| 46 |
+
verbosity: str = "medium"
|
| 47 |
+
):
|
| 48 |
+
"""
|
| 49 |
+
Генерація правової позиції з використанням GPT-5.3-chat-latest
|
| 50 |
+
|
| 51 |
+
Args:
|
| 52 |
+
court_decision_text: Текст судового рішення
|
| 53 |
+
reasoning_effort: Рівень reasoning ("low", "medium", "high")
|
| 54 |
+
verbosity: Рівень деталізації відповіді ("low", "medium", "high")
|
| 55 |
+
|
| 56 |
+
Returns:
|
| 57 |
+
Згенерована правова позиція у форматі JSON
|
| 58 |
+
"""
|
| 59 |
+
|
| 60 |
+
system_prompt = """Ти - експерт-правознавець, який аналізує судові рішення
|
| 61 |
+
та формує правові позиції Верховного Суду України."""
|
| 62 |
+
|
| 63 |
+
user_prompt = f"""
|
| 64 |
+
Проаналізуй наступне судове рішення та сформуй правову позицію:
|
| 65 |
+
|
| 66 |
+
<court_decision>
|
| 67 |
+
{court_decision_text}
|
| 68 |
+
</court_decision>
|
| 69 |
+
|
| 70 |
+
Поверни результат у форматі JSON з полями:
|
| 71 |
+
- title: заголовок правової позиції
|
| 72 |
+
- text: текст правової позиції
|
| 73 |
+
- proceeding: тип судочинства
|
| 74 |
+
- category: категорія справи
|
| 75 |
+
"""
|
| 76 |
+
|
| 77 |
+
response = client.chat.completions.create(
|
| 78 |
+
model=MODEL_NAME,
|
| 79 |
+
messages=[
|
| 80 |
+
{"role": "developer", "content": system_prompt},
|
| 81 |
+
{"role": "user", "content": user_prompt}
|
| 82 |
+
],
|
| 83 |
+
response_format={"type": "json_object"},
|
| 84 |
+
reasoning_effort=reasoning_effort,
|
| 85 |
+
verbosity=verbosity,
|
| 86 |
+
store=False,
|
| 87 |
+
max_completion_tokens=2048
|
| 88 |
+
)
|
| 89 |
+
|
| 90 |
+
return response.choices[0].message.content
|
| 91 |
+
|
| 92 |
+
|
| 93 |
+
def analyze_relevance(
|
| 94 |
+
legal_position: dict,
|
| 95 |
+
existing_positions: list,
|
| 96 |
+
reasoning_effort: str = "medium"
|
| 97 |
+
):
|
| 98 |
+
"""
|
| 99 |
+
Аналіз релевантності існуючих правових позицій з використанням GPT-5.3-chat-latest
|
| 100 |
+
|
| 101 |
+
Args:
|
| 102 |
+
legal_position: Згенерована правова позиція
|
| 103 |
+
existing_positions: Список існуючих правових позицій
|
| 104 |
+
reasoning_effort: Рівень reasoning ("low", "medium", "high")
|
| 105 |
+
|
| 106 |
+
Returns:
|
| 107 |
+
Аналіз релевантності у форматі JSON
|
| 108 |
+
"""
|
| 109 |
+
|
| 110 |
+
system_prompt = """Ти - експерт-аналітик правових позицій Верховного Суду України."""
|
| 111 |
+
|
| 112 |
+
positions_text = "\n\n".join([
|
| 113 |
+
f"[{i+1}] {pos['title']}: {pos['text']}"
|
| 114 |
+
for i, pos in enumerate(existing_positions)
|
| 115 |
+
])
|
| 116 |
+
|
| 117 |
+
user_prompt = f"""
|
| 118 |
+
Проаналізуй релевантність існуючих правових позицій до нової позиції:
|
| 119 |
+
|
| 120 |
+
Нова позиція:
|
| 121 |
+
{legal_position['title']}: {legal_position['text']}
|
| 122 |
+
|
| 123 |
+
Існуючі позиції:
|
| 124 |
+
{positions_text}
|
| 125 |
+
|
| 126 |
+
Поверни аналіз у форматі JSON з полями:
|
| 127 |
+
- relevant_positions: список релевантних позицій з обґрунтуванням
|
| 128 |
+
"""
|
| 129 |
+
|
| 130 |
+
response = client.chat.completions.create(
|
| 131 |
+
model=MODEL_NAME,
|
| 132 |
+
messages=[
|
| 133 |
+
{"role": "developer", "content": system_prompt},
|
| 134 |
+
{"role": "user", "content": user_prompt}
|
| 135 |
+
],
|
| 136 |
+
response_format={"type": "json_object"},
|
| 137 |
+
reasoning_effort=reasoning_effort,
|
| 138 |
+
verbosity="medium",
|
| 139 |
+
store=False,
|
| 140 |
+
max_completion_tokens=4000
|
| 141 |
+
)
|
| 142 |
+
|
| 143 |
+
return response.choices[0].message.content
|
| 144 |
+
|
| 145 |
+
|
| 146 |
+
# Запуск тестів
|
| 147 |
+
if __name__ == "__main__":
|
| 148 |
+
import json
|
| 149 |
+
|
| 150 |
+
if not os.getenv("OPENAI_API_KEY"):
|
| 151 |
+
print("ПОМИЛКА: Змінна OPENAI_API_KEY не встановлена.")
|
| 152 |
+
sys.exit(1)
|
| 153 |
+
|
| 154 |
+
# Тест 1: базове підключення
|
| 155 |
+
print("=" * 60)
|
| 156 |
+
print(f"ТЕСТ: {MODEL_NAME}")
|
| 157 |
+
print("=" * 60)
|
| 158 |
+
|
| 159 |
+
try:
|
| 160 |
+
test_basic_connection()
|
| 161 |
+
print("ТЕСТ 1 (підключення): OK\n")
|
| 162 |
+
except Exception as e:
|
| 163 |
+
print(f"ТЕСТ 1 (підключення): ПОМИЛКА - {e}\n")
|
| 164 |
+
sys.exit(1)
|
| 165 |
+
|
| 166 |
+
# Тест 2: генерація правової позиції
|
| 167 |
+
test_decision = """
|
| 168 |
+
ПОСТАНОВА ІМЕНЕМ УКРАЇНИ
|
| 169 |
+
|
| 170 |
+
Верховний Суд у складі колегії суддів Касаційного цивільного суду
|
| 171 |
+
розглянув у порядку письмового провадження справу за позовом фізичної особи
|
| 172 |
+
до банку про захист прав споживача.
|
| 173 |
+
|
| 174 |
+
Суд встановив, що банк нараховував комісію за обслуговування кредиту,
|
| 175 |
+
яка не була передбачена кредитним договором, що є порушенням прав споживача
|
| 176 |
+
відповідно до Закону України "Про захист прав споживачів".
|
| 177 |
+
"""
|
| 178 |
+
|
| 179 |
+
# NOTE: gpt-5.3-chat-latest підтримує лише reasoning_effort="medium"
|
| 180 |
+
print("Тест 2: Генерація правової позиції (reasoning_effort=medium)...")
|
| 181 |
+
try:
|
| 182 |
+
result = generate_legal_position(
|
| 183 |
+
court_decision_text=test_decision,
|
| 184 |
+
reasoning_effort="medium",
|
| 185 |
+
verbosity="medium"
|
| 186 |
+
)
|
| 187 |
+
parsed = json.loads(result)
|
| 188 |
+
print(f"Title: {parsed.get('title', 'N/A')}")
|
| 189 |
+
print(f"Category: {parsed.get('category', 'N/A')}")
|
| 190 |
+
print("ТЕСТ 2 (генерація): OK\n")
|
| 191 |
+
except Exception as e:
|
| 192 |
+
print(f"ТЕСТ 2 (генерація): ПОМИЛКА - {e}\n")
|
| 193 |
+
sys.exit(1)
|
| 194 |
+
|
| 195 |
+
# Тест 3: аналіз релевантності
|
| 196 |
+
print("Тест 3: Аналіз релевантності...")
|
| 197 |
+
existing = [
|
| 198 |
+
{
|
| 199 |
+
"title": "Про нарахування незаконних комісій банком",
|
| 200 |
+
"text": "Банк не має права нараховувати комісії, не передбачені договором."
|
| 201 |
+
}
|
| 202 |
+
]
|
| 203 |
+
try:
|
| 204 |
+
analysis = analyze_relevance(
|
| 205 |
+
legal_position=parsed,
|
| 206 |
+
existing_positions=existing,
|
| 207 |
+
reasoning_effort="medium"
|
| 208 |
+
)
|
| 209 |
+
print(f"Аналіз: {analysis[:200]}...")
|
| 210 |
+
print("ТЕСТ 3 (аналіз): OK\n")
|
| 211 |
+
except Exception as e:
|
| 212 |
+
print(f"ТЕСТ 3 (аналіз): ПОМИЛКА - {e}\n")
|
| 213 |
+
sys.exit(1)
|
| 214 |
+
|
| 215 |
+
print("=" * 60)
|
| 216 |
+
print("Всі тести пройшли успішно!")
|
main.py
CHANGED
|
@@ -97,6 +97,9 @@ def _build_openai_reasoning_params(
|
|
| 97 |
|
| 98 |
effort = _OPENAI_EFFORT_MAP.get(thinking_level.lower(), "medium")
|
| 99 |
if effort is not None:
|
|
|
|
|
|
|
|
|
|
| 100 |
params["reasoning_effort"] = effort
|
| 101 |
|
| 102 |
model_lower = model_name.lower()
|
|
|
|
| 97 |
|
| 98 |
effort = _OPENAI_EFFORT_MAP.get(thinking_level.lower(), "medium")
|
| 99 |
if effort is not None:
|
| 100 |
+
# gpt-5.3-chat-latest supports only "medium" for reasoning_effort
|
| 101 |
+
if "gpt-5.3" in model_name.lower() and effort != "medium":
|
| 102 |
+
effort = "medium"
|
| 103 |
params["reasoning_effort"] = effort
|
| 104 |
|
| 105 |
model_lower = model_name.lower()
|