Данный код демонстрирует создание ReAct (Reasoning and Acting) агента с использованием библиотеки LangChain.js.
Основные компоненты
ReAct агент — это AI-система, которая может рассуждать и действовать, используя доступные инструменты для решения задач пользователя.
- CustomReActParser — кастомный парсер для обработки JSON-ответов агента
- Инструменты (tools) — массив доступных агенту инструментов
- Промпт — шаблон для взаимодействия с языковой моделью
- RunnableSequence — цепочка выполнения агента
- AgentExecutor — исполнитель агента с настройками
import { ReActSingleInputOutputParser } from 'langchain/agents/react/output_parser';
import {AgentExecutor} from "langchain/agents";
import {ChatPromptTemplate} from '@langchain/core/prompts';
import {RunnableSequence} from "@langchain/core/runnables";
import validator from 'validator';
// Расширяет стандартный ReActSingleInputOutputParser для обработки JSON-ответов
class CustomReActParser extends ReActSingleInputOutputParser {
async parse(text) {
if (!validator.isJSON(result)) {
return super.parse(text);
}
const res = JSON.parse(result);
const action = res['Action'];
const actionInput = res['Action Input'];
const actionLog = res['Thought'];
const finalAnswer = res['Final Answer'];
if (finalAnswer?.length) {
return {
returnValues: {
output: finalAnswer,
success: true,
},
log: actionLog,
}
}
return {
tool: action,
toolInput: actionInput,
log: actionLog,
}
}
}
// Агент может использовать различные инструменты для выполнения задач.
const tools = []; // -> сюда можете добавить DynamicStructuredTool или DynamicTool
const toolNames = tools.map(t => t.name);
// Промпт-шаблон
const chatPrompt = ChatPromptTemplate.fromMessages([
[
"system", `Ты ассистент. Отвечай на русском языке.
У тебя есть доступ к следующим инструментам: {tools}
Используй следующий формат:
Question: пользователь написал мне "{input}"
Thought: думаю о том, как выполнить его задачу используя доступные инструменты
Action: я использую один инструмент из [{tool_names}]
Thought: я думаю о том, как выполнить API инструмента используя его схему
Action Input: я беру вопрос и подставляю его в схему инструмента.
Final Answer: ответом API является {final_answer}
You must return valid JSON. Do not return any additional text.
`],
]);
const runnableAgent = RunnableSequence.from([
{
// извлечение текста из документов
input: (input) => {
const userMessages = input.documents.filter(item => {
return item.encodingFormat === 'text/plain';
}).map(item => {
return item.text;
});
return userMessages.join('\n');
},
// история выполненных шагов
agent_scratchpad: ({steps}) => {
if (!steps?.length) return '';
return steps.map(step => {
return `Observation: ${step.observation}`;
}).join('\n\n');
},
// финальный результат
final_answer: (input) => {
const {steps} = input;
if (steps.length === 0) return '';
const {observation} = steps[steps.length - 1];
return observation;
},
// список доступных инструментов
tools: () => tools.map(tool => `${tool.name}: ${tool.description}`).join('\n'),
// имена инструментов
tool_names: () => toolNames.join(', '),
},
chatPrompt,
llm, // -> здесь установите вашу используемую LLM, например OpenAI
new CustomReActParser({toolNames: toolNames}),
]);
const agent = AgentExecutor.fromAgentAndTools({
agent: runnableAgent,
tools: tools,
returnIntermediateSteps: true,
returnOnlyOutputs: false,
maxIterations: 3,
verbose: true,
earlyStoppingMethod: 'force',
handleParsingErrors: true,
});
// запуск агента
const result = await agent.invoke({
documents: [
{
encodingFormat: 'text/plain',
text: 'ВАШ ЗАПРОС',
}
],
});
Такой агент подходит для
- Автоматизации задач с использованием API
- Создания интеллектуальных ассистентов
- Обработки сложных пользовательских запросов
- Интеграции с внешними сервисами