Chapter 4 · Model Configuration and Instruction Design
Chapter goals: Master the declarative usage of
useModel()and model identifier format, learn to tune with thinkingLevel and compaction, and understand the "upgrade"模式 of dynamic model switching.
4.1 useModel(): Declarative, Not Client-Side
useModel() is Flue's only required Hook, but it returns nothing and creates no SDK client — you only "name" the model; connection, auth, streaming, and retry are all handled by the Flue runtime:
'use agent';
import { useModel } from '@flue/runtime';
export function TriageAgent() {
// You don't need new Anthropic(), no API key passing, no retry handling
useModel('anthropic/claude-sonnet-4-6');
return 'Investigate the reported issue and recommend the next action.';
}Two hard rules:
- Must be called: an agent without
useModel()cannot start rendering; - Called exactly once per render: parameters can change, but the call itself must not disappear or duplicate.
Exception: sub-agents
Sub-agents cannot call useModel() in their render — their model is specified on the useSubagent() definition; if unspecified, they inherit the parent agent's model.
4.2 Model Identifier Format
The model identifier is a plain string in 'provider-id/model-id' format. Everything before the first / is the Provider ID; everything after is the provider's own model ID (which may itself contain slashes):
// Standard provider/model form
useModel('anthropic/claude-sonnet-4-6');
useModel('openai/gpt-5.5');
// When the model ID itself contains slashes — the first / is the delimiter
useModel('openrouter/moonshotai/kimi-k2.6'); // openrouter's moonshotai/kimi-k2.6
useModel('cloudflare/@cf/moonshotai/kimi-k2.6'); // Cloudflare Workers AI, no API key neededBuilt-in Providers come from Pi's full directory: anthropic, openai, google, amazon-bedrock, google-vertex, groq, mistral, xai, deepseek, cerebras, together, fireworks, openrouter, etc. The directory metadata includes context window size, output cap, rate, reasoning support, and input modalities — these determine compaction trigger timing and whether thinkingLevel takes effect.
Unknown models fail fast: the request errors before being sent, identifying the unresolved provider and model ID.
4.3 thinkingLevel and compaction Tuning
The second optional parameter provides two fields:
'use agent';
import { useModel } from '@flue/runtime';
export function DeepResearcher() {
useModel('anthropic/claude-opus-4-6', {
// Reasoning depth: off | minimal | low | medium (default) | high | xhigh | max
thinkingLevel: 'high',
// Auto-compaction config
compaction: {
reserveTokens: 30000, // Threshold margin (default model-aware, ≤20000)
keepRecentTokens: 16000, // Recent history preserved verbatim (default 8000)
model: 'anthropic/claude-haiku-4-5', // Cheaper model for summarization
},
});
return 'Conduct deep research on the given topic and produce a structured report.';
}Key points:
thinkingLevelis a default — individual operations can override (sub-agent definitions,harness.prompt()calls);- Thinking content is only sent live for reasoning-capable models;
compaction: falsedisables threshold auto-compaction (overflow recovery still has fallback).
When a conversation approaches the model's context limit, Flue automatically folds old history into a summary while keeping recent messages verbatim — the session continues seamlessly.
4.4 Dynamic Model Switching: The Cost Upgrade Pattern
Because rendering happens every round, the model identifier can be computed from state. The classic pattern is "upgrade": cheap model for daily work, strong model for complex tasks:
'use agent';
import { useModel, usePersistentState } from '@flue/runtime';
export function Reviewer() {
// escalated is a cross-round persistent flag
const [escalated, setEscalated] = usePersistentState('escalated', false);
// State determines which model this round uses — re-evaluated on each render
useModel(escalated
? 'anthropic/claude-opus-4-6'
: 'anthropic/claude-haiku-4-5');
return `
Review the code changes submitted by the user.
If you find a complex defect requiring deep推理,
first use the escalate tool to set escalated to true, then continue analysis.`;
}Paired with tools (Chapter 6) that let the model self-decide when to upgrade, you achieve a "cheap model does grunt work + strong model tackles hard problems" cost-optimized组合.
4.5 Writing High-Quality Instructions
The quality of the returned string directly determines the agent's ceiling. Four principles:
'use agent';
import { useModel } from '@flue/runtime';
export function CodeReviewer() {
useModel('anthropic/claude-sonnet-4-6');
return `
You are a senior code reviewer. Follow this流程 when reviewing PRs:
1. Read the change description first to understand intent;
2. Use grep to locate affected core logic, read surrounding context;
3. Classify issues by severity: blocker / suggestion / nit;
4. Output format: one paragraph per issue, with file and line number, plus fix suggestion.`;
}Four principles: 定角色 (who you are), 划流程 (step-by-step reasoning path), 给格式 (output structure), 设红线 (what not to do).
4.6 Chapter Summary
useModel()is declarative — Flue handles connections, auth, streaming, retries;- Model identifiers:
'provider-id/model-id'format; first/is the delimiter; thinkingLevelcontrols reasoning depth;compactioncontrols auto-summarization behavior;- Dynamic model switching: compute the model string from state on each render;
- High-quality instructions: define role, flow, format, and red lines.
🧪 随堂测验
点击你认为正确的选项。答错时会展示正确答案与原因解析。
1. What does useModel() do inside a Flue agent?
2. What is the correct model identifier format in Flue?
3. What happens when compaction kicks in during a long conversation?
4. Why can the model identifier be computed dynamically from state?
🛠️ Hands-On Exercises
- Write an agent that uses
thinkingLevel: 'high'for a reasoning task and compares output quality vsthinkingLevel: 'off'on the same prompt. - Implement the "upgrade" pattern from Section 4.4: start with haiku, escalate to opus when a complex defect is detected; verify the model switch actually occurs.
- Set
compaction: falseand observe what happens when the conversation exceeds the context window — does the overflow fallback still work?
Models configured. Next, learn session and context management.