Локальные LLM всё доступнее. OmniCoder-9B
от aNNiMON
Продолжая изучать тему локальных моделей, я наткнулся на хорошо сбалансированный вариант: OmniCoder-9B. Я тестировал OmniCoder целую неделю на разных задачах и со всеми она справлялась достойно. В отличие от Gemma 4 и Qwen, подключив эту модель к Codex/Claude, проблем с вызовом тулов вообще не было.
Скачиваем модель в Ollama.
Модель занимает 5.7 Гб, даже меньше, чем Qwen3.5:9b (6.6 Гб). Однако, в отличие от Gemma 4 e4b, в которой 4 миллиарда параметров, OmniCoder-9B имеет 9 миллиардов параметров, так что имейте в виду, модель будет более требовательной к памяти. Я запускаю на ноутбуке с RTX 3060 Laptop GPU 6GB VRAM и 32 GB RAM. Если у вас железо мощнее, проблем быть не должно.
Агенты
Начнём с той же задачи, что и в случае с Gemma 4: понять, какая версия проекта на Rust.
What version is the project currently on?
Прочитав Cargo.toml, модель узнала текущую версию проекта.
Игра Змейка на HTML5
Теперь к кодингу. Повышаем контекстное окно и запускаем Claude.
Generate a fancy snake game in HTML5. Use interesting effects such as motion-blur and particles. Keep css/js files separately from html.
Три с половиной минуты потребовалось на создание html и css. И ещё столько же на js:
● I've created a fancy neon snake game with the following features:
Visual Effects:
• Motion blur trail - The snake leaves a fading trail effect
• Particle explosions - Colorful particles burst when eating food or dying
• Screen shake - Intense shake on collisions and food consumption
• Glow effects - Neon glow around the snake head and pulsing food
• CRT scanline overlay - Retro screen effect
Game Features:
• Score tracking with high score (saved to localStorage)
• Progressive speed increase as you eat
• Smooth WASD/Arrow key controls
• Pulsing food with highlight effect
• Gradient coloring on snake body
Files created:
• index.html - Main game page with start/game over screens
• styles.css - Neon styling with glow effects and CRT overlay
• game.js - Snake logic, particles, and collision handling
Controls: Arrow keys or WASD to move. The food pulses and has a glowing ring effect. When you eat food, particles explode and the screen shakes. Game over triggers a larger explosion.
✻ Cogitated for 7m 3s

Первый вариант уже был рабочий, за исключением того, что змейка появлялась направленной саму в себя и нужно было быстро нажимать вниз или вверх, чтобы избежать проигрыша. И ещё еда для змейки перемещалась на новое место каждую секунду, так что было сложно угнаться. Зато логика, распадание съеденной еды на частицы, коллизии, тряска камеры, всё это работало отлично.

Результат:
- Игра: snake-omnicoder/
-
snake-omnicoder.zip

Режим планирования
В режиме планирования в Claude я попросил сделать на Python пайплайн для обработки ссылок: валидация, вытягивание метаданных, отправка текста в TTS, генерирование небольшого текстового превью о чём заданная статья и т.п.

Omnicoder сгенерировал адекватный план с вот такими нодами:
Спланировал входные и выходные параметры каждой ноды. И структуру файлов:
Весь план:
now-we-need-to-velvet-creek.md
Затем 10 минут всё это дело ворочал. Результат содержал одну ошибку, да и то, не в Python коде, а в регулярном выражении для вытягивания id видео с ютуба он не обозначил группу в скобках, хотя использовал её далее в коде.
И ещё в Ollama-нодах прописал дефолтным не Gemma4, а другую модель. Всё же результат очень достойный, учитывая, что весь этот код написан с первой итерации.
Вот готовое приложение в работе. За summary и mindmap отвечала локальная Gemma 4.


Добавление функционала в Java проект
Проверим работу с Java на примере добавления нового FFmpeg параметра в https://github.com/aNNiMON/effybot
Add audio noise reduction parameter (afftdn) with noise reduction -40, -20, -10, -5, -2 dB.
OmniCoder изучил проект, разобрался с организацией существующих параметров и сгенерировал готовый класс:
Затем добавил его обработку в интерфейсе Visitor
и его реализации FFmpegCommandBuilder
Так же добавил создание экземпляра AudioNoiseReduction в AudioResolver, где создаются все параметры аудио.

