第 4 章 · 模型配置与指令设计
本章目标:掌握
useModel()的声明式用法与模型标识格式,学会用 thinkingLevel 与 compaction 调优,理解动态切换模型的"升级"模式。
4.1 useModel():声明而非客户端
useModel() 是 Flue 唯一必需的 Hook,但它不返回任何东西、也不创建 SDK 客户端——你只负责"点名",连接、认证、流式、重试全部由 Flue 运行时接管:
'use agent';
import { useModel } from '@flue/runtime';
export function TriageAgent() {
// 你不需要 new Anthropic(),不需要传 API Key,不需要处理重试
useModel('anthropic/claude-sonnet-4-6');
return 'Investigate the reported issue and recommend the next action.';
}两条硬规则:
- 必须调用:没有
useModel()的 agent 渲染无法启动; - 每轮渲染恰好调用一次:参数可以变,但调用本身不能消失或重复。
例外:子代理
子代理(subagent)的渲染中不能调用 useModel()——它的模型在 useSubagent() 定义上指定;未指定时继承父 agent 的模型。
4.2 模型标识格式
模型标识是 'provider-id/model-id' 格式的普通字符串。第一个 / 之前是 Provider ID,之后全部是 Provider 自己的模型 ID(可以再含斜杠):
// 标准 provider/model 形式
useModel('anthropic/claude-sonnet-4-6');
useModel('openai/gpt-5.5');
// 模型 ID 自身含斜杠的情况——第一个 / 才是分隔符
useModel('openrouter/moonshotai/kimi-k2.6'); // openrouter 的 moonshotai/kimi-k2.6
useModel('cloudflare/@cf/moonshotai/kimi-k2.6'); // Cloudflare Workers AI,无需 API Key内置 Provider 来自 Pi 的完整目录:anthropic、openai、google、amazon-bedrock、google-vertex、groq、mistral、xai、deepseek、cerebras、together、fireworks、openrouter 等。目录元数据包含上下文窗口大小、输出上限、费率、推理支持、输入模态——它们决定了压缩触发时机与思考级别是否生效。
未知模型会快速失败:请求发出前就报错指出未解析的 provider 与 model ID。
4.3 thinkingLevel 与 compaction 调优
第二个可选参数提供两个字段:
'use agent';
import { useModel } from '@flue/runtime';
export function DeepResearcher() {
useModel('anthropic/claude-opus-4-6', {
// 推理深度:off | minimal | low | medium(默认) | high | xhigh | max
thinkingLevel: 'high',
// 上下文自动压缩配置
compaction: {
reserveTokens: 30000, // 触发阈值余量(默认模型感知,≤20000)
keepRecentTokens: 16000, // 最近历史原样保留量(默认 8000)
model: 'anthropic/claude-haiku-4-5', // 用更便宜的模型做摘要
},
});
return '对给定主题进行深入研究,输出结构化报告。';
}要点:
thinkingLevel只是默认值——单个操作可覆盖(子代理定义、harness.prompt()调用);- 思考内容只有对标记为 reasoning-capable 的模型才会真正发到线上;
compaction: false可关闭阈值自动压缩(溢出恢复仍会兜底)。
对话接近模型上下文上限时,Flue 自动把旧历史折叠成摘要、最近消息保持原文,会话无缝继续。
4.4 动态切模型:成本升级模式
因为每轮都重新渲染,模型标识可以按状态计算。经典模式是"升级":日常用便宜模型,复杂任务升级到强模型:
'use agent';
import { useModel, usePersistentState } from '@flue/runtime';
export function Reviewer() {
// escalated 是跨轮持久的标志位
const [escalated, setEscalated] = usePersistentState('escalated', false);
// 状态决定本轮用哪个模型——每次渲染重新评估
useModel(escalated
? 'anthropic/claude-opus-4-6'
: 'anthropic/claude-haiku-4-5');
return `
审查用户提交的代码变更。
若发现需要深度推理的复杂缺陷,
先使用 escalate 工具将 escalated 置为 true 再继续分析。`;
}配合工具(第 6 章)让模型自己决定何时升级,就能实现"便宜模型打杂 + 强模型攻坚"的成本优化组合。
4.5 编写高质量指令
返回的字符串质量直接决定 agent 上限。四条原则:
'use agent';
import { useModel } from '@flue/runtime';
export function CodeReviewer() {
useModel('anthropic/claude-sonnet-4-6');
return `
你是资深代码审查员。审查 PR 时遵循以下流程:
1. 先读变更描述,理解意图;
2. 用 grep 定位受影响的核心逻辑,通读上下文;
3. 按严重程度分类问题:blocker / suggestion / nit;
4. 输出格式:每个问题一段,标注文件与行号,附修复建议。
不要修改任何文件——你只有建议权。`; // ← 明确边界同样重要
}- 角色具体化:"资深代码审查员"优于"AI 助手";
- 流程步骤化:编号步骤让模型有章可循;
- 输出格式化:规定结构,下游才好消费;
- 划清边界:明确告诉它不能做什么。
本章小结
useModel()是唯一必需 Hook:声明式点名,运行时托管连接;- 标识格式
provider/model-id,首个/分隔 Provider 与模型 ID; thinkingLevel七档控制推理深度,compaction三字段调自动压缩;- 每轮重渲染使模型可按状态计算——升级模式省成本;
- 好指令四原则:角色具体、流程步骤化、输出格式化、边界清晰。
🧪 随堂测验
点击你认为正确的选项。答错时会展示正确答案与原因解析。
1. 关于 useModel(),下列说法错误的是?
2. 模型标识 'cloudflare/@cf/moonshotai/kimi-k2.6' 中,Provider ID 是哪部分?
3. thinkingLevel 的默认值是什么?
4. "升级模式"(escalation)指什么?
🛠️ 动手实践
- 把同一个 agent 分别指向 haiku 和 sonnet 各跑一次相同任务,对比回答质量与耗时。
- 写一个根据
usePersistentState在两个模型间切换的 agent,验证切换即时生效。 - 为你的日常某项工作写一个 agent 指令,严格套用 4.5 的四条原则。
模型已就位。下一章解决另一个核心问题:会话如何记住之前聊过什么。