В истории развития больших языковых моделей доминировал закон масштабирования предварительного обучения (Pre-training Scaling Law, Kaplan et al., Chinchilla). Он постулировал: прирост качества модели пропорционален объему обучающих данных, числу параметров нейросети и объему FLOPs, затраченных на этапе обучения. Однако к 2024–2026 годам инженерия столкнулась с физическими и экономическими барьерами: исчерпанием качественного публичного веб-корпуса (Data Wall), гиперболическим ростом стоимости дата-центров и квадратичным ростом аппаратных сбоев при распределенном обучении кластеров на сотни тысяч ускорителей.
Фундаментальным прорывом стал сдвиг парадигмы в сторону масштабирования вычислений на этапе вывода — Test-Time Scaling Law (или Inference-Time Scaling).
E[Loss] = f(Compute_pretrain, Compute_posttrain, Compute_inference)При фиксированном размере базовых весов модели качество решения нетривиальных инженерных задач (верификация распределенных протоколов, синтез трансляторов, математические доказательства) экспоненциально растет при увеличении вычислительного бюджета, выделяемого модели прямо во время генерации ответа.
Традиционный инференс (Pre-training heavy):
Prompt (N tokens) ───────────────────────────────► Completion (M tokens)
[ Задержка минимальна, глубина рассуждений ограничена 1 проходом по весам ]
Test-Time Compute инференс:
Prompt (N tokens) ──► [ Hidden Chain-of-Thought ] ──► Verified Completion
├─ Генерация гипотез
├─ Пошаговая верификация (PRM)
├─ Самокоррекция ветвлений
└─ 1,000 - 32,000 thinking tokensВместо попытки сгенерировать правильный ответ с первого токена (Greedy Single-pass Decoding), модели с архитектурой скрытых цепочек рассуждений (Hidden Chain-of-Thought, CoT) разворачивают пространство состояний в латентном или текстовом пространстве reasoning-токенов. Такие системы, как OpenAI o-серии (o1, o3-mini), DeepSeek R1 и Claude 3.7 Sonnet (Hybrid Reasoning), разделяют жизненный цикл генерации на две фазы: фазу поиска и верификации решения (Thinking Phase) и фазу формирования контракта ответа (Answer Phase).
В моделях прямого вывода каждый токен генерируется авторегрессионно на основе локального распределения вероятностей P(w_t | w_<t). Если модель допустила ошибку в выборе архитектурного паттерна на 3-м токене, вся последующая траектория декодирования деградирует (Error Cascading).
В архитектуре Test-Time Compute процесс вывода превращается в целенаправленный поиск в пространстве решений.
+-----------------------------------------------------------------------------------+
| TEST-TIME COMPUTE LIFECYCLE |
+-----------------------------------------------------------------------------------+
| |
| [ User Architectural Prompt ] |
| | |
| v |
| +-----------------------------------------------------------------------------+ |
| | PHASE 1: GENERATION & HYPOTHESIS SAMPLING | |
| | Модель формирует дерево подзадач, выдвигает гипотезы реализации, | |
| | выявляет скрытые граничные условия и инварианты. | |
| +-----------------------------------------------------------------------------+ |
| | |
| v |
| +-----------------------------------------------------------------------------+ |
| | PHASE 2: INTERNAL VERIFICATION & PROCESS REWARD EVALUATION | |
| | Проверка шагов: | |
| | Step 1: Проверка согласованности транзакций -> [Valid] | |
| | Step 2: Использование Distributed Lock на уровне приложения -> [Invalid] | |
| | ^-- ОБНАРУЖЕНО ПРОТИВОРЕЧИЕ: возможен Split-Brain! | |
| +-----------------------------------------------------------------------------+ |
| | |
| v |
| +-----------------------------------------------------------------------------+ |
| | PHASE 3: SELF-CORRECTION & PRUNING | |
| | Откат ветки рассуждений. Замена примитива синхронизации на Raft/Paxos. | |
| | Пересчет инвариантов согласованности данных. | |
| +-----------------------------------------------------------------------------+ |
| | |
| v |
| +-----------------------------------------------------------------------------+ |
| | PHASE 4: FINAL CONVERGENCE & STREAMING | |
| | Формирование очищенного артефакта (TypeScript код, DDL, архитектурный JSON) | |
| +-----------------------------------------------------------------------------+ |
| |
+-----------------------------------------------------------------------------------+При взаимодействии с reasoning-моделями API предоставляет специализированные протоколы. В Claude 3.7 Sonnet используется блок thinking, позволяющий задавать бюджет токенов на рассуждения и получать трассировку рассуждений в отдельном блоке стрима. В открытых моделях (DeepSeek R1, QwQ) рассуждения транслируются внутри тегов <think>...</think> либо через специализированные поля reasoning_content в SSE (Server-Sent Events).
Разберем реализацию шлюза на TypeScript, который унифицирует работу с Hybrid Reasoning API (Claude 3.7) и моделями с открытым reasoning-протоколом (DeepSeek R1), валидирует ответ через Zod и отделяет процесс мышления от финального полезного вывода.
import { z } from "zod";
/**
* Схема структурированного архитектурного решения
*/
export const ArchitecturalPlanSchema = z.object({
systemName: z.string(),
concurrencyModel: z.enum(["event-loop", "worker-threads", "actor-model", "csp"]),
invariants: z.array(z.string()),
tradeoffs: z.array(
z.object({
attribute: z.string(),
compromise: z.string(),
mitigation: z.string(),
})
),
implementationSnippet: z.string(),
});
export type ArchitecturalPlan = z.infer<typeof ArchitecturalPlanSchema>;
export interface ReasoningExecutionMetrics {
thinkingDurationMs: number;
thinkingTokens: number;
outputTokens: number;
totalDurationMs: number;
}
export interface UnifiedReasoningResponse {
plan: ArchitecturalPlan;
thinkingTrace: string;
metrics: ReasoningExecutionMetrics;
}
export interface HybridReasoningRequest {
systemPrompt: string;
userPrompt: string;
thinkingBudget: number; // 0 = standard mode, >0 = hybrid reasoning
model: "claude-3-7-sonnet-20250219" | "deepseek-r1";
}
/**
* Унифицированный шлюз выполнения Test-Time Compute задач
*/
export class TestTimeComputeGateway {
private readonly anthropicApiKey: string;
private readonly deepseekApiKey: string;
constructor(config: { anthropicApiKey?: string; deepseekApiKey?: string }) {
this.anthropicApiKey = config.anthropicApiKey || process.env.ANTHROPIC_API_KEY || "";
this.deepseekApiKey = config.deepseekApiKey || process.env.DEEPSEEK_API_KEY || "";
}
public async executeTask(request: HybridReasoningRequest): Promise<UnifiedReasoningResponse> {
const startTime = performance.now();
if (request.model === "claude-3-7-sonnet-20250219") {
return this.executeClaudeHybrid(request, startTime);
} else {
return this.executeDeepSeekR1(request, startTime);
}
}
/**
* Исполнение запроса с использованием Claude 3.7 Hybrid Reasoning
*/
private async executeClaudeHybrid(
request: HybridReasoningRequest,
startTime: number
): Promise<UnifiedReasoningResponse> {
const isThinkingEnabled = request.thinkingBudget > 0;
// При включенном thinking max_tokens должен строго превышать thinking budget
const maxTokens = isThinkingEnabled ? request.thinkingBudget + 4096 : 4096;
const payload: Record<string, unknown> = {
model: request.model,
max_tokens: maxTokens,
messages: [{ role: "user", content: request.userPrompt }],
system: request.systemPrompt,
};
if (isThinkingEnabled) {
payload.thinking = {
type: "enabled",
budget_tokens: request.thinkingBudget,
};
}
const response = await fetch("https://api.anthropic.com/v1/messages", {
method: "POST",
headers: {
"x-api-key": this.anthropicApiKey,
"anthropic-version": "2023-06-01",
"content-type": "application/json",
},
body: JSON.stringify(payload),
});
if (!response.ok) {
const errorText = await response.text();
throw new Error(`Claude API Execution Error [${response.status}]: ${errorText}`);
}
const data = await response.json();
const totalDurationMs = performance.now() - startTime;
let thinkingTrace = "";
let finalAnswerText = "";
// Парсинг блоков ответа Claude 3.7
for (const block of data.content) {
if (block.type === "thinking") {
thinkingTrace += block.thinking;
} else if (block.type === "text") {
finalAnswerText += block.text;
}
}
const cleanedJson = this.extractJsonBlock(finalAnswerText);
const parsedPlan = ArchitecturalPlanSchema.parse(JSON.parse(cleanedJson));
return {
plan: parsedPlan,
thinkingTrace,
metrics: {
thinkingDurationMs: totalDurationMs * 0.7, // Оценочная доля времени рассуждений
thinkingTokens: data.usage?.thinking_tokens ?? 0,
outputTokens: data.usage?.output_tokens ?? 0,
totalDurationMs,
},
};
}
/**
* Исполнение запроса через DeepSeek R1 с извлечением reasoning_content
*/
private async executeDeepSeekR1(
request: HybridReasoningRequest,
startTime: number
): Promise<UnifiedReasoningResponse> {
const response = await fetch("https://api.deepseek.com/v1/chat/completions", {
method: "POST",
headers: {
"Authorization": `Bearer ${this.deepseekApiKey}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "deepseek-reasoner",
messages: [
{ role: "system", content: request.systemPrompt },
{ role: "user", content: request.userPrompt },
],
// DeepSeek-R1 автоматически использует reasoning токены без отдельного поля budget
}),
});
if (!response.ok) {
const errorText = await response.text();
throw new Error(`DeepSeek API Error [${response.status}]: ${errorText}`);
}
const data = await response.json();
const choice = data.choices?.[0];
const totalDurationMs = performance.now() - startTime;
// В DeepSeek-R1 reasoning транслируется в reasoning_content
const thinkingTrace = choice?.message?.reasoning_content || "";
const finalAnswerText = choice?.message?.content || "";
const cleanedJson = this.extractJsonBlock(finalAnswerText);
const parsedPlan = ArchitecturalPlanSchema.parse(JSON.parse(cleanedJson));
return {
plan: parsedPlan,
thinkingTrace,
metrics: {
thinkingDurationMs: totalDurationMs * 0.75,
thinkingTokens: data.usage?.reasoning_tokens ?? 0,
outputTokens: data.usage?.completion_tokens ?? 0,
totalDurationMs,
},
};
}
private extractJsonBlock(text: string): string {
const jsonMatch = text.match(/```(?:json)?\s*([\s\S]*?)\s*```/);
if (jsonMatch) {
return jsonMatch[1].trim();
}
return text.trim();
}
}Добавление инструкций вроде "Think step by step", "Let's think carefully" в системный промпт для моделей класса o3-mini или Claude 3.7 с включенным thinking. Модели обучены через RL распознавать сложные контексты автономно. Ручные CoT-промпты приводят к двойной мета-рефлексии (Overthinking Loop), раздувая расход токенов без улучшения качества и ломая внутренние эвристики планирования.
Парсинг вывода без строгой изоляции блока thinking или reasoning_content. Если клиентский код ожидает чистый JSON, а модель начинает вывод с рассуждений в открытом тексте, парсер падает с синтаксической ошибкой. Необходимо обрабатывать reasoning на уровне SDK как отдельный поток метаданных.
В API Claude 3.7 Sonnet параметр budget_tokens определяет верхнюю границу токенов для рассуждений. Если задать max_tokens: 4000 и budget_tokens: 4000, модель исчерпает лимит на этапе внутренних мыслей, и на полезный ответ (final completion) не останется квоты. Запрос завершится с stop_reason: "max_tokens", оставив ответ обрезанным на полуслове. max_tokens обязан быть равен сумме бюджета рассуждений и ожидаемой длины ответа.
Установка высокой температуры (например, 0.7–1.0) при включенном reasoning. Внутренний механизм верификации опирается на детерминированные логические инварианты. Повышенная стохастичность разрушает валидацию шагов, приводит к галлюцинациям в промежуточных выкладках и сбивает модель с пути поиска оптимального решения. Для reasoning-инференса температура фиксируется на 0 (или не передается, если API блокирует ее переопределение).
Прием системного контракта, спецификации инвариантов и пользовательской задачи
Генерация пространства подзадач и вариантов реализации в латентном CoT
Пошаговая проверка граничных условий, гонок и консистентности через PRM
Откат от тупиковых ветвей рассуждений и устранение логических противоречий
Форматирование финального верифицированного ответа строго по схеме Zod