Решения

LLM‑агенты и инструменты: function calling и контекст

Задача страницы. Показать, как проектировать и эксплуатировать LLM‑агентов: function calling, управление контекстом и токен‑бюджетом, циклы observe‑act, шедулинг инструментов, SLA/стоимость, безопасность и наблюдаемость.

TL;DR

  • Проще и надёжнее один хорошо спроектированный одиночный агент с инструментами, чем «рои» агентов без ограничений.
  • Ключ к стабильности: строгий контракт JSON, лимиты глубины петли (шагов) и тайм‑ауты инструментов.
  • Снижение стоимости: короткие префиксы, дедуп кэшей/контента, RAG вместо «пухлых» историй, квантизация и «малый роутер → большая модель».
  • Наблюдаемость на уровне event‑трейсов: request → plan → tool_start → tool_result → summary → response.

Базовая архитектура агента

  1. Gateway/API — принимает запрос, нормализует (язык, ограничение длины, идентификатор сессии).
  2. Policy/Planner — короткая подсказка‑политика (правила, цели, недопустимые действия).
  3. LLM runtime — движок сервинга: vLLM/TGI/TensorRT‑LLM/SGLang/llama.cpp
    (см. /solutions/llm-inference/).
  4. Tool Executor — единый реестр инструментов (HTTP, DB, поиск, код, калькулятор…).
  5. Memory/State — краткосрочная сессия (контекст), долговременная векторная память (RAG), аудиторский лог.
  6. Formatter — приведение ответа к нужному JSON/Markdown/API.

Для сложных доменов добавьте router‑модель (малую) перед «большой»: дешёвый роутинг по классу задачи → экономия токенов и GPU‑часов.

Связанные разделы:
— сервинг: /solutions/llm-inference/vllm/, /solutions/llm-inference/tgi/, /solutions/llm-inference/tensorrt-llm/, /solutions/llm-inference/sglang/, /solutions/llm-inference/llama-cpp/
— стриминг: /solutions/llm-inference/streaming/
— мультимодельный хостинг: /solutions/llm-inference/multi-model/ 

Контракт function calling (строгий JSON)

Сведите взаимодействие к «интент → функция → аргументы». Агент возвращает только JSON, без скрытых рассуждений.

Определение инструмента (JSON Schema):

				
					{
  "type": "function",
  "name": "search_flights",
  "description": "Поиск рейсов",
  "parameters": {
    "type": "object",
    "properties": {
      "from": {"type":"string"},
      "to":   {"type":"string"},
      "date": {"type":"string", "pattern":"^\\d{4}-\\d{2}-\\d{2}$"}
    },
    "required": ["from","to","date"],
    "additionalProperties": false
  }
}

				
			

Требование к ответу модели при выборе инструмента:

				
					{
  "tool_name": "search_flights",
  "arguments": {"from":"SVO","to":"LED","date":"2025-09-01"}
}

				
			

Если инструмент не нужен:

				
					{
  "final_answer": "Краткий ответ пользователю…"
}

				
			

Правила робастности

  • Включайте валидацию схемы и автопочинку лёгких ошибок (типы, форматы).
  • temperature 0–0.3, top_p 0.9, запрет на произвольный текст вне JSON.
  • Повторный запрос (retry) только при парс‑ошибке/тайм‑ауте инструмента (с ограничением по попыткам).

Контекст и токен‑бюджет

Что «ест» контекст: system + policy + tools_schema + история + user + retrieved_docs + tool_results.
Бюджет (приближённо):

				
					Tokens_in ≈ T_sys + T_policy + T_schema + T_history + T_user + T_retrieved + T_tools_out
Tokens_out ≈ L_out
Tokens_total ≤ MaxContext

				
			

Правила экономии

  • Короткий system и сжатая policy.
  • Историю суммировать (rolling summary) с сохранением фактов ID→значение.
  • Хранить ссылки/ключи вместо «полных» данных; подробности подтягивать через RAG.
  • Разделить «короткие/длинные» сессии по пулам (см. /solutions/llm-inference/multi-model/).
  • Контролировать max_tokens и max context в API.

Связанные разделы: /solutions/rag/, /solutions/embeddings/.

Цикл Plan → Act → Observe (ограничение глубины)

Ограничьте число инструментальных шагов, тайм‑ауты и идемпотентность.

Псевдокод оркестратора:

				
					MAX_STEPS = 4
for step in range(MAX_STEPS):
    msg = build_prompt(history, tools_schema, policy)
    out = call_llm(msg)  # vLLM/TGI/…
    if "final_answer" in out:
        return out["final_answer"]
    tool = out["tool_name"]; args = out["arguments"]
    if not allowed(tool): return "Запрошен запрещенный инструмент"
    tool_result = call_tool_with_timeout(tool, args, timeout=8.0)
    history.append({"role":"tool", "name":tool, "content":truncate(tool_result, 2048)})
