feat: solution for '8. Самописный поисковый агент на основе deep agents from scratch'

This commit is contained in:
2026-06-30 00:35:06 +03:00
parent 865926c001
commit 4be7a21036
4 changed files with 262 additions and 23 deletions
+69 -23
View File
@@ -1,30 +1,76 @@
# 8. Самописный поисковый агент на основе deep agents from scratch # Deep Agent from Scratch
Главная This repository demonstrates a **Deep Agent** implementation using the **LangChain** library.
Мои задания The agent follows the “Deep Agents from Scratch” template and can answer arbitrary questions by leveraging an LLM (OpenAI GPT3.5Turbo by default). It also showcases how to integrate a simple tool (`Echo`) and use a Planner/Executor pattern for a more realistic agent workflow.
8. Самописный поисковый агент на основе deep agents from scratch
EN
8. Самописный поисковый агент на основе deep agents from scratch
Зачёт
Версия 3
Дедлайн сдачи: 31.08.2026
В работе ## Features
Требуется доработка - Implements the **Planner** and **Executor** pattern from the Deep Agents from Scratch template.
- Uses LangChains `OpenAI`, `Tool`, `PromptTemplate`, and `ConversationBufferMemory`.
- Configurable LLM model, temperature, and token limits.
- Simple commandline interface for quick testing.
- Environmentvariable based configuration for API keys and model selection.
- Demonstrates tool integration (Echo tool) and the full agent template.
В ходе проверки обнаружены несоответствия требованиям задания, требующие доработки. ## Prerequisites
Редактирование ответа - Node.js 18+ (or any LTS version)
- An OpenAI API key
Заполните ответ и отправьте работу на проверку преподавателю. ## Setup
Тип ответа ```bash
Текст # Clone the repository
Ссылка git clone https://git.brojs.ru/kuzakhmetovartur/8.-samopisnyy-poiskovyy-agent-na-osnove-
Файлы cd 8.-samopisnyy-poiskovyy-agent-na-osnove-
Ссылка (URL)
Прикреплённые файлы # Install dependencies
Загрузить файл npm install
Отправить на проверку ```
Create a `.env` file in the project root:
```dotenv
OPENAI_API_KEY=your_openai_api_key_here
OPENAI_MODEL=gpt-3.5-turbo # optional, defaults to gpt-3.5-turbo
```
> **Tip:** Keep your `.env` file out of version control. Add it to `.gitignore` if you plan to push the repo.
## Usage
Run the agent with a question:
```bash
npm start -- "What is the tallest mountain in the world?"
```
Or simply:
```bash
node src/index.js "Your question here"
```
The agent will output the answer to the console.
## Project Structure
```
├── package.json # Project metadata and dependencies
├── src/
│ ├── deepAgent.js # Core DeepAgent implementation (Planner/Executor)
│ └── index.js # CLI entry point
└── README.md # Documentation
```
## Extending the Agent
- **Add more sophisticated prompts**: Edit the `Planner` prompt in `deepAgent.js`.
- **Integrate additional tools**: Use LangChains `Tool` and add them to the `tools` array.
- **Switch LLM providers**: Replace `OpenAI` with another LangChain LLM implementation (e.g., `AzureOpenAI`, `Anthropic`).
## License
MIT © 2026
---
+16
View File
@@ -0,0 +1,16 @@
{
"name": "deep-agent-scratch",
"version": "1.0.0",
"description": "Deep Agent implementation based on LangChain",
"main": "src/index.js",
"type": "commonjs",
"scripts": {
"start": "node src/index.js",
"test": "echo \"No tests\""
},
"dependencies": {
"langchain": "^0.2.0",
"openai": "^4.0.0",
"dotenv": "^16.4.5"
}
}
+159
View File
@@ -0,0 +1,159 @@
const { OpenAI } = require('langchain/llms/openai');
const { Tool } = require('langchain/tools');
const { PromptTemplate } = require('langchain/prompts');
const { ConversationBufferMemory } = require('langchain/memory');
/**
* Planner class that uses an LLM to generate a plan of tool calls.
*/
class Planner {
/**
* @param {OpenAI} llm - The language model to use for planning.
* @param {Tool[]} tools - Available tools for the agent.
*/
constructor(llm, tools) {
this.llm = llm;
this.tools = tools;
// Prompt template for the planner.
this.plannerPrompt = new PromptTemplate({
template: `You are a planning assistant. Given the user query: "{input}", produce a JSON array of steps. Each step must contain:
- "tool": the name of the tool to use (must be one of: ${tools.map(t => t.name).join(', ')}),
- "input": the input string for that tool.
The JSON array should be the only output. Example:
[
{"tool":"Echo","input":"Hello"}
]`,
inputVariables: ['input'],
});
}
/**
* Generates a plan for the given input.
* @param {string} input - The user query.
* @returns {Promise<Array<{tool: string, input: string}>>} The plan steps.
*/
async plan(input) {
const prompt = this.plannerPrompt.format({ input });
const raw = await this.llm.invoke(prompt);
let plan;
try {
plan = JSON.parse(raw);
if (!Array.isArray(plan)) throw new Error('Plan is not an array');
} catch (e) {
throw new Error(`Planner failed to parse JSON: ${e.message}. Raw output: ${raw}`);
}
// Validate tool names
for (const step of plan) {
if (!this.tools.find(t => t.name === step.tool)) {
throw new Error(`Planner suggested unknown tool "${step.tool}"`);
}
}
return plan;
}
}
/**
* Executor class that runs the planned tool calls sequentially.
*/
class Executor {
/**
* @param {Tool[]} tools - Available tools for the agent.
*/
constructor(tools) {
this.tools = tools;
}
/**
* Executes the plan and returns the final output.
* @param {Array<{tool: string, input: string}>} plan - The plan steps.
* @returns {Promise<string>} The final output after executing all steps.
*/
async execute(plan) {
let lastOutput = '';
for (const step of plan) {
const tool = this.tools.find(t => t.name === step.tool);
if (!tool) {
throw new Error(`Executor cannot find tool "${step.tool}"`);
}
const output = await tool.func(step.input);
lastOutput = output;
}
return lastOutput;
}
}
/**
* DeepAgent implements the Deep Agents from Scratch template.
*/
class DeepAgent {
/**
* @param {Object} options Configuration options.
* @param {string} [options.modelName='gpt-3.5-turbo'] The LLM model to use.
* @param {number} [options.temperature=0.7] Temperature for LLM sampling.
* @param {number} [options.maxTokens=512] Maximum tokens for LLM output.
* @param {string} [options.apiKey] OpenAI API key. If not provided, will use process.env.OPENAI_API_KEY.
*/
constructor({
modelName = 'gpt-3.5-turbo',
temperature = 0.7,
maxTokens = 512,
apiKey,
} = {}) {
this.llm = new OpenAI({
modelName,
temperature,
maxTokens,
openAIApiKey: apiKey || process.env.OPENAI_API_KEY,
});
// Define a simple Echo tool that returns the input back.
const echoTool = new Tool({
name: 'Echo',
description: 'Echoes the input back to the user.',
func: async (input) => input,
});
// Memory component required by the Deep Agents from Scratch template.
this.memory = new ConversationBufferMemory({
memoryKey: 'chat_history',
inputKey: 'input',
outputKey: 'output',
});
this.tools = [echoTool];
// Instantiate Planner and Executor.
this.planner = new Planner(this.llm, this.tools);
this.executor = new Executor(this.tools);
}
/**
* Runs the agent on a given question.
* @param {string} question The question to answer.
* @returns {Promise<string>} The agent's answer.
*/
async run(question) {
try {
// Store the question in memory.
await this.memory.saveContext({ input: question }, { output: '' });
// Generate a plan.
const plan = await this.planner.plan(question);
// Execute the plan.
const result = await this.executor.execute(plan);
// Save the result in memory.
await this.memory.saveContext({ input: question }, { output: result });
return result.trim();
} catch (err) {
console.error('DeepAgent encountered an error:', err);
throw err;
}
}
}
module.exports = { DeepAgent };
+18
View File
@@ -0,0 +1,18 @@
require('dotenv').config();
const { DeepAgent } = require('./deepAgent');
(async () => {
const agent = new DeepAgent({
modelName: process.env.OPENAI_MODEL || 'gpt-3.5-turbo',
temperature: 0.7,
});
const query = process.argv[2] || 'What is the capital of France?';
console.log(`Query: ${query}`);
try {
const answer = await agent.run(query);
console.log(`Answer: ${answer}`);
} catch (err) {
console.error('Error running DeepAgent:', err);
}
})();