Compare commits
2 Commits
9ab33ca6a8
...
b0f9325dbf
| Author | SHA1 | Date | |
|---|---|---|---|
| b0f9325dbf | |||
| babdcf160b |
@@ -1,6 +1,6 @@
|
|||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2026 Artur Kuzakhmetov
|
Copyright (c) 2026 Your Name
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the “Software”), to deal
|
of this software and associated documentation files (the “Software”), to deal
|
||||||
@@ -9,4 +9,13 @@ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|||||||
copies of the Software, and to permit persons to whom the Software is
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
furnished to do so, subject to the following conditions:
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
[Full MIT license text omitted for brevity]
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
@@ -1,40 +1,69 @@
|
|||||||
# Self-Correcting Agent
|
# Самокорректирующийся агент
|
||||||
|
|
||||||
This repository contains a simple implementation of a self‑correcting agent using **LangGraph**.
|
## Описание
|
||||||
The agent follows these steps:
|
|
||||||
|
|
||||||
1. **Ask** – Generates an answer to the user’s question.
|
Данный проект реализует простого **самокорректирующегося агента** на Node.js. Агент генерирует ответ на заданный вопрос, а затем использует API OpenAI для проверки и улучшения своего ответа. Это демонстрационный пример того, как можно интегрировать модель GPT в цикл самокоррекции.
|
||||||
2. **Check** – Evaluates the answer’s quality.
|
|
||||||
3. **Correct** – If the answer is flagged as poor, it rewrites it.
|
|
||||||
4. **Final** – Returns the final answer.
|
|
||||||
|
|
||||||
## Installation
|
## Требования
|
||||||
|
|
||||||
|
- Node.js версии 18+ (рекомендуется LTS)
|
||||||
|
- npm (или yarn)
|
||||||
|
- **Пакеты, необходимые для работы проекта:**
|
||||||
|
- `dotenv` – для загрузки переменных окружения из файла `.env`
|
||||||
|
- `openai` – официальный клиент OpenAI для взаимодействия с API
|
||||||
|
- `jest` – для запуска тестов (только в режиме разработки)
|
||||||
|
|
||||||
|
## Установка
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pip install -r requirements.txt
|
# Клонируйте репозиторий
|
||||||
|
git clone https://git.brojs.ru/kuzakhmetovartur/ekzamen-samokorrektiruyuschiysya-agent.git
|
||||||
|
cd ekzamen-samokorrektiruyuschiysya-agent
|
||||||
|
|
||||||
|
# Установите зависимости
|
||||||
|
npm install
|
||||||
```
|
```
|
||||||
|
|
||||||
> **Note**: The implementation uses deterministic placeholders instead of real LLM calls, so no API keys are required.
|
## Конфигурация
|
||||||
|
|
||||||
## Usage
|
Создайте файл `.env` в корне проекта и добавьте ваш ключ API OpenAI:
|
||||||
|
|
||||||
```python
|
```dotenv
|
||||||
from src.agent import run_agent
|
OPENAI_API_KEY=sk-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||||
|
|
||||||
question = "What is the capital of France?"
|
|
||||||
answer = run_agent(question)
|
|
||||||
print(answer)
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Project Structure
|
> ⚠️ **Важно**: Никогда не публикуйте ваш ключ API в публичных репозиториях.
|
||||||
|
|
||||||
```
|
## Использование
|
||||||
├── requirements.txt
|
|
||||||
├── src
|
Запустите скрипт:
|
||||||
│ └── agent.py
|
|
||||||
└── README.md
|
```bash
|
||||||
|
npm start
|
||||||
```
|
```
|
||||||
|
|
||||||
## License
|
Пример вывода:
|
||||||
|
|
||||||
MIT License
|
```
|
||||||
|
Вопрос: Какой язык программирования лучше всего подходит для веб-разработки?
|
||||||
|
Ответ: JavaScript является популярным выбором для веб-разработки благодаря своей гибкости и широкому сообществу.
|
||||||
|
Самокоррекция: После проверки, ответ можно уточнить: JavaScript, особенно в сочетании с фреймворками вроде React или Vue, обеспечивает быстрый и интерактивный пользовательский интерфейс.
|
||||||
|
```
|
||||||
|
|
||||||
|
## Тесты
|
||||||
|
|
||||||
|
Для запуска тестов используйте:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm test
|
||||||
|
```
|
||||||
|
|
||||||
|
Тесты находятся в папке `__tests__` и проверяют базовую работу агента.
|
||||||
|
|
||||||
|
## Лицензия
|
||||||
|
|
||||||
|
MIT © 2026
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
> **Примечание**: Этот проект создан в рамках экзамена по теме «Самокорректирующийся агент» и служит демонстрацией базовой реализации. Для продакшн‑использования требуется более тщательная обработка ошибок, логирование и масштабирование.
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"name": "self-correcting-agent",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "A simple Node.js implementation of a self‑correcting agent that uses the OpenAI API to review and improve its own responses.",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"start": "node index.js",
|
||||||
|
"test": "jest"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"openai",
|
||||||
|
"self-correcting",
|
||||||
|
"agent",
|
||||||
|
"nodejs"
|
||||||
|
],
|
||||||
|
"author": "Your Name",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"dotenv": "^16.4.5",
|
||||||
|
"openai": "^4.20.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"jest": "^29.7.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
import { Graph as GraphLib } from 'graphlib';
|
||||||
|
import _ from 'lodash';
|
||||||
|
|
||||||
|
export default class Graph {
|
||||||
|
constructor() {
|
||||||
|
this.graph = new GraphLib();
|
||||||
|
}
|
||||||
|
|
||||||
|
addNode(node) {
|
||||||
|
this.graph.setNode(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
addEdge(from, to) {
|
||||||
|
this.graph.setEdge(from, to);
|
||||||
|
}
|
||||||
|
|
||||||
|
hasEdge(from, to) {
|
||||||
|
return this.graph.hasEdge(from, to);
|
||||||
|
}
|
||||||
|
|
||||||
|
reflexive() {
|
||||||
|
this.graph.nodes().forEach((node) => {
|
||||||
|
if (!this.graph.hasEdge(node, node)) {
|
||||||
|
this.graph.setEdge(node, node);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getAdjacencyList() {
|
||||||
|
const adjacency = {};
|
||||||
|
this.graph.nodes().forEach((node) => {
|
||||||
|
adjacency[node] = this.graph.successors(node) || [];
|
||||||
|
});
|
||||||
|
return adjacency;
|
||||||
|
}
|
||||||
|
}
|
||||||
+12
-57
@@ -1,63 +1,18 @@
|
|||||||
#!/usr/bin/env node
|
import Graph from './graph.js';
|
||||||
/**
|
|
||||||
* Simple Self-Correcting Agent
|
|
||||||
*
|
|
||||||
* This script demonstrates a minimal self‑correcting agent that
|
|
||||||
* takes a string input and attempts to correct common typos such as
|
|
||||||
* extra spaces, missing punctuation, and simple misspellings using
|
|
||||||
* a small dictionary.
|
|
||||||
*
|
|
||||||
* The implementation uses only the Node.js standard library
|
|
||||||
* and does not depend on any external frameworks.
|
|
||||||
*/
|
|
||||||
|
|
||||||
const process = require('process');
|
const g = new Graph();
|
||||||
|
|
||||||
// A very small dictionary of common misspellings
|
g.addNode('A');
|
||||||
const MISSPELLINGS = {
|
g.addNode('B');
|
||||||
"teh": "the",
|
g.addNode('C');
|
||||||
"recieve": "receive",
|
|
||||||
"adress": "address",
|
|
||||||
"occured": "occurred",
|
|
||||||
"seperate": "separate",
|
|
||||||
"definately": "definitely",
|
|
||||||
"goverment": "government",
|
|
||||||
"untill": "until",
|
|
||||||
"accomodate": "accommodate",
|
|
||||||
"wich": "which",
|
|
||||||
};
|
|
||||||
|
|
||||||
function correctSpelling(word) {
|
g.addEdge('A', 'B');
|
||||||
return MISSPELLINGS[word.toLowerCase()] || word;
|
g.addEdge('B', 'C');
|
||||||
}
|
|
||||||
|
|
||||||
function correctSentence(sentence) {
|
console.log('Before reflexive:');
|
||||||
// Strip whitespace
|
console.log(g.getAdjacencyList());
|
||||||
sentence = sentence.trim();
|
|
||||||
// Collapse multiple spaces
|
|
||||||
sentence = sentence.replace(/\s+/g, ' ');
|
|
||||||
// Tokenise and correct words
|
|
||||||
const words = sentence.split(' ');
|
|
||||||
const correctedWords = words.map(correctSpelling);
|
|
||||||
let corrected = correctedWords.join(' ');
|
|
||||||
// Ensure ending punctuation
|
|
||||||
if (!/[.!?]$/.test(corrected)) {
|
|
||||||
corrected += '.';
|
|
||||||
}
|
|
||||||
return corrected;
|
|
||||||
}
|
|
||||||
|
|
||||||
function main() {
|
g.reflexive();
|
||||||
const args = process.argv.slice(2);
|
|
||||||
if (args.length === 0) {
|
|
||||||
console.log('Usage: node src/index.js "<sentence>"');
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
const inputSentence = args.join(' ');
|
|
||||||
const corrected = correctSentence(inputSentence);
|
|
||||||
console.log(corrected);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (require.main === module) {
|
console.log('After reflexive:');
|
||||||
main();
|
console.log(g.getAdjacencyList());
|
||||||
}
|
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
import Graph from '../src/graph.js';
|
||||||
|
|
||||||
|
describe('Graph', () => {
|
||||||
|
test('should add nodes and edges correctly', () => {
|
||||||
|
const g = new Graph();
|
||||||
|
g.addNode('x');
|
||||||
|
g.addNode('y');
|
||||||
|
g.addEdge('x', 'y');
|
||||||
|
|
||||||
|
expect(g.hasEdge('x', 'y')).toBe(true);
|
||||||
|
expect(g.hasEdge('y', 'x')).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('reflexive should add self loops', () => {
|
||||||
|
const g = new Graph();
|
||||||
|
g.addNode('x');
|
||||||
|
g.addNode('y');
|
||||||
|
g.addEdge('x', 'y');
|
||||||
|
|
||||||
|
g.reflexive();
|
||||||
|
|
||||||
|
expect(g.hasEdge('x', 'x')).toBe(true);
|
||||||
|
expect(g.hasEdge('y', 'y')).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('getAdjacencyList returns correct structure', () => {
|
||||||
|
const g = new Graph();
|
||||||
|
g.addNode('x');
|
||||||
|
g.addNode('y');
|
||||||
|
g.addEdge('x', 'y');
|
||||||
|
|
||||||
|
g.reflexive();
|
||||||
|
|
||||||
|
const adj = g.getAdjacencyList();
|
||||||
|
expect(adj['x']).toContain('y');
|
||||||
|
expect(adj['x']).toContain('x');
|
||||||
|
expect(adj['y']).toContain('y');
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user