Loading

AI-Agents-in-Depth 一些核心概念记录

AI-Agents-in-Depth 一些核心概念记录

Agent概念

$$
\text{Agent} = \text{LLM} + \text{Context} + \text{Tools}
$$

LLM 是Agent的大脑,Context 是Agent所看到的一切,而Tools则是Agent的手。

ReAct循环

Agent执行任务的模式叫做ReAct(Reasoning + Acting)。

它的最小实现是一次tool的调用,过程大概是这样的:
Reasoning 思考该怎么做 -> Acting 调用工具 -> 查看工具调用结果 -> Reasoning 进一步思考该怎么做 -> Acting ......

直到完成任务。

每次的api调用都是无状态的

LLM每次看到的不只是新增部分,而是全部上下文(包括system prompt + tool description +之前的所有“聊天记录”)。

我们把整个不断新增的“聊天记录”叫做Trajectory 。它是以一个名为messages的列表的形式存在。
$$
\text{整个上下文} = (\text{System Prompt} + \text{Tool Description}) + \text{Trajectory}
$$

思考题

如果模型每次的回答中,思考链都像第一次拿到全文一样,该怎么处理?

答:优化 System Prompt:增加规则,要求模型“在获取工具执行结果后,只针对结果进行分析和下一步决策,禁止重复复述原始任务”。

KV Cache & Prompt Cache

两个不同层级的Cache,KV Cache 是指单次调用时前面的缓存,而Prompt Cache 则是跨请求间的缓存。

Context Engineering的几个Q&A

问题 1:认知基石(上下文的本质与循环机制)

  • 核心问题
    1. 为什么说“上下文质量决定了 Agent 能力的真正上限”?
    2. 大模型单次调用在本质上是无状态的,Agent 框架是如何维持多轮 ReAct 循环与任务连贯性的?
  • 你的回答
    1. 第一问不知道。
    2. Agent 框架通过每次都将“静态前缀 + 动态 Trajectory”重新发送,从而达到了多轮次的 ReAct 循环;只要没有工具调用之后,就返回最终回答。
  • 知识点复盘与补充
    • 天才新员工隐喻:大模型拥有强大的通用智力,但不知道具体的代码规范、业务逻辑和环境配置。决定交付质量的不是参数量,而是它在每个决策点能获得的精准信息(有效工作三要素:代码、流程、环境)。
    • 循环机理补充:你的回答非常准确。通过在 messages 列表中持续追加 userassistant(含工具调用)、tool(执行结果)轨迹,将状态外置在上下文中实现多轮连贯决策。

问题 2:底层机制(KV Cache 友好的上下文设计)

  • 核心问题
    1. 大模型的 KV Cache 前缀复用对上下文排布有哪些硬性约束?
    2. 为什么在系统提示词(System Prompt)中动态注入频繁变化的变量(如实时时间戳)是严重的反模式?
  • 你的回答: 动态内容不能向前插入,这会导致缓存失效,浪费资源重新计算;而是应该往后插入。
  • 知识点复盘与补充
    • 前缀不变性铁律:回答完全正确。Transformer 具有逐层传导机制,前缀变动 1 个字节,其后所有层和 token 的已计算缓存将全部失效推倒重算。
    • 代价与规范:在 System Prompt 注入动态变量会导致失去 Prompt Cache 的 90% 折扣优惠,并拉大首字延迟(TTFT)。工程上必须严格遵守“静态前缀绝对冻结,动态变量末尾追加”。

问题 3:动态加载(Skills 技能的注入策略)

  • 核心问题
    1. 将大量 Skills 完整内容直接写入 System Prompt 会有什么代价?
    2. 现代生产系统通常采用怎样的设计来兼顾指令遵循与缓存利用率?
  • 你的回答: 全量注入会导致新增 Skill 时 KV Cache 失效,成本增大;现代系统通常采用动态注入 Skill 列表,然后根据需求渐进式披露 Skill 内容。
  • 知识点复盘与补充
    • 生产级解法(元数据与路由分离):回答完全正确。在静态前缀中仅放置轻量的技能目录/元数据(约几百 token);当模型判断需要调用某个技能时,再通过专用工具将具体的 SKILL.md 动态读取并追加到轨迹末尾,既保证了前缀缓存命中,又避免了注意力被无关技能稀释。

