Skip to content

Conversation

@EvilFreelancer
Copy link
Member

Приветствую! Предлагаю вашему вниманию рефакторинг тулов о котором я размышлял всю прошлую неделю.

Первым делом выполнил небольшой рефакторинг, призванный разделить тулы и ядро в отдельные логические блоки.

  1. Вместо core.tools.base и core.tools.research была выполнена декомпозиция тулов, все тулы была разнесены по отдельным файлам, при этом логика тулов осталась прежней
  2. Все тулы были перемещены из core.tools на уровень выше и хранятся теперь в tools
  3. BaseTool был так же вынесен в отдельный файл base_tool.py, но при этом остался в core
  4. NextStepToolStub и NextStepToolsBuilder так же были вынесены в отдельный файл
    next_step_tools.py в core

Следующим важным нововведеним данного PR является механизм реестра тулов.

  1. В core был добавлен tools_registry, который содержит в себе класс ToolsRegistry и декоратор @tool позволяющий регистрировать в указанном регистри объекты расширящие класс BaseTool, то есть тулы
  2. Для того чтобы идентифицировать системные и исследовательские тулы был добавлен атрибут is_system_tool с типом boolean, по умолчанию он имеет статус False
  3. В классе ToolsRegistry имеются два метода, get_system_tools - возвращает список системных тулов и get_research_tools который будет возвращать исследовательские тулы, указанные методы призваны заменить хардкод system_agent_tools и research_agent_tools

Comment on lines 45 to 52
@classmethod
def get_research_tools(cls) -> list[Type[BaseTool]]:
"""Get all research tools (is_system_tool = False).
Returns:
List of research tool classes
"""
return [tool for tool in cls._tools.values() if not tool.is_system_tool]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Вот это немного нарушает мою изначальную концепцию, где можно было выпускать разные наборы тулов. Условно system, research, file, web search, server и всё такое. Импортишь их всем пакетом и агент приобретает необходимые навыки

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Предлагаю заменить на признак is_enable: bool, чтобы можно было управлять активными тулами на уровне регистри.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Сделал что пользователь можешь собрать любой набор какой хочет, если он передаёт их через toolkit в контроллере, то пользовательские тулы сливаются с системными.

Плюс во всех агентах используются все тулы, кроме случаев когда необходимо отключить ризонинг.

@virrius
Copy link
Member

virrius commented Sep 14, 2025

Я чучуточку скептичен насчёт регистри. Оно мне кажется немного оверкиллом. Пока не очевидны сценарии, где тулзы понадобились бы централизованно из регистри
Могу представить, что это было бы полезно в случае динамической сборки агентов в рантайме, но этот сценарий видится слишком специфичным
Можешь подробнее описать, в чём видишь пользу и удобство регистри?

Не вижу смысла в бинарном разделении system/research. В изначальной моей идее из коммента выше - это просто один из возможных пакетов тулзов В моём понимании флоу: импортим/пишем необходимые тулзы/их наборы, подсовываем в тулкит агента, радуемся

разделение на тулзов на файлики выглядит хорошо

Кроме того, стоит и конкретных агентов вынести на уровень с тулзами

