feat: solution for '8. Самописный поисковый агент на основе deep agents from scratch'
CI / build (3.1) (push) Has been cancelled
CI / build (3.11) (push) Has been cancelled
CI / build (3.8) (push) Has been cancelled
CI / build (3.9) (push) Has been cancelled

This commit is contained in:
2026-07-01 13:56:19 +03:00
parent fea117b469
commit dbd910be14
5 changed files with 176 additions and 119 deletions
+45 -37
View File
@@ -1,55 +1,63 @@
**What was implemented**
- Added the required dependencies (`langchain-openai` and `langchain-community`) to `package.json`.
- Reimplemented the search agent using LangChains `DeepAgent` instead of the previous custom logic.
- Configured the OpenAI LLM through the `langchain-openai` wrapper, reading the key from `OPENAI_API_KEY`.
- Integrated the builtin `SearchTool` from `langchain-community` so the agent can perform web searches automatically.
- Exposed a simple `ask()` helper that invokes the agent and returns the output, and a CLI demo in `src/index.js`.
**Что реализовано**
- Добавлены пакеты `langchain-openai` и `langchain-community` в `package.json`.
- Создан класс `DeepAgent` в `src/index.js`, реализующий шаблон «Deep Agents from Scratch».
- Внутри агента реализован **планировщик** (`LLMChain` + `PromptTemplate`), который принимает запрос пользователя и возвращает JSON‑объект с типом действия (`search` или `answer`).
- В зависимости от плана агент либо вызывает инструмент `SerpAPI` для веб‑поиска, либо возвращает готовый ответ.
- Добавлена простая память (`BufferMemory`) для хранения истории диалога.
- В `main()` инициализируются LLM, инструмент поиска, память и агент, а затем агент обрабатывает запрос, переданный в командной строке.
**Why the main parts satisfy the requirements**
- **LangChain usage** `DeepAgent` is instantiated directly (`src/agent.js`), meeting the “use LangChains Deep Agent API” constraint.
- **OpenAI API via langchain-openai** The LLM is created with `new OpenAI({...})` from `langchain-openai`, ensuring all calls go through that package.
- **Dependencies added** `langchain-openai` and `langchain-community` are listed in `package.json`, satisfying the dependency requirement.
- **No reliance on old code** The previous custom agent logic is completely replaced; only the new LangChain components are used.
- **Search capability** `SearchTool` is passed to the agent, allowing it to decide when to query the web, fulfilling the “search agent” goal.
**Почему это соответствует требованиям**
- **LangChain**: все взаимодействия с LLM и инструментами построены через `langchain`‑объекты (`OpenAI`, `SerpAPI`, `LLMChain`, `PromptTemplate`).
- **OpenAI API**: используется `OpenAI` из `langchain-openai` с ключом из переменной окружения `OPENAI_API_KEY`.
- **Deep Agent**: класс `DeepAgent` полностью соответствует шаблону «Deep Agents from Scratch» – отдельный планировщик, исполнитель и память.
- **Поиск**: при выборе `search` агент вызывает `SerpAPI.run(query)` и возвращает результат.
- **Ответ**: при выборе `answer` агент просто возвращает строку из плана.
**Key code excerpts**
**Ключевые фрагменты кода**
`package.json`
```json
"dependencies": {
"langchain": "^0.0.112",
"langchain-openai": "^0.0.112",
"langchain-community": "^0.0.112"
"langchain": "^0.0.0",
"langchain-openai": "^0.0.0",
"langchain-community": "^0.0.0",
"dotenv": "^16.0.0"
}
```
`src/agent.js`
`src/index.js` планировщик
```js
import { DeepAgent } from "langchain/agents";
import { OpenAI } from "langchain-openai";
import { SearchTool } from "langchain-community/tools/search";
const llm = new OpenAI({ temperature: 0, modelName: "gpt-3.5-turbo" });
const searchTool = new SearchTool();
const agent = new DeepAgent({
llm,
tools: [searchTool],
verbose: true
this.planner = new LLMChain({
llm: this.llm,
prompt: new PromptTemplate({
inputVariables: ["input"],
template: `You are a helpful assistant. Given the user query: "{input}"
Decide whether you need to perform a web search or can answer directly.
Respond in JSON format:
{
"type": "search" | "answer",
"query": "<search query>" | null,
"answer": "<answer>" | null
}
If you choose "search", provide the search query in "query". If you choose "answer", provide the answer in "answer".`,
}),
});
```
`src/index.js` (invocation)
`src/index.js` выполнение плана
```js
export async function ask(query) {
const result = await agent.invoke({ input: query });
return result.output;
if (plan.type === "search" && plan.query) {
const searchTool = this.tools.find((t) => t.name === "SerpAPI");
const searchResult = await searchTool.run(plan.query);
return searchResult;
} else if (plan.type === "answer" && plan.answer) {
return plan.answer;
}
```
**Honest limitations**
- The implementation assumes `OPENAI_API_KEY` is set; no fallback or user prompt is provided.
- No custom error handling beyond the basic try/catch in the CLI demo.
- The agent uses the default `SearchTool`; if a different search provider is needed, additional configuration would be required.
**Ограничения**
- Планировщик возвращает JSON, но не проверяет корректность ключей `type`, `query`, `answer` более глубоко.
- В случае ошибки в ответе LLM (невалидный JSON) агент выбрасывает исключение.
- Параметры модели и инструмента заданы статически; для гибкой конфигурации можно добавить CLI‑параметры.
Overall, the project now fully complies with the assignment: it uses LangChain, integrates OpenAI via the dedicated package, and rebuilds the search agent with the Deep Agent API.
Таким образом, проект теперь содержит полноценного Deep Agent, использующего LangChain и OpenAI API, способного выполнять поисковые запросы и выдавать ответы.