Files
multy-stub/server/routers/kfu-m-24-1/sber_mobile/support-ai-agent/support-agent.ts
2025-06-14 00:16:02 +03:00

166 lines
7.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { HumanMessage, AIMessage, SystemMessage, BaseMessage } from '@langchain/core/messages';
import { ChatPromptTemplate, MessagesPlaceholder } from '@langchain/core/prompts';
import { createReactAgent } from '@langchain/langgraph/prebuilt';
import { MemorySaver } from '@langchain/langgraph';
import gigachat from './gigachat';
import { SupportContextTool } from './support-context-tool';
import { KnowledgeBaseTool } from './knowledge-base-tool';
import { CreateTicketTool } from './create-ticket-tool';
export interface SupportAgentConfig {
temperature?: number;
threadId?: string;
}
export interface SupportResponse {
content: string;
success: boolean;
error?: string;
}
export class SupportAgent {
private llm: any;
private memorySaver: MemorySaver;
private agent: any;
private systemPrompt: string;
private threadId: string;
private isFirstMessage: boolean;
private userId: string;
constructor(config: SupportAgentConfig = {}) {
this.systemPrompt = this.getDefaultSystemPrompt();
this.threadId = config.threadId || 'default';
this.userId = this.threadId;
this.memorySaver = new MemorySaver();
this.isFirstMessage = true;
this.llm = gigachat;
if (config.temperature !== undefined) {
this.llm.temperature = config.temperature;
}
const tools = [
new SupportContextTool(this.userId),
new KnowledgeBaseTool()
];
this.agent = createReactAgent({
llm: this.llm,
tools: tools,
checkpointSaver: this.memorySaver
});
}
private getDefaultSystemPrompt(): string {
return `Ты - профессиональный агент службы поддержки управляющей компании.
ОСНОВНЫЕ ПРИНЦИПЫ:
- Помогай только с реальными проблемами и вопросами, связанными с ЖКХ, управляющей компанией и приложением
- Будь вежливым, профессиональным и по существу
- Если вопрос неуместен, не связан с твоими обязанностями или является развлекательным - вежливо откажись и перенаправь к основным темам
ДОСТУПНЫЕ ИНСТРУМЕНТЫ:
1. get_support_context - получает историю сообщений пользователя
ВСЕГДА используй ПЕРВЫМ при каждом новом сообщении
2. search_knowledge_base - поиск в базе знаний компании
Используй ТОЛЬКО для серьезных вопросов о:
- Процессах оплаты ЖКХ и тарифах
- Подаче заявок и документообороте
- Правилах и регламентах УК
- Технических вопросах приложения
- Процедурах и инструкциях компании
3. create_ticket - создание заявки в системе
Используй ТОЛЬКО когда:
- Пользователь сообщает о реальной проблеме (поломка, неисправность, жалоба)
- Проблема требует вмешательства УК или технических служб
- ОБЯЗАТЕЛЬНО сначала покажи пользователю полный текст заявки
- Получи ЯВНОЕ согласие пользователя перед созданием
- НЕ создавай заявки для консультационных вопросов
ПРАВИЛА ИСПОЛЬЗОВАНИЯ ИНСТРУМЕНТОВ:
- НЕ используй search_knowledge_base и create_ticket для:
* Общих вопросов и болтовни
* Развлекательных запросов
* Вопросов не по теме ЖКХ/УК
* Простых консультаций, которые можно решить обычным ответом
АЛГОРИТМ РАБОТЫ:
1. Получи контекст истории сообщений
2. Определи, является ли вопрос уместным и серьезным
3. Если нужна специфическая информация - найди в базе знаний
4. Если нужно создать заявку - покажи текст и получи согласие
5. Дай полный и полезный ответ
Всегда отвечай на русском языке и фокусируйся на помощи с реальными проблемами ЖКХ.`;
}
public async processMessage(userMessage: string, apartmentId?: string): Promise<SupportResponse> {
try {
const messages: BaseMessage[] = [];
if (this.isFirstMessage) {
messages.push(new SystemMessage(this.systemPrompt));
this.isFirstMessage = false;
}
messages.push(new HumanMessage(userMessage));
// Создаем инструменты с актуальным apartmentId
const tools = [
new SupportContextTool(this.userId),
new KnowledgeBaseTool(),
new CreateTicketTool(this.userId, apartmentId || '')
];
// Пересоздаем агента с обновленными инструментами
const tempAgent = createReactAgent({
llm: this.llm,
tools: tools,
checkpointSaver: this.memorySaver
});
const response = await tempAgent.invoke({
messages: messages
}, {
configurable: {
thread_id: this.threadId
}
});
const lastMessage = response.messages[response.messages.length - 1];
return {
content: typeof lastMessage.content === 'string' ? lastMessage.content : 'Извините, не удалось сформировать ответ.',
success: true
};
} catch (error) {
console.error('Ошибка при обработке сообщения:', error);
return {
content: 'Извините, произошла ошибка при обработке вашего запроса. Попробуйте позже.',
success: false,
error: error instanceof Error ? error.message : 'Неизвестная ошибка'
};
}
}
public async clearHistory(): Promise<void> {
this.memorySaver = new MemorySaver();
const tools = [
new SupportContextTool(this.userId),
new KnowledgeBaseTool()
];
this.agent = createReactAgent({
llm: this.llm,
tools: tools,
checkpointSaver: this.memorySaver
});
this.isFirstMessage = true;
}
}