logo
02

与 Prompt Engineering 的边界 — 5 层 Context 各自怎么调

⏱️ 20 分钟

与 Prompt Engineering 的边界 — 5 层 Context 各自怎么调

第 1 章给了 5 层 context 清单,这章把每层拆开:装什么、占多少 token、怎么独立调试、出问题怎么定位。

所有 context 工程化技术(rerank / memory / sub-agent)都是在某层做手术。

实际的 5 层长什么样

看一个真实 Anthropic API 调用的 context shape。下面是 JR omni-report daily-jobs routine 抓完 LinkedIn 后发给 Claude 的完整 message——

# tested: 2026-04-26 · anthropic@0.40.0 · model: claude-sonnet-4-6
client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=4096,

    # === Layer 1: System instruction ===
    system=[
        {
            "type": "text",
            "text": "你是 JR Academy 的 daily-jobs picker...",  # ~800 token
            "cache_control": {"type": "ephemeral"}  # 5min TTL prompt cache
        }
    ],

    # === Layer 2: Tool definitions ===
    tools=[
        {"name": "WebFetch", "description": "...", "input_schema": {...}},  # ~200 token
        {"name": "Write",    "description": "...", "input_schema": {...}},  # ~150 token
        # 共 6 个 tool ≈ 1100 token
    ],

    messages=[
        # === Layer 3: Memory / 历史对话 ===
        {"role": "user",      "content": "前 7 天已挑过的 job ID 列表..."},  # ~300 token
        {"role": "assistant", "content": "记下了"},

        # === Layer 4: Retrieved context ===
        {"role": "user", "content": [
            {"type": "text", "text": "LinkedIn 抓回的 30 个 job 全文:"},
            {"type": "text", "text": "<job1>...</job1><job2>...</job2>"}  # ~12000 token
        ]},

        # === Layer 5: User input(这次 task 的实际指令)===
        {"role": "user", "content": "从上面 30 个 job 里挑 3 个:"
                                    "1 aspirational / 1 actionable / 1 special。"
                                    "输出 JSON 严格匹配 ${OUT} 文件 schema。"}  # ~80 token
    ]
)

整段 context 约 14500 token。Prompt engineering 关心最后 user input(80 token,0.5%)。剩下 99.5% 是 context engineering 领地

5 层逐个拆

Layer 1: System instruction — 角色 + 不变规则

放什么:模型扮演的角色、永不变的硬规则(输出格式、禁止事项、token 上限)、可缓存的长说明(reference docs、style guide)。

调:必须 stable——一改 cache 全部失效。Anthropic prompt cache 5 分钟 TTL,复用要求 system 不变(官方文档)。加 cache_control: ephemeral 后续 system 计费降到 10%。

调试:system 单独 + 最小 user input,看角色是否到位。改 system 输出还一样,说明放错位置(应该 system 但写到 user)。

Layer 2: Tool definitions — 工具菜单

放什么:每个 function calling / MCP 工具的 name + description + input_schema,包含「什么时候用」(写在 description 里)。

调:每个 tool schema 100-300 token。15 个 tool ≈ 3000 token,全挤 context。Claude Code 接 MCP 可挂 17 server × N tool,所以默认很多 tool deferred(ToolSearch 按需加载)。

调试:tool list 减到 1,看模型是否还乱调用。会——description 不够清楚,模型在「猜」(context 污染)。

Layer 3: Memory / 历史对话 — 之前发生过什么

放什么:多轮对话前 N 轮(通常摘要)、Agent task scratchpad、长期 memory(用户偏好等)。

调:最容易爆 context budget。100 轮 × 1500 token = 150K,吃掉 200K 的 75%。需 memory 三层架构(第 6 章):scratchpad / working / persistent,独立压缩策略。

调试:history 截到只剩最近 1 轮,模型还能完成 task 吗?能——冗余;不能——需要更好摘要而不是删掉。

Layer 4: Retrieved context — 临时塞进来的事实

放什么:RAG 段落、WebFetch 内容、之前 tool call 输出。

调:token 量最大、最不稳定。20 段 × 500 字 = 10K token。Lost in the Middle(Liu et al. 2023, arXiv:2307.03172):中间文档模型基本看不见(第 3 章详述)。

调试:看模型回答引用 vs 召回。召回 10、引用 0——selection 失败,加 rerank(第 5 章)。

Layer 5: User input — 这一轮真正的指令

放什么:用户输入 + task 目标 + 输出要求。

调:prompt engineering 传统领地。区别:每次都变,不能 cache。

调试:固定前 4 层只改 user input 措辞看输出变化——A/B 测试标准做法。

Anthropic 5 个 Agent 模式 = 5 种 context 工程

Building Effective Agents(Anthropic, 2024-12-20)把 agentic system 拆成 5 种 pattern:

