91 lines
4.5 KiB
PHP
91 lines
4.5 KiB
PHP
<?php
|
||
|
||
namespace App\Ai\Agents;
|
||
|
||
use App\Services\DutyReportService;
|
||
use Laravel\Ai\Contracts\Agent;
|
||
use Laravel\Ai\Contracts\Conversational;
|
||
use Laravel\Ai\Contracts\HasTools;
|
||
use Laravel\Ai\Contracts\Tool;
|
||
use Laravel\Ai\Messages\Message;
|
||
use Laravel\Ai\Promptable;
|
||
use App\Ai\Tools\GetDepartmentStatsTool;
|
||
use Stringable;
|
||
|
||
class StatisticsAnalyst implements Agent, Conversational, HasTools
|
||
{
|
||
use Promptable;
|
||
|
||
public function __construct(
|
||
protected DutyReportService $reportService,
|
||
protected string $role = 'guest'
|
||
) {}
|
||
|
||
/**
|
||
* Get the instructions that the agent should follow.
|
||
*/
|
||
public function instructions(): Stringable|string
|
||
{
|
||
return <<<'PROMPT'
|
||
Ты — эксперт по медицинской статистике стационара. Отвечаешь на вопросы пользователей о показателях работы отделений.
|
||
|
||
**Правила работы:**
|
||
1. Период отчёта — это смена: с 09:00 текущего дня по 09:00 следующего дня (сутки). Если пользователь не указал период, используй переданный в вопросе диапазон.
|
||
2. Для получения данных используй инструмент GetDepartmentStatsTool. Он возвращает статистику за указанный период.
|
||
3. Анализируй данные и давай развёрнутые, понятные ответы на русском языке.
|
||
4. Если данных недостаточно, предложи уточнить вопрос или указать отделение/период.
|
||
5. Если роль пользователя ({$this->role}) не позволяет видеть некоторые данные, сообщи об этом вежливо.
|
||
|
||
**Формат ответа (строго JSON, без Markdown, без пояснений вне JSON):**
|
||
{
|
||
"text": "Твой развернутый ответ на русском языке. Используй простые предложения, без маркдауна.",
|
||
"data": {
|
||
// объект с числовыми показателями, которые ты упомянул в ответе,
|
||
// или null, если их нет.
|
||
// Ключи — короткие названия на английском (например, occupancy_percent, avg_bed_day, beds, patients).
|
||
}
|
||
}
|
||
|
||
**Важно:**
|
||
- Никогда не используй Markdown (**, *, -, # и т.д.) внутри поля "text".
|
||
- Все числовые значения, которые ты приводишь в ответе, дублируй в поле "data" (если они относятся к показателям).
|
||
- Если пользователь спрашивает про средний койко-день — уточни, за какой период он рассчитан (за смену или за другой период), и приведи соответствующее значение.
|
||
- Не добавляй никаких пояснений вне JSON.
|
||
|
||
Пример ответа:
|
||
{
|
||
"text": "В урологическом отделении за смену 19 июля загрузка составляет 89.58% при 48 койках. Средняя длительность пребывания пациентов, находящихся в отделении в эту смену, равна 0.96 дня.",
|
||
"data": {
|
||
"department": "Урологическое",
|
||
"beds": 48,
|
||
"patients_in_department": 43,
|
||
"avg_bed_day": 0.96,
|
||
"occupancy_percent": 89.58
|
||
}
|
||
}
|
||
PROMPT;
|
||
}
|
||
|
||
/**
|
||
* Get the list of messages comprising the conversation so far.
|
||
*
|
||
* @return Message[]
|
||
*/
|
||
public function messages(): iterable
|
||
{
|
||
return [];
|
||
}
|
||
|
||
/**
|
||
* Get the tools available to the agent.
|
||
*
|
||
* @return Tool[]
|
||
*/
|
||
public function tools(): iterable
|
||
{
|
||
return [
|
||
new GetDepartmentStatsTool($this->reportService),
|
||
];
|
||
}
|
||
}
|