`Create` Hook 在用户发送消息之后、LLM 接收消息之前运行。用它来预处理输入、配置 LLM 请求,或直接将请求路由给另一个 Agent。
## 最简实现
```typescript
// assistants/my-assistant/src/index.ts
import { agent } from "@yao/runtime";
export function Create(
ctx: agent.Context,
messages: agent.Message[]
): agent.Create {
return { messages }; // 原样透传
}
```
返回 `null` 或 `{ messages }` 均为默认行为。
## 返回值
可以返回的完整选项:
```typescript
return {
messages, // 发送给 LLM 的消息(可修改)
connector: "gpt-4o-mini", // 覆盖本次请求的 connector
prompt_preset: "task", // 从 prompts/ 中选择提示词预设
disable_global_prompts: true, // 本次请求跳过全局 system prompt
temperature: 0.7, // 覆盖 temperature
max_tokens: 2000, // 覆盖 max tokens(大多数模型)
max_completion_tokens: 2000, // 覆盖 max completion tokens(o 系列 / 较新模型)
mcp_servers: [ // 添加/覆盖本次请求的 MCP Server
{ server_id: "agents.my-assistant.tools", tools: ["search"] }
],
uses: { // 覆盖 wrapper 工具(视觉 / 搜索等)
vision: "yao.vision-agent",
search: "disabled",
},
force_uses: true, // 即使模型有原生能力也强制使用 Uses 工具
search: false, // 禁用本次请求的自动搜索(bool | SearchIntent)
locale: "zh-cn", // 覆盖本次请求的语言
metadata: { key: "value" }, // 合并到 ctx.metadata(可在 ctx.metadata 中访问)
};
```
## 常见模式
### 向消息中注入上下文
在 LLM 看到消息之前,向用户消息附加额外信息:
```typescript
export function Create(
ctx: agent.Context,
messages: agent.Message[]
): agent.Create {
const username = ctx.authorized?.user_id || "anonymous";
const time = new Date().toISOString();
// 以 system 消息的形式注入上下文
const enriched = [
{
role: "system",
content: `当前用户:${username}。时间:${time}。`,
},
...messages,
];
return { messages: enriched };
}
```
### 根据意图切换 Connector 或提示词
```typescript
export function Create(
ctx: agent.Context,
messages: agent.Message[]
): agent.Create {
const input = messages[messages.length - 1]?.content || "";
// 复杂分析任务路由到更强的模型
if (input.length > 500 || input.includes("analyze")) {
return {
messages,
connector: "gpt-4o",
prompt_preset: "analysis",
};
}
return { messages }; // 默认:快速模型 + 默认提示词
}
```
### 为 Next Hook 存储状态
用 `ctx.memory.context` 在同一次请求中从 Create 向 Next 传递数据:
```typescript
export function Create(
ctx: agent.Context,
messages: agent.Message[]
): agent.Create {
ctx.memory.context.Set("start_time", Date.now());
ctx.memory.context.Set("chat_id", ctx.chat_id);
return { messages };
}
```
## 委托(Delegation)
完全跳过 LLM,将请求交给另一个 Agent 处理。被委托的 Agent 沿用相同的对话历史。
```typescript
export function Create(
ctx: agent.Context,
messages: agent.Message[]
): agent.Create {
const input = messages[messages.length - 1]?.content || "";
// 路由到专项 Agent
if (input.toLowerCase().includes("code")) {
return {
delegate: {
agent_id: "yao.code-agent", // 必填
messages, // 必填
options: {}, // 可选 —— 覆盖 connector、locale 等
},
};
}
return { messages };
}
```
**`delegate` 共享对话历史。** 被委托的 Agent 能看到所有历史消息,相当于"接力棒"传递 —— 适合路由场景。
对于独立子任务(将 Agent 作为函数调用),使用 `ctx.agent.Call()` —— 见[多 Agent 协作](./multi-agent)。
## 真实示例:Mark 的 Create Hook
来自 `yaobots/assistants/yao/mark/src/index.ts` —— 检测编辑/创建模式并切换提示词预设:
```typescript
export function Create(
ctx: agent.Context,
messages: agent.Message[]
): agent.Create {
// 为 Next Hook 存储上下文
ctx.memory.context.Set("chat_id", ctx.chat_id);
ctx.memory.context.Set("start_time", Date.now());
const lastMsg = messages[messages.length - 1];
if (lastMsg?.content) {
ctx.memory.context.Set("user_input", lastMsg.content);
}
// 从 URL 检测编辑模式
const existing = detectAndLoadExisting(ctx);
if (existing) {
ctx.memory.context.Set("mode", "edit");
ctx.memory.context.Set("canvas_id", existing.canvas_id);
return { messages, prompt_preset: "edit" };
}
ctx.memory.context.Set("mode", "create");
return { messages };
}
```
## 下一步
你已经控制了 LLM 的输入。接下来处理它的输出。
→ **[Next Hook](./hook-next)**