Разработка ИИ-агентов · Модуль 4 · Урок 4.5

Капстоун: агент + собственный MCP-сервер на Go

Что собираем

Финальный проект соединяет весь курс: вы делаете собственный MCP-сервер на Go, выставляющий 1–2 полезных инструмента, и агент-хост, который подключается к этому серверу, отдаёт его инструменты модели и решает задачу в агентном цикле. Получается полноценный мини-продукт: модель рассуждает, MCP-сервер выполняет действия, агент всё оркеструет, а наблюдаемость показывает, что происходит.

Идея сервера может быть любой и приземлённой: заметки (создать/найти), задачи-todo, доступ к локальным файлам в песочнице, запрос к публичному API. Главное — пройти весь путь: схема инструмента → сервер → подключение → цикл → логи и стоимость.

Сборка по частям курса

Соберите проект, переиспользуя уже пройденное:

  • MCP-сервер (Модуль 4.2): stdio-сервер на официальном Go SDK (или на stdlib для понимания), с 1–2 инструментами, строгими схемами и валидацией.
  • Подключение (4.3): хост запускает сервер подпроцессом, делает initialize, tools/list, превращает инструменты в tool-схемы модели.
  • Агентный цикл (Модуль 1): send → стоп-сигнал → tools/call нужному серверу → дозапись результата → safety-cap.
  • Надёжность (Модуль 2): валидация, ретраи на временные ошибки, программный gate на необратимое действие.
  • Наблюдаемость и стоимость (4.4): структурные логи каждого оборота, агрегированный usage, приблизительная цена, prompt caching.

Не пытайтесь сделать всё сразу идеально: сначала «тонкая вертикаль» (один инструмент проходит весь путь), потом наращивайте.

Критерии готовности

Капстоун удался, если выполняется следующее. Агент через ваш MCP-сервер решает реальную задачу: на запрос, требующий инструмента, он делает корректный tools/call, получает результат и формулирует ответ; завершение — по стоп-сигналу, с работающим safety-cap. Сервер валидирует вход и не падает на кривых аргументах; логи в stderr не мешают протоколу в stdout. В логах видно: какие инструменты вызваны, сколько оборотов, сколько токенов и какая приблизительная стоимость.

Это и есть «агент в продакшн-форме» в миниатюре. Дальше его можно расширять: больше инструментов и ресурсов, несколько MCP-серверов, мультиагентная оркестрация из Модуля 3, человек в контуре на критичных шагах. Вы прошли путь от «LLM + инструменты + цикл» до агента со стандартным протоколом интеграций — поздравляем.

Каркас капстоуна: хост подключает MCP-сервер и крутит агентный цикл
func main() {
    log := slog.New(slog.NewJSONHandler(os.Stderr, nil))

    // 1. Подключаем собственный MCP-сервер (подпроцесс по stdio).
    client, err := startMCPServer("./mcp-notes") // initialize внутри
    if err != nil {
        log.Error("mcp start", "err", err)
        os.Exit(1)
    }
    defer client.Close()

    // 2. Берём инструменты сервера и отдаём их модели как tool-схемы.
    tools, owner, err := collectTools(map[string]mcpClient{"notes": client})
    if err != nil {
        log.Error("list tools", "err", err)
        os.Exit(1)
    }

    // 3. Агентный цикл (Модуль 1), где tool_calls маршрутизируются в MCP.
    messages := []Message{
        {Role: "system", Content: "Ты агент заметок. Для операций используй инструменты."},
        {Role: "user", Content: "Создай заметку «купить кофе» и подтверди."},
    }
    answer, stats, err := runAgentMCP(messages, tools, owner, client, log)
    if err != nil {
        log.Error("agent", "err", err)
        os.Exit(1)
    }
    log.Info("done", "round_trips", stats.RoundTrips, "total_tokens", stats.TotalTokens)
    fmt.Println(answer)
}

Anti-patterns

Анти-паттернПочему плохоКак правильно
Делать всё сразу: 10 инструментов, мультиагент, UIТонете в сложности, ничего не работает целикомТонкая вертикаль: один инструмент проходит весь путь, потом расширять
Капстоун без логов и подсчёта стоимостиНе видно, что и почём делает агентСтруктурные логи оборотов + агрегированный usage и цена
Необратимое действие без подтвержденияАгент может натворить дел автономноПрограммный gate / human-in-the-loop на критичных операциях
Сервер без валидации и обработки ошибокПадает на первом кривом вызовеВалидировать аргументы, возвращать ошибки как результат, логировать в stderr

Практическое задание (Капстоун)

  • Напишите MCP-сервер на Go с 1–2 инструментами (например, заметки: create_note, search_notes).
  • В хосте подключите сервер, выполните initialize/tools/list и преобразуйте инструменты в tool-схемы модели.
  • Реализуйте агентный цикл с маршрутизацией tool_calls в tools/call и safety-cap.
  • Добавьте валидацию на сервере, ретраи на временные ошибки и gate на необратимое действие.
  • Включите структурные логи каждого оборота и подсчёт токенов/стоимости; проверьте оба сценария — с инструментом и без.
  • Проверьте сквозной сценарий: запрос → корректный tools/call → результат → финальный ответ по стоп-сигналу.

Проверка знаний

С чего разумнее всего начать капстоун?

  • A Реализовать сразу все запланированные инструменты и мультиагентную оркестрацию
  • B Сделать тонкую вертикаль: один инструмент проходит весь путь сервер → подключение → цикл → логи, затем расширять
  • C Сначала написать UI
  • D Отложить наблюдаемость на потом

Какие сигналы подтверждают, что капстоун-агент работает корректно?

  • A Он всегда вызывает инструмент, даже на «привет»
  • B На задачу с инструментом делает корректный tools/call и отвечает по результату; завершается по стоп-сигналу; в логах видны инструменты, обороты, токены и стоимость
  • C Он никогда не обращается к серверу
  • D Он игнорирует ошибки сервера