Spaces:
Runtime error
Runtime error
import groq | |
import time | |
import os | |
import json | |
import logging | |
logging.basicConfig(level=logging.DEBUG) | |
client = groq.Groq() | |
def make_api_call(messages, max_tokens, is_final_answer=False, custom_client=None): | |
global client | |
if custom_client is not None: | |
client = custom_client | |
for attempt in range(3): | |
try: | |
if is_final_answer: | |
response = client.chat.completions.create( | |
model="llama3-8b-8192", | |
messages=messages, | |
max_tokens=max_tokens, | |
temperature=0.2 | |
) | |
return response.choices[0].message.content | |
else: | |
response = client.chat.completions.create( | |
model="llama3-8b-8192", | |
messages=messages, | |
max_tokens=max_tokens, # Используем переданный параметр max_tokens | |
temperature=0.2, | |
response_format={"type": "json_object"} | |
) | |
raw_response = response.choices[0].message.content | |
logging.debug(f"RAW JSON RESPONSE: {raw_response}") # Используем логирование для диагностики | |
try: | |
parsed_response = json.loads(raw_response) | |
except json.JSONDecodeError as e: | |
raise ValueError(f"Invalid JSON: {e}, content: {raw_response}") | |
if all(k in parsed_response for k in ("title", "content", "next_action")): | |
return parsed_response | |
else: | |
raise ValueError("JSON missing required keys") | |
except Exception as e: | |
if attempt == 2: | |
if is_final_answer: | |
return { | |
"title": "Error", | |
"content": f"Failed to generate final answer after 3 attempts. Error: {str(e)}" | |
} | |
else: | |
return { | |
"title": "Error", | |
"content": f"Failed to generate step after 3 attempts. Error: {str(e)}", | |
"next_action": "final_answer" | |
} | |
time.sleep(1) | |
def generate_response(prompt, custom_client=None): | |
""" | |
Генерирует ответ, возвращая промежуточные шаги рассуждений и финальный результат. | |
Функция является генератором: yield возвращает кортеж (steps, total_thinking_time). | |
""" | |
messages = [ | |
{"role": "system", "content": """ | |
Вы – интеллектуальный помощник, который анализирует и объясняет свои рассуждения на русском языке шаг за шагом. | |
### 🔹 Формат ответа | |
Ваш ответ должен быть строго в JSON-формате без дополнительного текста или форматирования (например, без ```json```). | |
Обязательные ключи: | |
- "title" – краткое название шага. | |
- "content" – описание действий. | |
- "next_action" – "continue" или "final_answer". | |
Пример: | |
{"title": "Анализ задачи", "content": "Выделение ключевых элементов...", "next_action": "continue"} | |
🔹 Дополнительные требования: | |
- Используйте русский язык. | |
- Избегайте Unicode-кодировок (например, писать "Привет", а не "\u041f\u0440\u0438..."). | |
"""}, | |
{"role": "user", "content": prompt}, | |
{"role": "assistant", "content": "Спасибо! Начинаю анализ..."} | |
] | |
steps = [] | |
step_count = 1 | |
total_thinking_time = 0 | |
while True: | |
start_time = time.time() | |
step_data = make_api_call(messages, max_tokens=500, custom_client=custom_client) # Передаём max_tokens | |
end_time = time.time() | |
thinking_time = end_time - start_time | |
total_thinking_time += thinking_time | |
steps.append((f"Step {step_count}: {step_data['title']}", step_data['content'], thinking_time)) | |
messages.append({"role": "assistant", "content": json.dumps(step_data)}) | |
if step_data.get('next_action') == 'final_answer' or step_count >= 25: | |
break | |
step_count += 1 | |
yield steps, None # Возвращаем промежуточные шаги без финального времени | |
messages.append({ | |
"role": "user", | |
"content": "Предоставьте окончательный ответ без формата JSON. Сохранить исходное форматирование из подсказки." | |
}) | |
start_time = time.time() | |
final_data = make_api_call(messages, max_tokens=1200, is_final_answer=True, custom_client=custom_client) | |
end_time = time.time() | |
thinking_time = end_time - start_time | |
total_thinking_time += thinking_time | |
steps.append(("Final Answer", final_data, thinking_time)) | |
yield steps, total_thinking_time | |