Локальный AI-агент для генерации, проверки и автоматического исправления Lua-кода через управляемый agent loop.
LocalScript - это backend-сервис, который превращает пользовательский запрос на естественном языке в рабочий Lua-код. Агент не просто один раз вызывает модель: он планирует следующий шаг, генерирует решение, валидирует результат и при ошибках запускает цикл исправления.
Проект построен вокруг локального inference через Ollama и модели qwen2.5-coder:7b. Внешние AI API не используются, поэтому систему можно запускать и демонстрировать в изолированной среде.
Главная идея проекта - показать практичную LLM-инженерию: не красивую обертку над промптом, а контролируемый пайплайн с состоянием, валидацией, ограничениями, retry logic и понятной архитектурой.
- Local-first architecture: генерация работает локально через Ollama, без OpenAI API, Anthropic API или других облачных провайдеров.
- Custom agent loop: агент написан вручную, без LangChain и LangGraph, поэтому логика принятия решений полностью прозрачна.
- Planner + tools pattern: planner выбирает действие, а tools выполняют конкретные шаги:
generate,fix,clarify,done. - Validation-driven generation: сгенерированный Lua-код проверяется перед возвратом пользователю.
- Self-repair flow: если validator находит ошибку, агент передает ее обратно модели и просит исправить уже существующий код.
- Session memory: API хранит историю диалога по
session_idи обрезает контекст при превышении лимита. - Robust JSON parsing: отдельный parser вытаскивает JSON даже из неидеальных ответов модели.
- Docker-ready demo: сервис, Ollama и загрузка модели описаны в Docker Compose.
User request
|
v
FastAPI /chat
|
v
Session memory + context trimming
|
v
Agent planner
|
+--> clarify -> one short clarification question
+--> generate -> Lua code generation
+--> fix -> error-aware code repair
+--> done -> final response
|
v
Lua validator
|
v
Structured JSON response
Такой подход делает поведение агента предсказуемым: модель отвечает не произвольным текстом, а структурированным JSON, а каждое действие проходит через контролируемую Python-логику.
| Area | Technologies |
|---|---|
| API | FastAPI, Pydantic, Uvicorn |
| Local LLM | Ollama, qwen2.5-coder:7b |
| Agent Runtime | Custom Python agent loop |
| Prompting | Planner prompt, generation prompt, fix prompt |
| Validation | luac, lua, subprocess timeouts |
| State | Server-side session memory |
| Packaging | Docker, Docker Compose |
generate -> validate -> fix -> validate -> done
Агент работает итеративно:
- Planner анализирует историю, текущий код и последнюю ошибку.
- Generator создает компактный Lua-код в строгом JSON-формате.
- Validator проверяет синтаксис через
luac. - Fixer получает исходную задачу, текущий код и текст ошибки.
- Agent loop повторяет исправление до успешной проверки или достижения лимита.
Это приближает проект к реальному coding assistant, где важен не сам факт генерации, а способность дойти до валидного результата.
Проверка, что сервис запущен.
{
"message": "service is running"
}Основной endpoint для работы с агентом.
Request:
{
"session_id": "demo-user",
"message": "Напиши Lua-функцию для факториала"
}Response:
{
"status": "success",
"code": "function factorial(n)\n if n == 0 then return 1 end\n return n * factorial(n - 1)\nend",
"explanation": "Recursive factorial implementation",
"error": null,
"reasoning": "Valid code is already available.",
"confidence": 0.9
}Possible statuses:
| Status | Description |
|---|---|
success |
код успешно создан и прошел проверку |
clarify |
агенту нужно одно уточнение от пользователя |
failed |
агент не смог получить валидный результат в заданных лимитах |
Сброс server-side memory для выбранной сессии.
cd docker
docker compose up --buildПосле запуска будут подняты:
- ollama на порту
11434; - model-init для загрузки
qwen2.5-coder:7b; - agent на порту
8080.
Проверка API:
curl http://localhost:8080/Пример запроса:
curl -X POST http://localhost:8080/chat \
-H "Content-Type: application/json" \
-d '{
"session_id": "demo-user",
"message": "Сделай Lua-код для сортировки массива чисел"
}'.
├── main.py # FastAPI app, endpoints, session memory
├── requirements.txt
├── docker/
│ ├── Dockerfile # Python service image
│ └── docker-compose.yml # Ollama + model init + agent service
├── data/
│ ├── examples/fewshot.json # few-shot examples for generation
│ └── tasks/dataset_seed.jsonl
├── src/
│ ├── agent/
│ │ ├── agent.py # main agent loop and tool dispatcher
│ │ └── state.py # conversation state, code, errors, confidence
│ ├── llm/
│ │ └── llm.py # Ollama client wrapper
│ ├── prompts/
│ │ ├── planner.py # action selection prompt
│ │ ├── generate.py # Lua generation prompt
│ │ ├── fix.py # validation-aware repair prompt
│ │ └── decide.py
│ ├── utils/
│ │ └── parser.py # defensive JSON extraction and normalization
│ ├── validator/
│ │ └── validator.py # Lua validation helpers
│ └── config.py # model and agent settings
└── tests/
└── test_generate_prompt.py
Агентная логика реализована вручную. Это делает проект проще для отладки и честнее для демонстрации: видно, где planner принимает решение, где вызывается модель, где парсится ответ и где происходит validation.
Модель должна возвращать JSON с полями code и explanation. Так API получает не свободный текст, а предсказуемую структуру, которую можно валидировать и отдавать клиенту.
Локальные модели не всегда идеально соблюдают формат. Поэтому parser умеет убирать markdown fences, извлекать JSON из ответа, чистить control characters и нормализовать переносы строк внутри кода.
Система не доверяет результату модели на слово. Lua-код проходит проверку через luac, а ошибка сохраняется в state и используется на следующей итерации исправления.
В src/config.py заданы ограничения на модель и поведение агента:
MODEL_NAME = "qwen2.5-coder:7b"
LLM_OPTIONS = {
"num_ctx": 4096,
"num_predict": 256,
"temperature": 0.2
}
MAX_FIX_ATTEMPTS = 4
MAX_CLARIFY_ATTEMPTS = 3Эти лимиты помогают избежать бесконечных циклов и делают поведение сервиса более предсказуемым.
LocalScript показывает несколько важных навыков, которые полезны в реальной backend и AI engineering разработке:
- проектирование agentic workflow без магии фреймворков;
- работа с локальными open-source моделями;
- prompt engineering под строгий JSON output;
- обработка нестабильных LLM-ответов;
- server-side memory и context trimming;
- subprocess-based validation;
- контейнеризация AI-сервиса;
- умение превращать эксперимент с моделью в воспроизводимый API.
- Добавить полноценные endpoint tests для
/chatи/reset. - Подключить runtime validation в основной путь агента.
- Вынести
MODEL_NAMEв environment variables. - Добавить benchmark report по качеству генерации.
- Реализовать persistent session storage.
- Добавить UI-клиент для демонстрации agent loop.
Проект собран как демонстрация практической AI engineering разработки: локальная LLM, управляемый agent loop, validation-first подход и аккуратный backend API.
