LangChainGo: подключение Go-приложения к OpenAI-совместимому API
Библиотека langchaingo принимает любой OpenAI-совместимый адрес. Показываем клиент, запрос, стриминг и цепочку с шаблоном на Go и считаем стоимость вызовов.
5 мин · · разработка · API-ключи
LangChain для Go, он же langchaingo, ходит в модели через тот же протокол, что и официальный OpenAI SDK. Поэтому его можно направить на любой OpenAI-совместимый шлюз, поменяв адрес, ключ и имя модели. Ниже настройка langchain go по шагам: клиент, простой запрос, сообщения с системной ролью, стриминг и цепочка с шаблоном. В конце считаем, сколько стоят такие вызовы.
Код сверен с исходниками библиотеки github.com/tmc/langchaingo на 18 октября 2026. API библиотеки развивается, поэтому перед началом сверьтесь со своей версией на pkg.go.dev. В go.mod библиотеки на момент проверки указан Go 1.26, убедитесь, что ваш тулчейн подходит.
Установка и ключ
go get github.com/tmc/langchaingoКлюч fetch_... создаётся в кабинете Zukko. Полный ключ показывается один раз, сохраните его и передавайте приложению через переменную окружения:
export ZUKKO_API_KEY=fetch_ваш_ключКлиент: base URL, ключ и модель
Пакет llms/openai создаёт клиента функцией openai.New с опциями. Три нужные нам: WithBaseURL, WithToken и WithModel.
package main
import (
"context"
"fmt"
"log"
"os"
"github.com/tmc/langchaingo/llms"
"github.com/tmc/langchaingo/llms/openai"
)
func main() {
ctx := context.Background()Адрес для OpenAI-формата всегда с /v1: https://api.zukko.pro/v1. Библиотека сама добавит путь /chat/completions.
То же без кода: по исходникам клиент читает переменные окружения OPENAI_BASE_URL, OPENAI_API_KEY и OPENAI_MODEL, если опции не заданы. Тогда в программе достаточно openai.New(), а адрес, ключ и модель переключаются снаружи.
Сообщения, системная роль и расход токенов
Для диалога с системной инструкцией используйте GenerateContent:
messages := []llms.MessageContent{
llms.TextParts(llms.ChatMessageTypeSystem, "Ты помощник Go-разработчика. Отвечай кратко."),
llms.TextParts(llms.ChatMessageTypeHuman, "Чем context.WithTimeout отличается от context.WithDeadline?"),
}
resp, err := llm.GenerateContent(ctx, messages, llms.WithTemperature(0.2))
if err != nil {
log.Fatal(err)
}
choice := resp.Choices[0]
fmt.Println(choice.Content)
fmt.Println("вход:", choice.GenerationInfo["PromptTokens"],
"выход:", choice.GenerationInfo["CompletionTokens"],
"из кэша:", choice.GenerationInfo["PromptCachedTokens"])В GenerationInfo библиотека складывает данные об использовании токенов: PromptTokens, CompletionTokens, TotalTokens, а также PromptCachedTokens. У моделей GPT шлюз видит чтение кэша, и оно приходит в prompt_tokens_details.cached_tokens, откуда библиотека берёт это поле. Эти числа удобно писать в лог: они позволяют свериться со списаниями в кабинете.
Про llms.WithMaxTokens: по исходникам библиотека отправляет его как max_completion_tokens. Если конкретная модель или маршрут отвечают 400 на этот параметр, уберите опцию, проверьте запрос через curl и сверьтесь с документацией langchaingo о режиме старого поля max_tokens.
Стриминг
_, err = llm.GenerateContent(ctx, messages,
llms.WithStreamingFunc(func(ctx context.Context, chunk []byte) error {
fmt.Print(string(chunk))
return nil
}),
)Сервер Zukko в потоке OpenAI-формата всегда присылает последний чанк с usage и пустым списком choices. Если писать разбор потока самому, проверяйте, что choices не пуст, прежде чем читать первый элемент. В langchaingo такой чанк обрабатывается: библиотека пропускает его как текстовый кусок и берёт из него статистику использования.
Цепочка с шаблоном
В langchaingo шаблон запроса и модель связывает LLMChain. Шаблон в актуальной версии записывается в синтаксисе Go template:
import (
"github.com/tmc/langchaingo/chains"
"github.com/tmc/langchaingo/prompts"
)
prompt := prompts.NewPromptTemplate(
"Предложи три названия для сервиса, который {{.description}}. Ответ списком.",
[]string{"description"},
)
chain := chains.NewLLMChain(llm, prompt)
out, err := chains.Run(ctx, chain, "переводит голосовые сообщения в текст")
if err != nil {
log.Fatal(err)
}
fmt.Println(out)chains.Run подходит, когда у цепочки один входной параметр и один выход. Для нескольких параметров используйте chains.Call и передавайте map[string]any. Если вы переносите примеры из старых статей, проверьте синтаксис подстановки: фигурные скобки с одним именем без точки могут не сработать.
Официальный SDK openai-go
Если LangChain вам не нужен, а нужен просто клиент OpenAI-формата на Go, подойдёт официальная библиотека github.com/openai/openai-go/v3. По её README адрес меняется опцией option.WithBaseURL:
client := openai.NewClient(
option.WithBaseURL("https://api.zukko.pro/v1"),
option.WithAPIKey(os.Getenv("ZUKKO_API_KEY")),
)
resp, err := client.Chat.Completions.New(ctx, openai.ChatCompletionNewParams{
Messages: []openai.ChatCompletionMessageParamUnion{
openai.UserMessage("Привет! Ответь одним словом."),
},
Model: "deepseek-v4.1-flash",
})
if err != nil {
log.Fatal(err)
}
fmt.Println(resp.Choices[0].Message.Content)Пакеты openai и option импортируются из github.com/openai/openai-go/v3 и github.com/openai/openai-go/v3/option. В README этой библиотеки на момент проверки указан Go 1.26 или новее. Если нужен низкоуровневый вариант с net/http и разбором SSE, см. Claude API в Go.
Сколько это стоит
Цены на 18 октября 2026, доллары за 1M токенов. Пример: сервис обрабатывает 1 000 запросов, в каждом 400 токенов входа и 150 токенов выхода. Это 0.4M токенов входа и 0.15M выхода.
| Модель | Вход / выход | Формула | Итого |
|---|---|---|---|
deepseek-v4.1-flash | 0.013 / 0.038 | 0.4 × 0.013 + 0.15 × 0.038 | $0.0109 |
gpt-6.1-sol | 0.27 / 1.32 | 0.4 × 0.27 + 0.15 × 1.32 | $0.306 |
claude-sonnet-5-5 | 0.4 / 2 | 0.4 × 0.4 + 0.15 × 2 | $0.46 |
Для Claude через langchaingo и формат chat/completions весь вход идёт по цене входа, а скидка за кэш работает в Anthropic-формате. У GPT чтение кэша видно в обоих форматах. Актуальный список моделей и цен — GET https://api.zukko.pro/v1/models, подробности о форматах — в справочнике chat/completions. Чтобы тестовый цикл не потратил лишнего, заведите отдельный ключ с дневным лимитом.
Если что-то не работает
Ошибки приходят из библиотеки как обычный error с текстом ответа сервера. Ориентируйтесь на смысл:
- 401: неверный ключ. Проверьте префикс
fetch_и что переменная окружения задана в том процессе, который запускает программу. - 402: не хватает баланса.
- 403
model_not_allowed_for_key: модели нет в списке разрешённых у ключа. - 404
model_not_found: неверное имя модели, сверьтесь сGET /v1/models. Если ошибка 404 приходит на каждый запрос, проверьте адрес: он должен заканчиваться на/v1. - 503
model_disabled: модель выключена, переключитесь на другую из списка.
Доступ из России — через шлюз, оплата СБП (платёжная страница добавляет 8,5% сверху), картой MasterCard или криптой. Разбор ошибок — в статье 401, 402, model not found.
Частые вопросы
Можно ли в langchaingo использовать Claude или DeepSeek, а не только GPT?
Да. Шлюз принимает любую свою модель в OpenAI-формате, поэтому достаточно поменять строку в WithModel. Перед сменой проверьте, что нужная вам функция (инструменты, JSON-режим) работает с выбранной моделью.
Нужно ли писать /v1 в адресе?
Да, для OpenAI-формата адрес https://api.zukko.pro/v1. Без /v1 запросы уйдут на неверный путь.
Как узнать, сколько токенов потратил запрос?
Читайте GenerationInfo в ответе: поля PromptTokens, CompletionTokens и PromptCachedTokens. Историю расходов смотрите в кабинете в разделе «Использование» или через GET /v1/usage.
Есть ли у langchaingo готовый агент с инструментами?
В библиотеке есть агенты и инструменты, но их состав и API менялись, поэтому смотрите примеры в репозитории в папке examples под вашу версию.
zukko
Платите в 25×
меньше
за Claude Code & ChatGPT
Один ключ fetch_* и base URL api.zukko.pro — в Cursor, Claude Code, Codex и любом SDK.
Похожие статьи
- Свой прокси к нейросети на Node.js: не показывать API-ключ во фронтендеНебольшой сервер на Express между вашим фронтендом и API нейросети: ключ остаётся на сервере, а модели, длина запроса и частота ограничены.
- DeepSeek API на Python: запросы, стриминг, JSON и обработка ошибокГотовый код для DeepSeek V4.1 Flash и V4 Pro на OpenAI SDK: запрос, стриминг, разбор JSON и аккуратная обработка ошибок.
- Gemini API на Python: запросы через OpenAI SDK и OpenAI-форматРабочий пример Gemini API на Python без отдельной библиотеки: меняем base_url в OpenAI SDK, добавляем стриминг и JSON и сравниваем с google-genai.
- Anthropic SDK для Python: base_url, ключ и первый запрос через шлюзОфициальный пакет anthropic для Python нужно только направить на другой адрес. Разбираем base_url, ключ, стриминг, подсчёт токенов, кэш и ошибки.