Anthropic 模式Context engineering 决策
Prompt chaining大 task 拆多 call,每 call 只看自己需要的
Routing便宜模型分类 → 选模板 → 给贵模型
Parallelization多 LLM 同时跑、汇聚
Orchestrator-workers主 agent 拆 task,sub-agent 各自干
Evaluator-optimizer一个生成、一个评估、循环

5 个模式的工程决策都不是 prompt 措辞,都是 context 怎么切、传、收。

JR 真实案例:classroom-deck-builder skill

JR 的 classroom-deck-builder skill 把 Quest lesson 编译成「直播课」(slide + 配音 + 讲解动作)。

最初一个 LLM call 生成 N 张 slide + 配音。结果叙事断裂、口吻不一致。改成两阶段:

Stage 1: outline 阶段
  Context = lesson goal + style guide
  → 输出 N 个 SceneOutline(仅标题 + 一句话指令)

[人工审 outline,可改可删]

Stage 2: finalize 阶段(SSE 流式)
  Context = lesson goal + style guide + 已批准的 outline 全集
  → 逐个 scene 生成完整 slide + 配音

Stage 2 多塞「已批准 outline 全集」一层,每个 scene 知道自己在整体叙事里的位置。一键模式没这层,所以叙事断。

典型动作:不改 prompt 措辞,改 LLM call 之间 context 怎么传

单层 context vs 分层 context — Trade-off

第一个 LLM 应用大多把 5 层混在一个 prompt 字符串。能跑但调试地狱。分层工程量大,但能独立优化每层。

维度单层混合 prompt分层 context
写起来string format,30 行ContextBuilder 类,100+ 行
调试出错整段重写可单独 mock 任意一层
Token 成本不能用 prompt cache前 2 层可 cache,省 60-90%
多人协作一改影响所有人system / tools 独立 owner
适用单一 task 脚本Production LLM 应用
不适用复杂 agentic 系统一次性 demo

JR 规则:超过 3 个 LLM call 或多人维护,必须分层。

一句话带走

Prompt engineering 关心 1 / 5(user input)。Context engineering 关心 5 / 5——还关心层间怎么传、cache、isolate。Production LLM 应用 80% 工程量在前 4 层。


引用来源

  1. Anthropic. (2024-12-20). Building Effective Agents.
  2. Anthropic. Prompt caching docs — 5 分钟 TTL ephemeral cache.
  3. Anthropic. Cookbook — agent patterns.
  4. Anthropic. Tool use docs.
  5. Liu et al. (2023-07-06). Lost in the Middle. arXiv:2307.03172.

Production case: JR Academy classroom-deck-builder skill.claude/skills/classroom-deck-builder/)— 两阶段 pipeline 实现 context isolation。

📚 相关资源

❓ 常见问题

关于本章主题最常被搜索的问题,点击展开答案

System prompt 和 user prompt 区别是什么?

System 装不变的规则 + 角色,每次调用复用、走 prompt cache 省 90% 成本;user 是这一轮的 task 指令,每次都变。两者混一字符串调试是地狱,production 必须分开。

我的 context 里 system / tools / memory / retrieval / user 各自占多少 token?

典型 production RAG 占用:system 800 + tools 1100 + memory 300 + retrieval 12000 + user 80 = 14280 token。用 Anthropic SDK 的 token counter 分段量。Retrieval 层永远是最大头。

Anthropic 5 个 agent pattern 是什么?

5 个 pattern:Prompt chaining(拆步)、Routing(先分类再选模板)、Parallelization(并行 + 汇聚)、Orchestrator-workers(主 agent + sub-agent)、Evaluator-optimizer(生成 + 评估循环)。每个都是 context 怎么切/怎么传的工程决策,不是 prompt 措辞。

我已经在用 OpenAI Chat Completions API,5 层 context 还适用吗?

适用。5 层是工程抽象,不绑模型:OpenAI 的 system role + tools 参数 + messages history + retrieval 注入 + user message 一一对应。Gemini / DeepSeek / Qwen API 字段名不同但层次完全一致,迁移只是改 SDK 包名。

做客服机器人这种简单业务,5 层都要做吗?

不需要全做:客服机器人最少 3 层够用——system(角色 + 业务规则)+ retrieval(FAQ 知识库 top-3)+ user。Memory 层做不做看是否需要跨 session 记住客户偏好;tools 层只在要操作订单/退款时才加。先 3 层上线再按 ticket 复盘加层。

新手最容易在哪一层翻车?

Retrieval 层。80% 自学项目栽在「召回了相关文档但 LLM 还是答错」——以为是 prompt 不行去调 system 措辞,真问题是 retrieval 没做 selection(filter / rerank / judge)。第 3、5 章专门讲。