Задача хоть и не очень сложная, но модель однозначно справилась с первой попытки, затратив порядка 7 минут на всё.
Заключение
Моделью я очень доволен. Она сравнительно компактная, имеет приемлемую скорость. Для повседневных вопросов, как то сделать краткую выжимку текста, модель не очень подойдёт. Зато она отлично работает с тулами и с разными языками программирования.
Если знаете ещё какие-то интересные модельки, делитесь в комментариях.
English version
Скачиваем модель в Ollama.
- ollama pull carstenuhlig/omnicoder-9b
Модель занимает 5.7 Гб, даже меньше, чем Qwen3.5:9b (6.6 Гб). Однако, в отличие от Gemma 4 e4b, в которой 4 миллиарда параметров, OmniCoder-9B имеет 9 миллиардов параметров, так что имейте в виду, модель будет более требовательной к памяти. Я запускаю на ноутбуке с RTX 3060 Laptop GPU 6GB VRAM и 32 GB RAM. Если у вас железо мощнее, проблем быть не должно.
Агенты
Начнём с той же задачи, что и в случае с Gemma 4: понять, какая версия проекта на Rust.
What version is the project currently on?

Прочитав Cargo.toml, модель узнала текущую версию проекта.
Игра Змейка на HTML5
Теперь к кодингу. Повышаем контекстное окно и запускаем Claude.
- OLLAMA_CONTEXT_LENGTH=80000
- ollama launch claude
Generate a fancy snake game in HTML5. Use interesting effects such as motion-blur and particles. Keep css/js files separately from html.

Три с половиной минуты потребовалось на создание html и css. И ещё столько же на js:
● I've created a fancy neon snake game with the following features:
Visual Effects:
• Motion blur trail - The snake leaves a fading trail effect
• Particle explosions - Colorful particles burst when eating food or dying
• Screen shake - Intense shake on collisions and food consumption
• Glow effects - Neon glow around the snake head and pulsing food
• CRT scanline overlay - Retro screen effect
Game Features:
• Score tracking with high score (saved to localStorage)
• Progressive speed increase as you eat
• Smooth WASD/Arrow key controls
• Pulsing food with highlight effect
• Gradient coloring on snake body
Files created:
• index.html - Main game page with start/game over screens
• styles.css - Neon styling with glow effects and CRT overlay
• game.js - Snake logic, particles, and collision handling
Controls: Arrow keys or WASD to move. The food pulses and has a glowing ring effect. When you eat food, particles explode and the screen shakes. Game over triggers a larger explosion.
✻ Cogitated for 7m 3s

Первый вариант уже был рабочий, за исключением того, что змейка появлялась направленной саму в себя и нужно было быстро нажимать вниз или вверх, чтобы избежать проигрыша. И ещё еда для змейки перемещалась на новое место каждую секунду, так что было сложно угнаться. Зато логика, распадание съеденной еды на частицы, коллизии, тряска камеры, всё это работало отлично.

Результат:
- Игра: snake-omnicoder/
-
snake-omnicoder.zip
Режим планирования
В режиме планирования в Claude я попросил сделать на Python пайплайн для обработки ссылок: валидация, вытягивание метаданных, отправка текста в TTS, генерирование небольшого текстового превью о чём заданная статья и т.п.

