Improved prompts

This commit is contained in:
uxname committed 2025-05-24 22:41:41 +03:00
1 parent 1cec68ea61
commit 17ea20b11b
2 files changed
+74 -23

No files matched your search

+28 -22
View File
@@ -27,37 +27,43 @@ export class TelegramBot {
try { try {
const userPipeline: Pipeline = { const userPipeline: Pipeline = {
description: 'User message processing pipeline', description: 'Криптокошелёк анализатор для Liquidswap',
systemPrompt: `Ты полезный ассистент, который всегда отвечает на русском языке. systemPrompt: `Вы — профессиональный криптоаналитик и портфельный менеджер.
Анализируй сообщения пользователя и давай развернутые ответы. Анализируйте криптовалютный рынок, используя актуальные веб-данные.
Твой ответ всегда должен быть в стиле гопника, но не слишком длинный. Проведите анализ портфеля пользователя, адаптируясь к широкому (рыночные тренды, новости) или ограниченному (только портфель) набору данных.
Всегда начинай своё сообщение со слов: "Мой господин". Если данные портфеля отсутствуют, запросите их. Охватите по возможности:
Старайся форматировать информацию которую отправляешь, выделяй жирным шрифтом основные сведения. - Технический анализ (тренды, волатильность, индикаторы).
Старайся использовать эмодзи.`, - Фундаментальный анализ (новости, проекты).
- Риски (корреляции, ликвидность, регуляторные факторы).
- Диверсификацию и оптимизацию.
Предоставьте рекомендации по улучшению портфеля.
Формат ответа: отчет с разделами "Текущая ситуация на рынке", "Анализ портфеля", "Риски", "Рекомендации".
Тон профессиональный, без сложного жаргона.
Если данных недостаточно, задайте уточняющие вопросы.
Обеспечьте точность ≥ 95%, избегая неподтвержденных предположений.`,
steps: [ steps: [
{ {
name: 'Обработка сообщения', name: 'Обработка запроса',
prompt: userMessage, prompt: userMessage,
}, },
{ {
name: 'Генерация ответа', name: 'Анализ',
prompt: `Я хочу грамотно распределить свой криптовалютный портфель, используя данные DeFi-протокола Liquidswap.
Пожалуйста, предоставьте рекомендации по распределению активов,
основываясь на данных от инструментов:
\`get_tokens\`,
\`get_pools\`,
\`get_pools_historical_aprs\` (за 5 дней),
\`get_pools_historical_tvls\` (за 5 дней),
\`get_balances_by_address\` (мой адрес Aptos, если потребуется, запросите его) и \`multi_tool_use.parallel\`.`,
},
{
name: 'Форматирование ответа',
prompt: prompt:
'Отформатируй свой ответ, в формат HTML для Telegram.' + 'Отлично, теперь используя эмодзи давай сделаем из этих данных telegram пост',
'Не добавляй никакого дополнительного текста или других символов.' +
'Твой ответ будет напрямую отправлен пользователю через Telegram.' +
'**Поддерживаемые теги**: \n' +
'- `<b>`, `<strong>`: Жирный текст. \n' +
'- `<i>`, `<em>`: Курсив. \n' +
'- `<u>`, `<ins>`: Подчёркивание. \n' +
'- `<s>`, `<strike>`, `<del>`: Зачёркивание. \n' +
'- `<a href="URL">`: Ссылки (внешние или `tg://user?id=123`). \n' +
'- `<code>`: Моноширинный текст (короткий код). \n' +
'- `<pre>`: Блок кода (поддерживает `<code class="language-ЯЗЫК">`).' +
'Используй ТОЛЬКО эти теги И НИКАКИЕ ДРУГИЕ!',
}, },
], ],
}; };
this.activePipelines.set(chatId, userPipeline); this.activePipelines.set(chatId, userPipeline);
await ctx.sendChatAction('typing'); await ctx.sendChatAction('typing');
+46 -1
View File
@@ -31,9 +31,23 @@ export class PipelineExecutor {
private async initChain(openAIApiKey: string): Promise<Runnable> { private async initChain(openAIApiKey: string): Promise<Runnable> {
const tools = await this._getOrLoadTools(); const tools = await this._getOrLoadTools();
const llm = new ChatOpenAI({ const llm = new ChatOpenAI({
model: 'gpt-4o', model: 'gpt-4.1-2025-04-14',
temperature: 0.2, temperature: 0.2,
openAIApiKey: openAIApiKey, openAIApiKey: openAIApiKey,
callbacks: [
{
handleLLMStart: async (_llm, prompts) => {
console.log('\n=== LLM CALL STARTED ===');
console.log('Prompts:', prompts);
console.log('========================\n');
},
handleLLMError: async (err) => {
console.error('\n=== LLM ERROR ===');
console.error(err);
console.error('=================\n');
},
},
],
}); });
return llm.bindTools(tools); return llm.bindTools(tools);
} }
@@ -84,12 +98,43 @@ export class PipelineExecutor {
return results; return results;
} }
private logAIMessages(
messages: (HumanMessage | SystemMessage | AIMessage | ToolMessage)[],
direction: 'TO_AI' | 'FROM_AI',
) {
console.log(`\n=== AI ${direction} MESSAGES ===`);
messages.forEach((msg, i) => {
console.log(`\nMessage ${i + 1} (${msg._getType()}):`);
if ('content' in msg) {
console.log('Content:', msg.content);
}
if ('tool_calls' in msg && msg.tool_calls) {
console.log('Tool calls:', JSON.stringify(msg.tool_calls, null, 2));
}
if ('tool_call_id' in msg) {
console.log('Tool call ID:', msg.tool_call_id);
}
});
console.log('==========================\n');
}
private async _resolveToolCalls( private async _resolveToolCalls(
chain: Runnable, chain: Runnable,
messages: (HumanMessage | SystemMessage | AIMessage | ToolMessage)[], messages: (HumanMessage | SystemMessage | AIMessage | ToolMessage)[],
): Promise<AIMessage> { ): Promise<AIMessage> {
// Log messages being sent to AI
this.logAIMessages(messages, 'TO_AI');
let response: AIMessage = await chain.invoke(messages); let response: AIMessage = await chain.invoke(messages);
// Log response from AI
console.log('\n=== AI RESPONSE ===');
console.log('Content:', response.content);
if (response.tool_calls) {
console.log('Tool calls:', JSON.stringify(response.tool_calls, null, 2));
}
console.log('==================\n');
while (response.tool_calls && response.tool_calls.length > 0) { while (response.tool_calls && response.tool_calls.length > 0) {
messages.push(response); messages.push(response);