feature/worker #111
@@ -40,6 +40,7 @@
|
||||
"gigachat": "^0.0.14",
|
||||
"jsdom": "^25.0.1",
|
||||
"jsonwebtoken": "^9.0.2",
|
||||
"langchain": "^0.3.7",
|
||||
"langchain-gigachat": "^0.0.11",
|
||||
"mongodb": "^6.12.0",
|
||||
"mongoose": "^8.9.2",
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
import { StructuredTool, ToolRunnableConfig } from '@langchain/core/tools';
|
||||
import { z } from 'zod';
|
||||
import { CallbackManagerForToolRun } from '@langchain/core/callbacks/manager';
|
||||
import { getVectorStore } from './vector-store';
|
||||
|
||||
export class KnowledgeBaseTool extends StructuredTool {
|
||||
name = 'search_knowledge_base';
|
||||
description = 'Ищет информацию в базе знаний компании о процессах, оплатах, подаче заявок, правилах и документах УК. Используй этот инструмент для вопросов, требующих специфических знаний о компании.';
|
||||
|
||||
schema = z.object({
|
||||
query: z.string().describe('Поисковый запрос для поиска в базе знаний'),
|
||||
});
|
||||
|
||||
protected async _call(
|
||||
arg: z.infer<typeof this.schema>,
|
||||
runManager?: CallbackManagerForToolRun,
|
||||
parentConfig?: ToolRunnableConfig<Record<string, any>>
|
||||
): Promise<string> {
|
||||
try {
|
||||
const vectorStore = getVectorStore();
|
||||
const retriever = vectorStore.asRetriever({
|
||||
k: 5
|
||||
});
|
||||
|
||||
const relevantDocs = await retriever.getRelevantDocuments(arg.query);
|
||||
|
||||
if (!relevantDocs || relevantDocs.length === 0) {
|
||||
return 'В базе знаний не найдено информации по данному запросу. Возможно, стоит переформулировать вопрос или обратиться к специалисту.';
|
||||
}
|
||||
|
||||
const formattedDocs = relevantDocs.map((doc, index) => {
|
||||
return `Документ ${index + 1}:\n${doc.pageContent}\n`;
|
||||
}).join('\n---\n');
|
||||
|
||||
return `Найдена следующая информация в базе знаний компании:\n\n${formattedDocs}\n\nИспользуй эту информацию для ответа на вопрос пользователя.`;
|
||||
|
||||
} catch (error) {
|
||||
return 'Произошла ошибка при поиске в базе знаний. Попробуйте переформулировать запрос.';
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ 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';
|
||||
|
||||
export interface SupportAgentConfig {
|
||||
temperature?: number;
|
||||
@@ -38,7 +39,8 @@ export class SupportAgent {
|
||||
}
|
||||
|
||||
const tools = [
|
||||
new SupportContextTool(this.userId)
|
||||
new SupportContextTool(this.userId),
|
||||
new KnowledgeBaseTool()
|
||||
];
|
||||
|
||||
this.agent = createReactAgent({
|
||||
@@ -58,11 +60,22 @@ export class SupportAgent {
|
||||
- Проявлять эмпатию к проблемам пользователей
|
||||
- Если не знаешь ответ, честно сообщить об этом и предложить альтернативные способы получения помощи
|
||||
|
||||
ВАЖНО: У тебя есть доступ к инструменту get_support_context, который позволяет получить историю предыдущих сообщений пользователя.
|
||||
ВСЕГДА используй этот инструмент ПЕРВЫМ ДЕЛОМ при получении каждого нового сообщения, чтобы понять контекст и предыдущие обращения пользователя.
|
||||
Только после получения контекста отвечай на вопрос пользователя.
|
||||
У тебя есть доступ к двум инструментам:
|
||||
|
||||
Если в истории есть предыдущие обращения, обязательно ссылайся на них в своем ответе, показывая что помнишь предыдущее общение.
|
||||
1. get_support_context - получает историю предыдущих сообщений пользователя
|
||||
ВСЕГДА используй этот инструмент ПЕРВЫМ ДЕЛОМ при получении каждого нового сообщения
|
||||
|
||||
2. search_knowledge_base - ищет информацию в базе знаний компании
|
||||
Используй этот инструмент для вопросов о:
|
||||
- Процессах оплаты и тарифах
|
||||
- Подаче заявок и документооборота
|
||||
- Правилах и регламентах УК
|
||||
- Технических вопросах приложения
|
||||
- Любых специфических вопросах о компании
|
||||
|
||||
ВАЖНО: Сначала получи контекст, затем при необходимости найди информацию в базе знаний, и только после этого отвечай пользователю.
|
||||
|
||||
Если в истории есть предыдущие обращения, обязательно ссылайся на них в своем ответе.
|
||||
|
||||
Всегда отвечай на русском языке и старайся быть максимально полезным.`;
|
||||
}
|
||||
@@ -107,7 +120,8 @@ export class SupportAgent {
|
||||
this.memorySaver = new MemorySaver();
|
||||
|
||||
const tools = [
|
||||
new SupportContextTool(this.userId)
|
||||
new SupportContextTool(this.userId),
|
||||
new KnowledgeBaseTool()
|
||||
];
|
||||
|
||||
this.agent = createReactAgent({
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
import { createClient } from '@supabase/supabase-js';
|
||||
import { SupabaseVectorStore } from '@langchain/community/vectorstores/supabase';
|
||||
import { GigaChatEmbeddings } from 'langchain-gigachat';
|
||||
import { Agent } from 'node:https';
|
||||
|
||||
const httpsAgent = new Agent({
|
||||
rejectUnauthorized: false,
|
||||
});
|
||||
|
||||
let vectorStoreInstance: SupabaseVectorStore | null = null;
|
||||
|
||||
export function getVectorStore(): SupabaseVectorStore {
|
||||
if (!vectorStoreInstance) {
|
||||
const client = createClient(
|
||||
process.env.RAG_SUPABASE_URL!,
|
||||
process.env.RAG_SUPABASE_SERVICE_ROLE_KEY!,
|
||||
);
|
||||
|
||||
vectorStoreInstance = new SupabaseVectorStore(
|
||||
new GigaChatEmbeddings({
|
||||
credentials: process.env.GIGA_AUTH,
|
||||
httpsAgent,
|
||||
}),
|
||||
{
|
||||
client,
|
||||
tableName: 'slon',
|
||||
queryName: 'match_slon'
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
return vectorStoreInstance;
|
||||
}
|
||||
Reference in New Issue
Block a user