Comment on lines 25 to 26
logging.basicConfig(
level=logging.INFO,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@virrius а мы зачем так внутри агента настраиваем basicConfig логера?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Это наследие оригинальной версии и вопрос скорее к @virrius мой код на данном участке просто выполняет декомпозицию (раскладывает классы по файликам).

@EvilFreelancer
Copy link
Member Author

Я чучуточку скептичен насчёт регистри. Оно мне кажется немного оверкиллом. Пока не очевидны сценарии, где тулзы понадобились бы централизованно из регистри Могу представить, что это было бы полезно в случае динамической сборки агентов в рантайме, но этот сценарий видится слишком специфичным Можешь подробнее описать, в чём видишь пользу и удобство регистри?

Сделал регистри опциональным, это теперь для нас история, мы можем добалять тулы в общий пул из любого места, юзерам возможно это тоже понравится, возможность использовать кастомные toolkit вдобавок к дефолтному набору - сохранена.

Не вижу смысла в бинарном разделении system/research. В изначальной моей идее из коммента выше - это просто один из возможных пакетов тулзов В моём понимании флоу: импортим/пишем необходимые тулзы/их наборы, подсовываем в тулкит агента, радуемся

Убрал эту логику, теперь список тулов запрашивается из регистир, плюс к этому набору добавляется набор переданный юзером через toolkit.

Кроме того, стоит и конкретных агентов вынести на уровень с тулзами

Предлагаю агентов перенести в свой неймспейс отдельным PR, а то в этом и так уже много правок.

Copy link
Collaborator

@MiXaiLL76 MiXaiLL76 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tool, tool, tool

Comment on lines +9 to 17
from sgr_deep_research.tools import (
AgentCompletionTool,
BaseTool,
ClarificationTool,
CreateReportTool,
NextStepToolsBuilder,
NextStepToolStub,
ReasoningTool,
WebSearchTool,
research_agent_tools,
system_agent_tools,
)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Много тулзов. Они тут зачем если есть регистри? я вижу там удаляются некоторые тулзы по возможности, мб просто по tool.class.name будем делать? чтобы меньше импортов было?

*(toolkit or []),
]
self.toolkit = [*ToolsRegistry.get_tools(), *(toolkit or [])]
self.toolkit.remove(ReasoningTool) # we use our own reasoning scheme
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ну типо вот тут, сделать удаление через class.name, можно тупо перебором мб?

Comment on lines 13 to 17
AgentCompletionTool,
BaseTool,
ClarificationTool,
CreateReportTool,
ReasoningTool,
WebSearchTool,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tool, tool, tool, tool. Если есть регистри, они не нужны в таком виде

Comment on lines +58 to +62
tools = {
ReasoningTool,
CreateReportTool,
AgentCompletionTool,
]
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tool, tool, tool....

registry.get("name")?

Comment on lines +12 to 17
from sgr_deep_research.tools import (
AgentCompletionTool,
BaseTool,
ClarificationTool,
CreateReportTool,
ReasoningTool,
WebSearchTool,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tool, tool, tool

Copy link
Member

@virrius virrius left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Моё понимание концепции сейчас на уровне:
коллекция для централизованного хранения и обработки тулзов - ОК, но само по себе не слишком полезно. Добавляет абстракцию, добавляет список стейтов (enabled) и накидывает лишней логики копирования

Применение в агенте - не ОК - оно используется буквально для инициализации toolkit, который по идее должен быть полностью заменён локальным registry агента

Добавление/удаление тулзов - не ОК, непонятно, как эффективно выбрать необходимый набор тулзов из общего количества

Регистри всё ещё кажется излишним и не слишком удобным. Я не понимаю/не оценил идею, в которой оно может быть полезно в текущей реализации

Предположим, количество тулзов в проекте возрастёт до сотни. А агент мы хотим формировать из 7-12. Каков будет механизм выбора тулзов из регистри? Писать 90 раз disable_tool? Сейчас внего копируется весь общий регистри. Согласно нашим обсуждениям об идее регистри, стоит сделать минимальную обёртку, которая могла бы фыормировать необходимый список тулов из общего количество по конфигу

Моё предложение - пивотнуться на уровне идеи или прикопать это дело до момента, когда появится более сформированная потребность

Comment on lines -183 to +177
if isinstance(action_tool, ClarificationTool):
if isinstance(action_tool, BaseTool):
Copy link
Member

@virrius virrius Sep 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Мне кажется, тут что-то пошло не так с переименованием. Важно чтобы этот кейс срабатывал именно для ClarificationTool.

Выше в тайпинге тоже бы предпочёл видеть конкретно ReasoningTool

class BaseTool(BaseModel):
"""Class to provide tool handling capabilities."""

is_enabled: ClassVar[bool] = True
Copy link
Member

@virrius virrius Sep 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Вот тут вангую проблемы будут. Это поле где-то используется? Предполагается к использованию?

}

@classmethod
def get_default_registry(cls) -> "ToolsRegistry":
Copy link
Member

@virrius virrius Sep 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Выглядит лишним в текущей логике. Можно просто через конструктор инициализировать

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants