File size: 7,284 Bytes
a6f9b2b
c19d193
a6f9b2b
 
 
6aae614
8fe992b
9b5b26a
 
a6f9b2b
9b5b26a
a6f9b2b
9b5b26a
a6f9b2b
9b5b26a
 
a6f9b2b
9b5b26a
a6f9b2b
 
 
 
8c01ffb
a6f9b2b
 
 
 
 
8c01ffb
ae7a494
a6f9b2b
ae7a494
e121372
a6f9b2b
 
 
 
13d500a
8c01ffb
9b5b26a
 
8c01ffb
a6f9b2b
861422e
 
a6f9b2b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8c01ffb
8fe992b
a6f9b2b
8c01ffb
 
 
 
 
 
861422e
8fe992b
 
9b5b26a
8c01ffb
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
from smolagents import CodeAgent, HfApiModel, load_tool
import yaml
from smolagents import tool
from duckduckgo_search import DDGS

from tools.final_answer import FinalAnswerTool

from Gradio_UI import GradioUI


@tool
def DuckDuckGoSearchTool(query: str) -> str:
    """
    Инструмент для поиска информации в интернете с помощью DuckDuckGo.

    Args:
        query: Поисковый запрос.
    """
    with DDGS() as ddgs:
        results = [r for r in ddgs.text(query, max_results=5)]  # Ограничиваем до 5 результатов
        if not results:
            return "По вашему запросу ничего не найдено."

        formatted_results = "\n\n".join(
            f"**Заголовок:** {r['title']}\n**Ссылка:** {r['href']}\n**Краткое содержание:** {r['body']}"
            for r in results
        )
    return formatted_results


final_answer = FinalAnswerTool()

model = HfApiModel(
    max_tokens=2096,
    temperature=0.5,
    model_id='Qwen/Qwen2.5-Coder-32B-Instruct',  # Возможно, эта модель перегружена
    custom_role_conversions=None,
)

# Import tool from Hub
image_generation_tool = load_tool("agents-course/text-to-image", trust_remote_code=True)


with open("prompts.yaml", 'r') as stream:
    prompt_templates = yaml.safe_load(stream)

#  Ключевое изменение: обновленный system_prompt в стиле Thought-Action-Observation
system_prompt = """
Ты — профессиональный поисковый ассистент, аналог Perplexity. Твоя задача — предоставлять исчерпывающие и точные ответы на запросы пользователей, основываясь на информации из нескольких источников в интернете.

Ты должен действовать в цикле **Thought-Action-Observation**:

*   **Thought:**  Сначала обдумай задачу.  Определи, какую информацию нужно найти и какие шаги предпринять.  Сформулируй план действий.  *Всегда начинай с Thought.*
*   **Action:**  Выполни действие, используя доступные инструменты.  В твоем распоряжении *только* инструмент `DuckDuckGoSearchTool` для поиска и `final_answer` для окончательного ответа.  Используй `DuckDuckGoSearchTool` с правильным аргументом (`query`).  Код должен быть на Python и заключен в теги ` ```py ` и ` ```<end_code> `.
*   **Observation:**  Получи результат действия (вывод `print()` в коде).  Оцени результат.  Если нужно, перейди к следующему шагу (Thought). Если ответ найден, используй `final_answer`.

**Правила:**

1.  **Всегда следуй циклу Thought-Action-Observation.**  Каждый шаг должен присутствовать.
2.  **Используй только доступные инструменты.** Не выдумывай несуществующие инструменты.
3.  **Правильно вызывай инструменты.**  Передавай аргументы *напрямую*, а не в виде словаря.  Например, `DuckDuckGoSearchTool(query="столица Франции")`, а не `DuckDuckGoSearchTool({"query": "столица Франции"})`.
4.  **Анализируй несколько источников.**  Не ограничивайся одним результатом поиска.
5.  **Формируй сводку (саммари).**  Ответ должен быть кратким, ёмким и содержать ссылки на источники (или названия сайтов, если ссылки не помещаются).
6.  **Пиши на русском языке.**
7.  **Если информации недостаточно, сообщи об этом.** Не придумывай ответ.
8.  **Не сохраняй результаты поиска в переменные для следующего шага. Используй `print()`.** Результат `print()` автоматически попадет в Observation. Это *единственный* способ передать информацию между шагами.
9. **Переменные сохраняются между шагами.** Если ты определил переменную на одном шаге, она будет доступна на следующих.
10. **Нельзя использовать один и тот же запрос дважды.** Если ты уже искал что-то, не повторяй поиск с тем же запросом.

**Пример (не копируй его полностью, адаптируй под задачу):**

Пользователь:  Какая самая высокая гора в мире?

Thought:  Мне нужно найти самую высокую гору в мире.  Я буду использовать DuckDuckGoSearchTool для поиска информации.
Action:
```py
print(DuckDuckGoSearchTool(query="самая высокая гора в мире"))
```<end_code>
Observation:  (Здесь будет вывод DuckDuckGoSearchTool, содержащий несколько результатов поиска)

Thought:  Я получил несколько результатов.  Нужно проанализировать их, найти наиболее авторитетные источники и убедиться, что информация совпадает.  Затем я сформирую сводку и верну ответ.
Action:
```py
# (Здесь мог бы быть код для дополнительного анализа, если бы были другие инструменты.
#  Но так как у нас только DuckDuckGoSearchTool,
#  мы предполагаем, что первый шаг уже дал достаточно информации)
final_answer("Самая высокая гора в мире - Эверест (Джомолунгма).  Высота - 8848.86 метров.  Источники: Википедия (ссылка), National Geographic (ссылка).")
```<end_code>

---
Доступные тебе инструменты:
{%- for tool in tools.values() %}
- {{ tool.name }}: {{ tool.description }}
    Takes inputs: {{tool.inputs}}
    Returns an output of type: {{tool.output_type}}
{%- endfor %}

Начни!
"""
prompt_templates['system_prompt'] = system_prompt


agent = CodeAgent(
    model=model,
    tools=[DuckDuckGoSearchTool, final_answer, image_generation_tool],
    max_steps=6,
    verbosity_level=1,
    grammar=None,
    planning_interval=None,
    name=None,
    description=None,
    prompt_templates=prompt_templates
)


GradioUI(agent).launch()