Начало работы
svir — маленький компонуемый Rust SDK для общения с большими языковыми моделями: протокол обмена между вашим приложением и сервером модели — и ничего лишнего.
Он говорит на OpenAI-совместимом Chat Completions, всегда потоком — так, как его отдают LM Studio, llama.cpp, vLLM, mlx-lm, Azure OpenAI и облачные эндпоинты.
svir находится в стадии preview. Публичный API ещё может меняться между
релизами 0.x. Что изменилось — в
журнале изменений.
Этот сайт описывает svir 0.1.5.
Установка
svir требует Rust 1.85 или новее (edition 2024). Если Rust ещё не
установлен, поставьте его через rustup.
cargo add svir
cargo add tokio --features macros,rt-multi-thread
Или вручную:
[dependencies]
svir = "0.1.5"
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
Фичи по умолчанию дают клиент и HTTPS. Остальные подключаются явно; см. Фичи и TLS.
Первый вызов
Запустите любой OpenAI-совместимый сервер. LM Studio по умолчанию слушает
http://127.0.0.1:1234; вместо qwen3-27b подставьте ID модели, которая на
нём есть.
use svir::prelude::*;
#[tokio::main]
async fn main() -> Result<(), Error> {
let client = Client::openai("http://127.0.0.1:1234").build()?;
let request = Request::new("qwen3-27b")
.system("Be precise.")
.user("Why do rivers meander?");
// The whole answer.
let answer = client.complete(&request).await?;
println!("{}", answer.text.trim());
// The same answer as it arrives.
let mut stream = client.stream(&request).await?;
while let Some(event) = stream.next().await {
match event? {
Event::Text(piece) => print!("{piece}"),
Event::Completed(done) => println!("\n{:?}", done.usage),
_ => {}
}
}
Ok(())
}
Что здесь видно — и что повторяет любая программа на svir:
Client::openai(url)возвращает билдер;build()проверяет URL и ключ и возвращает клиента. URL — это база сервера, с/v1или без.- Модель — это ID, который перечисляет сервер, а не название семейства.
Узнать, что есть на сервере, можно через
client.list_models(). - Клиент не хранит диалог: диалог — это запрос, и владеете им вы.
completeвозвращает готовый ответ.streamотдаёт события по мере прихода; последнее из них,Event::Completed, несёт весь ответ.- Drop потока отменяет запрос.
Что он умеет
Ядро — это протокол:
- Типы: сообщения с частями — текстом, изображениями и файлами; описания, вызовы и результаты инструментов; обязательный или запрещённый вызов инструмента; ответ в JSON или в JSON по схеме; расход токенов; причины завершения; один типизированный тип ошибки.
- Кодировщик: тело запроса, которое стримится с диска вместе с
вложениями, с точным
Content-Length, известным до первого байта. - Декодер: разбор SSE, вызовы инструментов, собранные из дельт,
рассуждения из
reasoning_content,reasoningили inline-тегов<think>, расход токенов, ошибки внутри потока и жёсткие лимиты. Строгий по умолчанию, мягкий по запросу. - Транспорт: HTTP с необязательной Bearer-аутентификацией, типизированным разбором статусов, таймаутами и отменой через drop.
- Совместимость: сервер, который отвергает необязательные поля вроде
reasoning_effort, распознаётся один раз и запоминается. То, чему ответ должен соответствовать, — выбор инструмента или формат ответа, — никогда не отбрасывается.
Поверх ядра, по желанию:
- Слои: middleware вокруг каждого вызова, со
встроенными
Retry,TimeoutиTrace. - Инструменты: трейт
Toolboxдля всего, что описывает инструменты модели и отвечает на её вызовы, иTools— простой реестр типизированных обработчиков. Без макросов.
Намеренно не входит: цикл агента, история сессий, хранилище и MCP. Это территория приложения. svir даёт ему детали, а страницы этого сайта показывают те несколько строк, которые нужны для каждой.
Принципы
- Протокол в ядре, строительные блоки сверху. svir встаёт под чат-бэкенд и под движок агента, и никому из них не приходится под него прогибаться.
- Ничего не теряется молча. ID вызовов инструментов, рассуждения и служебные данные провайдера сохраняются при передаче туда и обратно. То, что адаптер не может представить, — явная ошибка, а не выброшенное поле.
- Сначала целиком, потом исполнение. Вызов инструмента, пришедший частично, — только данные для отображения.
- Строго и с лимитами по умолчанию. Неизвестный ввод — ошибка, если вы не попросили мягкий режим. У байтов, событий и вызовов инструментов всегда есть лимиты, и упереться в лимит — типизированный исход.
- Секреты не попадают в записи. Ключи никогда не оказываются в ошибках, событиях и логах.
- Тесты без модели. Транспорт спрятан за одним трейтом, поэтому код, который вызывает модель, можно тестировать вообще без сервера.
Что дальше
- Запросы и Чтение ответа — о повседневных вызовах.
- Инструменты — цикл, который возвращает модели результаты инструментов.
- Структурированный вывод — ответ в JSON, прочитанный в тип.
- Настройка и Слои — о клиенте.
- Ошибки и Диагностика — на случай, когда что-то не работает.
- Agent Skill учит всему этому кодового ассистента.
В каталоге примеров по одной короткой программе на каждый способ использования svir, а справочник API — на docs.rs.