模型只能用在上下文窗口里看到的信息工作——当前对话、记住的细节、应用数据、工具结果、知识库段落。上下文工程就是决定模型该看什么、什么时候看 。目标不是给得越多越好,而是保持上下文相关且新鲜:给太少模型缺料,给太多关键细节更难找、成本上升、而且在撑爆窗口之前回答质量就已经在降了。
Mastra 这篇指南的价值在于把"往上下文里塞信息"拆成了一张选型表。这是浓缩版:
| 需求 | 机制 | 模型实际看到什么 |
|---|---|---|
| 稳定身份、规则、约束 | Instructions | 每次调用的 system 上下文 |
| 数据库 / API 的当前数据 | Tools | 工具定义 + 选定的返回结果 |
| 当前客户 / 应用数据 | Inline context | 插值进用户消息的数据 |
| 大而稳定的知识库 | RAG | 索引里语义相关的 chunk |
| 用户 / 组织管理的文档 | Filesystems | 通过读/搜工具选中的文件 |
| 近期对话或持久事实 | Memory | 历史、观察、检索到的记忆 |
| 长时程对话 | Observational Memory | 稠密观察 + 最近未观察的消息 |
| 运行中的新事件 / 变化状态 | Signals | 用户、响应式、通知、状态消息 |
| 只部分任务需要的指令 | Dynamic skills | skill 元数据 + 按需加载的说明 |
#逐条的取舍要点
Instructions :只放对大多数调用都成立的行为约束。运行时按需解析(当前用户、租户、语言、角色)可以,但要小心——动态部分频繁变化会破坏 prompt 缓存前缀 ,稳定段放前面,易变背景走消息或 signal。
Inline context :应用已查到客户数据时直接插值进当前消息,注意只挑模型需要的字段并加标签,别把整条数据库记录序列化进去。副作用:开 memory 时这条消息会被存进历史——敏感或一次性数据别这么塞;想让背景只影响本次回复且不污染历史,用一次性的 context 消息。
Tools :取当前数据的推荐方式——模型自己决定何时要数据、传什么参数,应用控制查询和返回字段。返回太长时用 toModelOutput 给模型一个瘦身表示,完整结果留给应用层。
RAG :这份文档对 RAG 的态度很冷静——现在很多应用直接从源专属工具 起步,模型选工具的能力变强了,直查往往更简单更便宜,不用维护 chunking + embedding + 向量索引这条管道。RAG 只在"对非结构化内容的语义检索"是真需求时才上,并用元数据过滤、rerank、保守 topK 收紧返回。
Filesystems :当事实来源本身就是一堆文件(个人助理读用户文档、团队知识库放 Google Drive)时用,agent 拿到 list/read/search 内置工具,底层可以跑 BM25、向量或混合检索。和 RAG 的分界:文件需要被列出、读取、更新时选 filesystem;纯检索需求才选独立 RAG 管道。
Memory :resource + thread 两个键决定记忆归谁、属于哪段对话。lastMessages 滑动窗口适合短对话,但有个隐蔽代价——每过一条消息窗口前移,最老的消息被挤出,prompt 缓存前缀随之失效 。长对话直接上 Observational Memory。
Observational Memory :Observer 把老消息和工具交互持续转成稠密观察,定期 reflection 重组压缩。模型拿到的是观察日志 + 最近未观察的消息 + 续接提示。设计重点是观察按稳定 chunk 追加 ,保住 prompt 前缀可复用;还能在缓存将过期或换 provider 前主动激活缓冲观察。
Signals(beta) :给 memory 线程注入系统侧上下文,投递方式看线程状态——sendMessage 唤醒空闲或进入活跃 loop,queueMessage 排到下一轮,sendSignal 加响应式/通知上下文,sendStateSignal 维护一条有快照和增量的状态通道(浏览器状态、编辑器状态这类持续变化的值)。亮点是 transient signal:只进本次调用、不落历史,需要时再发,避免在历史里堆重复提醒。
Dynamic skills :任务专属的说明按需加载,不堆在基础 instructions 里。
#上下文控制:怎么给上下文做减法
任务变长后,另一半边工作是不让模型看到多余的东西。
Compaction ——指南对压缩的态度非常直白:"Friends don't let friends do compaction." 等到 token 阈值再把 transcript 总结成一段,是把之前所有内容压成一个摘要的钝刀:压缩轮本身加延迟,反复压缩会压平时序、丢掉后面才重要的细节。Mastra 干脆不内置 compaction,建议用 Observational Memory 走持续观察的路(要的话可以用自定义 processor 自己实现)。
Processors 是细粒度闸门,在模型调用前改写输入,常用于"留在存储里但不必每轮都发给模型"的内容:
toModelOutput:冗长工具结果换成模型用的瘦身版ToolCallFilter:老工具调用和结果从请求里删掉,但 memory 和 UI 里保留ToolSearchProcessor:大工具目录换成"搜索 + 加载"两步TokenLimiter:按预算剪非 system 消息,当最后兜底而不是依赖模型最大窗口
Subagents 的边界同样要显式控制:默认父对话全量转发给子 agent——用 messageFilter 只给专家需要的那几段;回程默认只回文本,嵌套工具调用留给应用层;除非父模型真要推理子 agent 的中间过程,别开 includeSubAgentToolResultsInModelContext。
#一句话总结
这份指南本质是一张二维选型图:信息归谁所有、以什么形式存在 (系统规则 / 应用数据 / 用户文件 / 语义知识库 / 运行中事件)× 变得多快 (稳定到可缓存 / 每轮都变)。选对格子的回报是双份的——回答更准,账单更小。