# если шаги исчерпаны
return "Нужны уточнения или слишком сложный запрос."

				
			

Рекомендации

  • Timeout/Retry/Backoff на каждый инструмент.
  • Идемпотентность: повторный вызов не должен портить состояние (или используйте транзакции/«сухой прогон»).
  • Лимит объёма tool_result в контекст (например, 2–4 К токенов + сжатие).

Инструменты (паттерны)

  • Внешние API/БД (чтение/запись) — через строго типизированные клиенты.
  • RAG — извлечение пассажа + референса; в контекст подаётся краткая цитата + id.
  • Калькуляторы/компиляторы — sandbox, лимит CPU/памяти/времени.
  • Воркфлоу — запуск подзадач (рендер, транскод, ML‑инференс).

Связанные страницы: /solutions/rag/, /solutions/llm-inference/streaming/.

Стриминг и UX

  • Возвращайте TTFT как можно раньше: система → план → первые токены.
  • Для инструментов генерируйте события: tool_start/tool_result (SSE/WS) — удобно в UI и логах.
  • Поддерживайте cancel/«стоп» и idle timeout (см. /solutions/llm-inference/streaming/).

SLA и стоимость

Обозначим: P — prefill ток/с, D — decode ток/с на батч, B — батч, L_in/L_out — длины, O — накладные, N_tools — число вызовов инструментов.

Латентность (приближённо):

T ≈ (L_in / P) + (L_out / (D / B)) + N_tools × (T_tool + T_marshal) + O

QPS и цена за 1M токенов:

QPS ≈ B / T

Tokens_per_hour ≈ D × 3600

Cost_per_1M ≈ (GPU_hour_price × Num_GPU) / (Tokens_per_hour / 1e6)

Снижение T/цены: квантизация (см. /solutions/llm-inference/quantization/), «router → big», строгие лимиты длины, кэширование результатов инструментов.

Безопасность и guardrails

  • Allow‑list инструментов и доменов, валидация аргументов по схеме.
  • PII‑санитайзинг до отправки в инструменты/лог.
  • Политики: запрет опасных действий, ограничение «кода/записей» только на безопасные рантаймы.
  • Аудит‑лог: кто/когда/что вызвал, аргументы, результат, длительность, статус.

Связанные разделы: /solutions/llm-inference/guardrails/, /solutions/security/.

Наблюдаемость и отладка

  • Трейсы событий: request → plan → tool_start/result → tokens → done.
  • Метрики: TTFT/TBT/TTLT, N_tools, доля ошибок инструментов, парс‑ошибки JSON, retry‑rate.
  • Семплинг примеров для быстрой регресс‑оценки качества (см. /solutions/llm-training/eval/).
  • Логи без утечек PII; маскируйте секреты.

Связанные страницы: /solutions/llm-inference/observability/, /solutions/monitoring-logging/.

Паттерны надёжности

  • JSON‑режим + строгая схема + автопочинка (type‑coerce, defaults).
  • Роутер‑модель (малая) для дешёвого распознавания задачи.
  • Фиксация версий: модель@версия, инструменты@api‑версия, политика@hash.
  • Деградация: при перегрузе уменьшаем max_tokens, переводим в short‑pool или меньшую модель (см. /solutions/llm-inference/multi-model/).
  • Ограничение глубины петли и размера tool_result с обязательным резюме «для контекста».

Пример API агента (единая точка входа)

				
					# fastapi_agent.py
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()

class ChatRequest(BaseModel):
    messages: list
    tools: list | None = None
    max_tokens: int = 300

@app.post("/v1/agent")
def agent(req: ChatRequest):
    history = normalize(req.messages)
    tools_schema = compile_tools(req.tools or REGISTRY)
    for _ in range(4):  # MAX_STEPS
        out = call_llm(history, tools_schema, max_tokens=req.max_tokens)
        if "final_answer" in out:
            return {"choices":[{"message":{"content": out["final_answer"]}}]}
        result = call_tool(out["tool_name"], out["arguments"], timeout=8.0)
        history.append({"role":"tool","name":out["tool_name"],"content": trim(result, 2048)})
    return {"choices":[{"message":{"content":"Нужны уточнения."}}]}

				
			

Как запускать это в cloudcompute.ru

Чек‑лист перед продом

  • Контракт JSON Schema и режим вывода «только JSON».
  • Лимиты: max_tokens, max context, MAX_STEPS, тайм‑ауты инструментов.
  • Роутер‑модель/пулы (short/long), деградация и фоллбеки.
  • Метрики/трейсы: TTFT/TBT/TTLT, N_tools, ошибки/ретраи.
  • Безопасность: allow‑list инструментов, валидация аргументов, PII‑маскирование, аудит‑лог.
  • Ночные регрессы качества на ключевых задачах.