g1-demo / g13.py
enotkrutoy's picture
Rename g1.py to g13.py
58e2f4d verified
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