Omnicoder сгенерировал адекватный план с вот такими нодами:
- ┌─────────┐
- │ URL │ ──→ validate & detect type (regex)
- └─────────┘
- ↓
- ┌─────────────────────────┐
- │ Type Router │
- │ ├─ YouTube URL → yt-dlp │
- │ └─ Article URL → fetch │
- └─────────────────────────┘
- ↓
- ┌────────────────────────────┐
- │ Node 1: Metadata Extractor │
- │ (yt-dlp metadata + content)│
- │ ↓ saves to temp file │
- └────────────────────────────┘
- ↓
- ┌───────────────────────┐
- │ Node 2: Summarizer │
- │ (Ollama: summary) │
- │ ↓ reads temp file │
- │ ↓ saves to temp file │
- └───────────────────────┘
- ↓
- ┌──────────────────────┐
- │ Node 3: Mindmap │
- │ (Ollama: mindmap) │
- │ ↓ reads temp file │
- │ ↓ saves to temp file │
- └──────────────────────┘
- ↓
- ┌───────────────────────┐
- │ Node 4: TTS Generator │
- │ (Ollama: tts) │
- │ ↓ reads temp file │
- │ ↓ saves to temp file │
- └───────────────────────┘
- ↓
- ┌───────────────────────────┐
- │ Node 5: Markdown Renderer │
- │ (assembles all outputs) │
- └───────────────────────────┘
Спланировал входные и выходные параметры каждой ноды. И структуру файлов:
- summarize/
- ├── summarize.py # Main CLI entry point
- ├── nodes/ # Node implementations
- │ ├── base.py # Abstract base class for nodes
- │ ├── router.py # URL type detection & routing
- │ ├── metadata.py # yt-dlp extraction
- │ ├── summarizer.py # Ollama summary
- │ ├── mindmap.py # Ollama mindmap
- │ ├── tts.py # TTS
- │ └── renderer.py # Markdown assembly
- └── requirements.txt # Dependencies
Весь план:
now-we-need-to-velvet-creek.mdЗатем 10 минут всё это дело ворочал. Результат содержал одну ошибку, да и то, не в Python коде, а в регулярном выражении для вытягивания id видео с ютуба он не обозначил группу в скобках, хотя использовал её далее в коде.
- YOUTUBE_PATTERNS = [
- r'https?://www\.youtube\.com/watch\?v=[\w_-]+',
- r'https?://youtu\.be/[\w_-]+',
- r'https?://m\.youtube\.com/watch\?v=[\w_-]+',
- ]
- for pattern in self.YOUTUBE_PATTERNS:
- match = re.search(pattern, url)
- if match:
- if 'youtu.be/' in url:
- return url.split('youtu.be/')[1].split('?')[0].split('/')[0]
- return match.group(1) if match.group(1) else match.group(0).split('v=')[1].split('&')[0]
И ещё в Ollama-нодах прописал дефолтным не Gemma4, а другую модель. Всё же результат очень достойный, учитывая, что весь этот код написан с первой итерации.
Вот готовое приложение в работе. За summary и mindmap отвечала локальная Gemma 4.


Добавление функционала в Java проект
Проверим работу с Java на примере добавления нового FFmpeg параметра в https://github.com/aNNiMON/effybot
Add audio noise reduction parameter (afftdn) with noise reduction -40, -20, -10, -5, -2 dB.
OmniCoder изучил проект, разобрался с организацией существующих параметров и сгенерировал готовый класс:
- package com.annimon.effybot.parameters;
- import com.annimon.effybot.commands.ffmpeg.Visitor;
- import java.util.List;
- public class AudioNoiseReduction extends StringParameter {
- public static final String ID = "anoreduce";
- private static final List<String> VALUES = List.of(
- "", "5", "12", "20", "30", "40"
- );
- public AudioNoiseReduction() {
- super(ID, "🔈 Noise Reduction", VALUES, "");
- }
- @Override
- public String describeValue(String value) {
- if (value.isEmpty()) {
- return "NONE";
- } else {
- return super.describeValue(value);
- }
- }
- @Override
- public int defaultColumnsCount() {
- return 4;
- }
- @Override
- public <I> void accept(Visitor<I> visitor, I input) {
- visitor.visit(this, input);
- }
- }
Затем добавил его обработку в интерфейсе Visitor
- intterface Visitor {
- // ...
- void visit(AudioNoiseReduction p, I input);
- }
- @Override
- public void visit(AudioNoiseReduction p, MediaSession input) {
- if (discardAudio) return;
- if (p.getValue().isEmpty()) return
- audioFilters.add("afftdn=nr=" + p.getValue());
- }
Так же добавил создание экземпляра AudioNoiseReduction в AudioResolver, где создаются все параметры аудио.

Задача хоть и не очень сложная, но модель однозначно справилась с первой попытки, затратив порядка 7 минут на всё.
Заключение
Моделью я очень доволен. Она сравнительно компактная, имеет приемлемую скорость. Для повседневных вопросов, как то сделать краткую выжимку текста, модель не очень подойдёт. Зато она отлично работает с тулами и с разными языками программирования.
Если знаете ещё какие-то интересные модельки, делитесь в комментариях.
English version