问题 4:状态追踪(Agent 状态栏与任务对齐)

  • 核心问题: 既然大模型理论上能看到完整历史轨迹,为什么长任务中仍需在末尾设计 Agent 状态栏(Agent Status Bar / TODO 列表)?它解决了什么认知缺陷?
  • 你的回答: 当前主流大模型对“数数”这种统计能力仍有缺陷,需要统计时会重新看一遍;如果用状态栏机制把每次的重要状态以 KV 的形式实时显示,能极大增加准确性,减少大参数模型的资源消耗。
  • 知识点复盘与补充
    • 检索而非推理:注意力机制擅长在上下文做相似检索,但不擅长在单次前向传播中做全局的隐式计数与归纳。
    • 显式知识注入:将“重试次数”、“任务完成度”等关键状态由外部代码计算好,作为元信息(通常借用 user 角色)直接注入末尾,让模型“瞥一眼”就能获取确切状态,避免陷入盲目重扫或死循环。

问题 5:退化与衰减(上下文腐化与压缩)

  • 核心问题: 什么是上下文腐化(Context Rot)?结合位置偏好(Lost in the Middle),在上下文过长时应采用哪些压缩与排布策略?
  • 你的回答: 上下文腐化是指经过多轮对话上下文逐渐过长,导致模型对中间内容的注意力下降;(上下文压缩部分还没看)。
  • 知识点复盘与补充
    • 概念补充:回答准确。由于注意力机制存在“首尾偏好(Lost in the Middle)”,多轮对话中间塞入大量低质数据后,模型会发生注意力漂移和状态丢失。
    • 分层压缩策略
      1. 低价值噪声直接删除(不浪费 token 做摘要);
      2. 大体积输出存盘,上下文仅保留摘要预览;
      3. 自适应批量替换(未超阈值保留原文,超阈值后批量替换历史 Tool Results,减少缓存失效频次);
      4. 子 Agent 隔离(将高噪声的检索/读取任务交由独立子 Agent 处理,主上下文仅接收精炼结论)。

上下文压缩

上下文压缩的目的:防止上下文超出最大窗口限制,降低成本,防止上下文腐化。
上下文压缩的对象:tool_result,冗长的工具原始 stdout/stderr 输出等。不能压缩的对象:前缀部分,标准的字面量(1000kg这些)。

压缩与 KV Cache 的权衡机制

用摘要替换原始 tool_results 时,替换位置之前的缓存依然有效(前缀持续命中),仅替换位置之后的缓存需要局部重算。

生产级分层压缩机制(参考 Claude Code 五层体系)

  1. 第 1 层(预算控制):大体积输出存入本地磁盘,上下文中仅保留摘要预览;替换后的字符串首次确定后即冻结(保障跨会话缓存一致性)。
  2. 第 2 层(噪声直接删除):低价值/未引用的内容直接移除,不做摘要。
  3. 第 3 层(API 层微压缩):利用 API 层的上下文编辑能力批量剔除指定工具结果,在即将溢出、反正要付出缓存重建代价时触发。
  4. 第 4 层(归档式摘要):像 git log 那样逐轮保留结构化独立记录,而不是粗暴地像 git squash 合并为一条,保留逻辑脉络。
  5. 第 5 层(LLM 全量压缩 + 熔断器):由独立模型执行全局重写归档;配备连续失败熔断器,防止在无法恢复的会话中死循环烧钱。

架构演进:隔离优于压缩(子 Agent 上下文隔离)

  • 事后补救 vs 源头隔离
    • 压缩:信息进入主上下文造成污染后,再花额外 LLM 算力做有损裁剪,且会破坏局部的 KV Cache。
    • 子 Agent(Sub-Agent):将海量搜索、代码翻找等高噪声任务委派给独立的子 Agent,中间过程随子 Agent 销毁而整段丢弃
  • 架构收益:主 Agent 上下文仅增加“派发任务 + 最终结论”两条消息,主上下文近乎零膨胀,且主 Agent 的静态前缀与历史 KV Cache 获得 100% 完美保护
posted @ 2026-08-25 17:42  幽暗天琴沙雕  阅读(1)  评论(0)    收藏  举报