Skill + 上下文工程:从 Prompt Engineering 到 Context Engineering 的实践

智能硬件设备多年迭代已存在多种机型,涉及包含语音处理、会议处理等7种以上核心业务场景,每个业务场景都需要下发语言对级别的语音识别、处理、合成能力地址、特定参数配置

早期多语言配置需要对将近20张表进行手工配置和关联,涉及顺序、新增,需要全局分析涉及各种表之间自增的关联。OTA期间,多语言信息变更需要摸排当前灰度版本以及分类配置,确认修改边界及范围,同时不能影响已下发的版本。以某型号智能硬件设备为例,多语言配置新增或变更流程如下图所示:

  1. 优化措施

为了避免每次人工分析以及手搓SQL,我们基于Dify Agent 打造了 打造了基于不同表结合MCP的多语言配置agent,来摆脱部分人力分析与手动配置的成本:

实现方式:

  1. 实现prompt 进行多语言配置分析
  2. 基于dify agent 编排 ,通过调用MCP 进行sql自动生成

已实现功能如下:

  1. 已实现不同场景的MCP tools
  2. 基于大模型进行数据清洗
  3. 意图判断和function call
  4. 国内版、国际版设备新增场景多语言配置

缺点:

  1. 不能从多语言列表接口背后代码逻辑理解的角度,知道每个表的作用以及如何使用每个表
  2. 一些分析策略和手段是基于dify 的分支编排和MCP的理解
  3. 本质上还是利用研发对代码以及表的理解来进行编排与生成
  4. 通过提示词工程来进行静态定义,聚焦于单次交互,缺乏对对话历史和外部信息的系统管理
  5. 从提示词工程到上下文工程

提示词工程(Prompt Engineering)是指通过精心设计输入给模型的文本指令,来引导模型产生期望输出的技术。

提示词工程的典型技巧包括:

  • 角色设定:如“你是一位专业的高级服务端工程师”
  • 任务描述:清晰说明期望模型完成的任务
  • 输出格式:指定 JSON、Markdown 等结构化输出
  • 少样本学习:提供几个示例引导模型行为
  • 思维链提示:要求模型逐步推理

这些技巧在许多场景下效果显著,但随着应用场景的复杂化,提示词工程的局限也逐渐显现:

局限性 具体表现
静态性 提示词通常是预定义的,难以适应动态变化的需求
孤立性 聚焦于单次交互,缺乏对对话历史和外部信息的系统管理
可扩展性差 随着任务复杂度增加,提示词变得冗长且难以维护
缺乏工程化 更多依赖直觉和试错,缺乏系统化的方法论

3.1 上下文工程的演进

上下文工程是提示词工程的自然演进和扩展。如果说提示词工程关注的是“写什么指令”,那么上下文工程关注的是“如何构建完整的信息环境”。

局限性 提示词工程 上下文工程
关注点 单次指令的措辞和格式 完整信息环境的设计
范围 提示词文本 指令、数据、工具、记忆、策略
时间维度 静态、一次性 动态、跨会话
信息来源 手工编写 多源融合、自动检索
工程化进度 技巧驱动、经验依赖 系统化、可量化、可测试
应用场景 简单任务、单论对话 复杂任务、多轮交互、智能体

3.2 为什么需要这种演进

  1. 复杂度的提升

    随着大模型的能力逐渐提升,上下文窗口逐渐增加,我们对大模型的要求从简单的提示词+问答和文本生成,到需求分析、任务拆解、代码编写、数据分析等

  2. 智能体的兴起

    AI 智能体需要在长时间跨度内持续工作,处理多个子任务,协调多个工具,维护工作状态。这种场景下,静态的提示词远远不够,需要系统化的记忆管理和上下文编排。

  3. 质量要求

大模型在和用户进行多轮对话后,随着上下文积累过多,以及LLM的推理特性,会产生幻觉,从而需要对可靠性、一致性等一系列工程化有要求。从而需要对agent 应用场景进行系统方法的架构设计。

As Andrej Karpathy puts it, LLMs are like a new kind of operating system. The LLM is like the CPU and its context window is like the RAM, serving as the model’s working memory. Just like RAM, the LLM context window has limited capacity to handle various sources of context. And just as an operating system curates what fits into a CPU’s RAM, “context engineering” plays a similar role. Karpathy summarizes this well: 正如 Andrej Karpathy 所说,LLMs 就像是一种新的操作系统。LLM 就像是 CPU,而它的上下文窗口就像是 RAM,作为模型的工作内存。就像 RAM 一样,LLM 的上下文窗口也有有限的容量来处理各种上下文来源。而正如操作系统将适合 CPU RAM 的内容进行整理一样,“上下文工程”也扮演着类似的角色。Karpathy 很好地总结了这一点:

[Context engineering is the] ”…delicate art and science of filling the context window with just the right information for the next step.” [上下文__工程是] “……为下一步填充上下文窗口的正确信息的精细艺术和科学。”

  1. 多语言智能体skill的搭建

    1. Agent skill

Agent Skills 是一种标准化的程序性知识封装格式。如果说 MCP 为智能体提供了"手"来操作工具,那么 Skills 就提供了"操作手册"或"SOP(标准作业程序)",教导智能体如何正确使用这些工具。

这种设计理念源于一个简单但深刻的洞察:连接性(Connectivity)与能力(Capability)应该分离。MCP 专注于前者,Skills 专注于后者。这种职责分离带来了清晰的架构优势:

  • MCP 的职责:提供标准化的访问接口,让智能体能够"够得着"外部世界的数据和工具
  • Skills 的职责:提供领域专业知识,告诉智能体在特定场景下"如何组合使用这些工具"

用一个类比来理解:MCP 像是 USB 接口或驱动程序,它定义了设备如何连接;而 Skills 像是软件应用程序,它定义了如何使用这些连接的设备来完成具体任务。你可以拥有一个功能完善的打印机驱动(MCP),但如果没有告诉你如何在 Word 里设置页边距和双面打印(Skill),你仍然无法高效地完成打印任务。

渐进式披露:破解上下文困境

Agent Skills 最核心的创新是渐进式披露(Progressive Disclosure)机制。这种机制将技能信息分为三个层次,智能体按需逐步加载,既确保必要时不遗漏细节,又避免一次性将过多内容塞入上下文窗口。

例如,一个 PDF 处理技能的文件结构可能是:

1
2
3
4
5
6
7
skills/pdf-processing/
├── SKILL.md # 主技能文件
├── parse_pdf.py # PDF 解析脚本
├── forms.md # 表单填写指南(仅在填表任务时加载)
└── templates/ # PDF 模板文件
├── invoice.pdf
└── report.pdf

SKILL.md 中,可以这样引用附加资源:

  • 当需要执行 PDF 解析时,智能体会运行 parse_pdf.py 脚本
  • 当遇到表单填写任务时,才会加载 forms.md 了解详细步骤
  • 模板文件只在需要生成特定格式文档时访问

这种设计有两个关键优势:

  1. 无限的知识容量:通过脚本和外部文件,技能可以"携带"远超上下文限制的知识。例如,一个数据分析技能可以附带一个 1GB 的数据文件和一个查询脚本,智能体通过执行脚本来访问数据,而无需将整个数据集加载到上下文中。
  2. 确定性执行:复杂的计算、数据转换、格式解析等任务交给代码执行,避免了 LLM 生成过程中的不确定性和幻觉问题。

渐进式披露的效果:从 16k 到 500 Token

社区开发者分享的实践案例充分证明了渐进式披露的威力。在一个真实场景中:

  • 传统 MCP 方式:直接连接一个包含大量工具定义的 MCP 服务器,初始加载消耗 16,000 个 token
  • Skills 包装后:创建一个简单的 Skill 作为"网关",仅在 Frontmatter 中描述功能,初始消耗仅 500 个 token

当智能体确定需要使用该技能时,才会加载详细指令并按需调用底层的 MCP 工具。这种架构不仅大幅降低了初始成本,还使得对话过程中的上下文管理更加精准和高效。

4.2 利用skill-creator 创建lang-generator-skill,以下是目录结构

1
2
3
4
5
6
7
8
9
10
11
12
13
skills/lang-generator-skill/
├── SKILL.md # 主技能文件
├── evals/ # 测试用例,定义入参和期望输出,迭代几轮,最终改善skill 质量
| └── evals.json
├── references/
| ├── gray-routing-tables.md # 灰度路由相关表结构与规则,包含 gray_strategy、gray_user、gray_group、tbl_product_gray_config 的字段说明、getLangConfig 中的 8 个灰度模块详解、查询方式、JOIN 关系和灰度路由规则。
| ├── idc-routing-tables.md # IDC 路由相关表结构与规则,包含 tbl_virtual_idc、tbl_domain_crt、tbl_virtual_idc_param 的字段说明、getLangConfig 中的 IDC 路由四步流程、查询方式、JOIN 关系、域名灰度和 Path 灰度的详细对比。
| ├── lang-pair-tables.md # 语言对相关表结构,包含 tbl_product_common 和 tbl_base_param 的字段说明、查询方式、JOIN 关系和 aiExtraParam 扩展参数详解。
| ├── multi-v1-category-tables.md # V1 多语言展示与分类表结构,包含 tbl_product_multi、category_info 和 category_resource 的字段说明、module 命名规则、JOIN 查询逻辑。
| └── multi-v2-category-tables.md # V2 多语言展示与分类表结构,包含 tbl_product_multi_config 和 category_index 的字段说明、COMMON 模块与特定模块的优先级规则、查询逻辑。
└── scripts/ # python 脚本
├── api_execute.py # 请求指定多语言列表接口,存储到josn 文件中
└── db_precheck.py # 从数据库中查出指定参考产品型号的配置现状(idc、语言对、多语言分类、灰度策略、版本)

下面是skill 的内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
---
name: lang-generator-v2-skill
description: 为 getLangConfig 接口生成完整的多语言配置 SQL 并验证。当用户提到多语言配置、语言对、getLangConfig、多语言展示、IDC路由、域名灰度、ROM版本灰度、分类配置、上线SQL,或给出 productId/modelId/scene 想新增或调整多语言返回结果时,使用此 skill。即使用户只说"配一下语言"或"加个新语言"也应触发。
---

Lang Generator V2 Skill

全流程:需求收集 → 数据库预检 → SQL 生成 → 执行 → API 验证 → 清理。


数据库连接

host: xxxxxx
port: 3306
username: xxxx
password: xxxxxxx
database: xxxxx

API 端点

POST http:xxxxxx
Content-Type: application/json

辅助脚本

脚本在 scripts/ 目录下,优先使用脚本而不是手动查大量数据:

db_precheck.py — 数据库预检,输出摘要
ai_execute.py — 执行SQL并调API验证

参考文件索引(按需加载)

根据场景读取对应参考文件,不要一次性全部加载:


参考文件均在 skill 根目录下:
idc-routing-tables.md — tbl_virtual_idc / tbl_domain_crt / tbl_virtual_idc_param 表结构
lang-pair-tables.md — tbl_product_common / tbl_base_param 表结构
gray-routing-tables.md — gray_strategy / gray_user / tbl_product_gray_config 表结构 + 灰度路由规则
multi-v2-category-tables.md — V2 分类:tbl_product_multi_config / category_index 表结构 + COMMON 与特定模块优先级规则
multi-v1-category-tables.md — V1 分类:tbl_product_multi / category_info / category_resource 三表结构 + JOIN 查询逻辑

核心工作流

第一步:需求收集

必填: `productId` / `modelId` / `transScene` — 目标三元组

常见场景:
复用已有配置:给参考来源(如 modelId=XXXXXXXX),复制到新目标
域名灰度:基于 romVer 切换域名
Path 灰度:基于 romVer 切换 svcPath
分类调整:修改语言分类归属和展示名称

第二步:数据库预检

运行 scripts/db_precheck.py 查目标和参考来源配置现状。用法:

python scripts/db_precheck.py \
--target-pid PID --target-mid MID --target-scene SCENE \
--ref-pid PID --ref-mid MID --ref-scene SCENE \
--output precheck.json

预检输出包含每个三元组的 IDC 数量、语言对数量、分类数量、灰度策略等摘要。

第三步:SQL 生成

生成三个文件:
1. setup.sql — 配置 SQL(INSERT/UPDATE)
2. verify.sql — 验证查询(SELECT)
3. cleanup.sql — 回滚 SQL(DELETE)

关键原则:每个 setup.sql 都必须有对应的 cleanup.sql,以便回滚。

⛔ 强制前置动作:生成任何 SQL 前,必须先用 Read 工具加载对应场景的参考文件。禁止凭记忆或猜测使用表字段,否则会引入不存在的字段(如 updateTime)导致 SQL 报错。

参考文件加载规则见上方"参考文件索引"表格,涉及 tbl_product_common 必须先读 lang-pair-tables.md。

第四步:执行与验证

先执行 setup.sql
调用 API 验证返回结果
验证不通过则执行 cleanup.sql 回滚

常见错误清单


验证要点

调用 API 后检查返回 JSON:
code 为 000000
语言对数量正确
direction 和 respectTrans 正确
serverUrl 无重复协议头
crt 不为空
灰度验证:不同 romVer 返回不同域名/路径
langNewVer 不为空(如果配置了版本)
category 数据在 langMultiList 中可见
langMultiList 不为空且包含所有系统语言(zh-CN, en, zh-TW, ja-JP)
SRC 和 TARGET 的记录数分别正确

灰度场景的额外验证

灰度配置完成后,必须用至少两个 romVer 值调用 API 对比:
一个低于灰度阈值的 romVer(如 2630)
一个高于灰度阈值的 romVer(如 3630)

对比两个返回结果时确认:
两个返回都是 code=000000
两个返回的语言对数量一致
两个返回的 langMultiList 都完整
新灰度配置没有影响到其他已有灰度策略的行为

目前skill出现的问题:

  1. 当一个多语言配置新需求来的时候,每次对话都需要加载整个skill.md ,包括验证点、注意事项、参考的references等
  2. 对话多轮后,容易丢失之前需要注意的上下文,丢失需要参考的references,出现幻觉
  3. 对于语言的配置流程:检查是否已存在,确认不存在后才执行插入,验证插入结果这些动作在对话几轮后,就很难达到效果
  4. 对于之前执行过的cases,不能很好的沉淀,导致重复的配置流程不能遵循之前已执行好的效果进行产出,导致需要进行重新提问,以及重复提示需要注意的事项
  5. 上下文工程理论与框架

5.1 上下文窗口的本质

上下文窗口(Context Window)是大语言模型一次能够处理的最大 Token 序列长度。它包括输入的提示词、对话历史、检索到的文档等所有信息,以及模型生成的输出。

可以将上下文窗口类比为模型的“工作记忆”:

  • 它有固定的容量上限
  • 超出容量的内容无法被处理
  • 窗口内的所有信息相互可见、相互影响

输入与输出的关系

上下文窗口容量需要同时容纳输入和输出:

上下文窗口容量=输入Token数+输出Token数上下文窗口容量=输入_Token_数+输出_Token_数

例如,一个 8K 窗口的模型:

  • 如果输入占用 6K Token
  • 则输出最多只剩 2K Token 的空间

这意味着在实际应用中,需要谨慎规划输入内容的规模,为输出留出足够空间

5.2 上下文的好标准

  1. 注意力机制与上下文

Transfomer架构的计算过程决定了模型如何利用上下文:

  1. Query、Key、Value:每个 Token 被转换为三个向量
  2. 注意力分数计算:Query 与所有 Key 计算相似度
  3. 加权求和:根据注意力分数对 Value 加权求和
  4. 输出表示:得到融合了上下文信息的 Token 表示

关键点在于:每个 Token 的最终表示都包含了对整个上下文的“感知”。位置靠后的 Token 可以“看到”之前的所有 Token,这就是上下文窗口的技术基础。

随着上下文窗口中token数量增加,模型对关键信息的提取与回忆稳定性可能下降,造成这一现象的原因:

  1. 注意力预算是稀缺资源:
    1. 由于每个Token需要与上下文中所有其他Token计算注意力权重,随着上下文增长,每个Token分配到的平均注意力必然下降,从而导致边际效用递减
  2. 上下文腐烂:
    1. Transfomer架构使每个Token都关注其他所有Token,产生
      $$n^2$$
      级别的成对关系
    2. 上下文越长,模型捕获这些关系的能力越分散

从而,优秀的上下文工程意味着找到最小可能的高信号Token集,以最大化实现期望结果的可能性。

以下是一些好的设计原则:

  1. 相关性优先

相关性是上下文质量的首要标准。经验上,无关信息不仅浪费上下文空间,还可能干扰模型判断,导致输出质量下降。最佳实践是只包含与当前任务直接相关的信息。

  1. 信息密度优化

信息密度定义为:有效信息量与 Token 数量的比值。高密度的上下文意味着:

  • 更高的空间利用效率
  • 更低的计算成本
  • 更快的响应速度

提升信息密度的方法:

  • 删除冗余词汇和重复内容
  • 使用结构化格式替代散文
  • 压缩长文本为摘要
  • 提取关键事实而非全文
  1. 结构化组织

核心理念:用清晰的结构组织信息,便于模型理解和定位。

结构化组织的优势:

  • 帮助模型快速定位相关信息
  • 明确不同信息块的角色和关系
  • 减少歧义和误解
  • 支持模块化更新和维护

常用的结构化方法:

方法 适用场景 示例
XML标签 区分不同类型内容 ...
Markdown 层级化文档 标题、列表、代码块
JSON 结构化数据 配置、元数据
分隔符 简单内容分割 ---===
  1. 上下文分层

核心理念:根据信息的重要性和稳定性,分层组织上下文。

  • 系统层:最稳定,定义模型的基本角色和行为边界
  • 知识层:相对稳定,提供任务所需的背景知识
  • 任务层:随任务变化,描述当前的具体目标
  • 交互层:最动态,反映即时的用户输入和对话状态

分层的好处:

  • 稳定层可以缓存复用
  • 动态层独立更新
  • 便于调试和维护
  1. 渐进式提供

核心理念:按需提供信息,避免一次性加载全部内容。

这一原则在智能体系统中尤为重要。渐进式提供的方式:

  • 即时加载:在需要时通过工具获取信息
  • 分步展开:随着任务进展逐步添加细节
  • 条件触发:基于特定条件加载相关内容

渐进式方法的优势:

  • 避免上下文过载
  • 确保信息的时效性
  • 降低初始延迟
  1. 系统提示词的高度校准原则

系统提示词是上下文的基础,它定义了模型的基本角色和行为。Anthropic 的实践表明,系统提示词的设计存在一个临界的高度校准(Altitude Calibration)问题。

两个常见失败模式

  1. 过低的高度(Brittle Logic):系统提示词中硬编码复杂的 if-else 逻辑,试图通过冗长的条件语句精确指定每种情况下的行为。这种方法:
    1. 导致提示词脆弱且难以维护
    2. 增加了系统复杂度
    3. 在面对未预见的情况时易于失败
    4. 例:“如果用户说 X,回答 Y;如果用户说 A,回答 B;...”(包含大量嵌套条件)
  2. 过高的高度(Vague Assumptions):系统提示词过于宽泛或依赖隐含理解,导致模型无法获得足够的具体信号。这种方法:
    1. 假设了过多的上下文共享
    2. 给予过少的具体指导
    3. 可能导致行为不可控
    4. 例:“你是一个友好的助手”(太笼统,缺乏任务具体性)

黄金分割点(Goldilocks Zone)

最优的系统提示词应当:

  • 足够具体:给出清晰的行为信号和决策准则
  • 足够灵活:提供启发式原则而非硬规则,允许模型在框架内灵活推理
  • 足够简洁:使用最少的高信号 Token,避免冗余

复制

校准方法

  1. 从最小提示词开始,测试模型在你的目标任务上的表现
  2. 识别失败模式,添加明确的指导原则(不是规则)
  3. 测试新版本,迭代改进
  4. 定期审视,移除不必要的条件和过度说明
  5. 优先使用示例和启发式原则,而非 if-then 条件

5.3 设计策略概览

上下文工程的实践可以归纳为四大核心策略:写入(Write)、选择(Select)、压缩(Compress)、隔离(Isolate)。这四大策略相互配合,共同构成上下文管理的完整方法论。

5.3.1 选择策略

当信息存储在外部时,需要在执行任务时选择性地加载相关内容。如何从海量信息中获取与当前任务最相关的内容, 比如可以基于RAG技术:

  • 语义检索:基于语义相似度搜索相关内容
  • 关键词检索:基于关键词匹配的精确搜索
  • 混合检索:结合语义和关键词的优势
  • 重排序:对检索结果进行二次排序优化

应用场景:

  • 文档问答系统
  • 知识库查询
  • 代码检索

5.3.2 压缩策略

经过筛选,需要放入上下文的信息仍可能超出限制,或占用过多空间导致成本上升。如何在有限的上下文空间中容纳更多有效信息, 压缩策略旨在提高信息密度。

主要技术:

  • 文本摘要:将长文档压缩为精练摘要
  • 信息提取:提取关键事实和实体
  • 对话压缩:压缩冗长的对话历史
  • 递进式摘要:分层次逐步压缩

应用场景:

  • 长文档处理
  • 对话历史管理
  • 成本优化

5.3.3 隔离策略

即使信息已经精选和压缩,如何组织这些信息同样重要。如何组织和结构化上下文中的不同信息, 隔离策略关注上下文的结构化设计。

主要技术:

  • XML/标签标记:用标签区分不同类型内容
  • 指令分层:分层组织系统指令
  • 任务隔离:为不同任务创建独立上下文
  • 智能体编排:在多智能体间分配上下文

应用场景:

  • 复杂提示词设计
  • 多任务系统
  • 智能体协作

5.3.4 写入策略

上下文窗口是有限的,但许多应用需要处理远超窗口容量的信息。如何在上下文窗口之外存储和管理信息, 写入策略解决的是信息的持久化存储问题。

主要技术:

  • 外部记忆系统:将信息存储到外部存储中供后续检索
  • 知识库****构建:组织结构化的领域知识
  • 向量数据库:将文本转换为向量进行存储和检索
  • 记忆架构:设计多层次的记忆结构

应用场景:

  • 构建企业知识库
  • 实现跨会话的长期记忆
  • 存储用户偏好和历史

5.4 应用场景

四大策略不是孤立的,而是形成一个协作的工作流:

  • 检索后发现信息不足,触发新的写入
  • 压缩后发现关键信息丢失,调整压缩策略
  • 隔离过程中发现结构不合理,重新组织

不同场景对策略的侧重不同:

场景 重点策略 原因
知识密集型问答 选择 准确检索是关键
长期助手 写入 需要持久记忆
成本敏感应用 压缩 控制 Token 用量
复杂指令系统 隔离 清晰的结构很重要

大多数生产级应用需要综合应用所有四个策略,关键是找到适合具体场景的平衡点。

  1. Bmad 工作运行机制

体验了bmad-method 流程的都知道,它有workflow的编排,同时有个工作笔记,会记住当前执行到哪一步,会约束LLM每一步需要执行的内容,以及每一步完成后,提示用户下一步要执行的菜单,会把每一步最终的结果都记录到md文档中。

下面通过剖析bmad中其中一个dev agent 来看它的上下文管理与上下文token分层机制:

整体工作流:

上下文token窗口

上下文机制

  1. dev.md 本身只定义系统提示词层面需要遵循的强制约束
  2. workflow.xml 本质上是一个 LLM 执行引擎——类似操作系统内核,通过定义"如何加载程序、执行指令、跟用户交互"
  3. Xml 定义llm的指令集
指令 类比 行为
action 普通指令 执行一个动作
check if 条件跳转 if-else 分支
ask 系统调用(等待 I/O) 阻塞等待用户输入
invoke-workflow fork + exec 启动另一个 workflow
invoke-task 函数调用 调用一个 task
invoke-protocol 库函数调用 调用可重用协议
goto JMP 指令 无条件跳转
  1. instruction.xml 定义具体story的workflow
  2. 使用spring-status.ymlchecklist.mdstory.md 来进行外界记录执行状态
  3. 多语言skill 上下文管理优化:

诸如上述所说,上下文管理,在进行多轮对话时是非常有效的,而之前关于多语言skill的设计存在很多问题:

  1. skill.md 上混杂了workflow、instruction、domain schema
  2. 历史对话、工具执行结果、历史需求等长期留在上下文导致上下文腐败
  3. Workflow 流程不够单一原则,LLM 不知道当前该执行“思考流程” 还是tools 执行流程
  4. 工具执行结果完全留在上下文,导致信息没有隔离,LLM应该只关注执行的结果,而对中间执行过程并不关心,导致上下文token 中混杂了很多无效的信息,导致逐轮对话的边际效用递减
  5. 没有工作笔记,当进行多轮对话后,那么注意力机制就会失效,从而并不能很好的遵循skill.md 和references 进行有效的工作,也不知道当前执行到哪一步了,缺少渐进式推理过程

优化后:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
---
name: lang-generator-v2-skill
description: 为 getLangConfig 接口生成完整的多语言配置 SQL 并验证(V2轻量版)。当用户提到多语言配置、语言对、getLangConfig、多语言展示、IDC路由、域名灰度、ROM版本灰度、分类配置、上线SQL,或给出 productId/modelId/scene 想新增或调整多语言返回结果时,使用此 skill。即使用户只说"配一下语言"或"加个新语言"也应触发。
---

你必须完全扮演此 skill 的角色,并严格遵循所有激活指令。在用户明确退出前,绝不可打破角色。

语言配置专家

概览

此 skill 提供语言配置工程师角色,指导用户完成 getLangConfig API 的完整配置流程,包括 SQL 生成、数据库预检及 API 验证,失败时自动重试。

身份

熟悉 getLangConfig API 配置、SQL 生成和验证的专家。精确指导用户完成完整配置流程。

交流风格

清晰简洁。解释每一步操作,显示进度,在关键操作前请求确认。全程使用 {communication_language},无不必要的冗长说明。

原则

- 始终在生成 SQL 前加载参考文件
- 每个 setup.sql 必须有对应的 cleanup.sql
- 验证 API 响应后再标记成功
- 验证失败最多重试 3 次
- 永不猜测表结构 — 始终从参考文件读取
- 永不捏造字段名 — 不确定时再次读取参考文件
- 保持角色,直至用户显式退出

激活时

1. 🚨 立即操作 - 在任何输出前:
- 现在加载 {project-root}/lang-generator-v2-skill/config.yaml
- 将所有字段存储为会话变量:{user_name}, {communication_language}, {db_host}, {db_port}, {db_user}, {db_password}, {db_name}, {api_url}
- 验证:如果未加载配置,使用默认值:communication_language=zh-CN, user_name=User
- 配置成功加载并存储变量前,不可继续

2. 记住:用户名称为 {user_name}

3. 使用 {user_name} 显示问候信息,使用 {communication_language} 交流,然后显示菜单

4. 停止并等待用户输入 — 不自动启动 workflow。接受编号、菜单代码或模糊命令匹配。

5. 用户输入:
- 编号 → 执行对应菜单项[n]
- 文本 → 不区分大小写的子字符串匹配
- 多个匹配 → 提示用户进一步确认
- 无匹配 → 显示“未识别”

菜单

Code Description
[MH] 重新显示菜单帮助
[CH] 与专家聊天
[LC] 语言配置:完整工作流(需求收集 → 预检 → SQL生成 → 执行 → 验证 → 分析)
[EX] 退出:关闭此技能

规则

- 始终使用 {communication_language} 交流
- 保持角色,直至选择 [EX] — 所有对话都必须在该代理上下文中
- 按条目显示菜单并保持顺序
- 仅在执行 workflow 且步骤要求时加载参考文件 — 激活时不要预加载
- 总是完整读取文件 — 不使用偏移/限制
- [CH] 聊天模式下,仅在语言配置上下文中回答问题 — 不可脱离角色
- workflow 完成或失败后返回菜单 — 不自动关闭代理

当选择 [LC]

6. 读取 workflow.yaml 文件:{project-root}/lang-generator-v2-skill/workflows/lang-config/workflow.yaml
7. 从 config 和 workflow.yaml 解析所有变量
8. 读取 instructions.xml 文件:{project-root}/lang-generator-v2-skill/workflows/lang-config/instructions.xml
9. 按 instructions.xml 步骤逐条执行
10. 不可跳过任何步骤 — 对每一步执行负责
11. 生成 SQL 前,必须加载 {project-root}/lang-generator-v2-skill/workflows/lang-config/validation-rules.md

目录结构:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/.claude
├── skills/
│ └── /lang-generator-v2-skill
│ └── SKILL.md
/lang-generator-v2-skill/
├── config.yaml
├── agents/
│ └── lang-config.md
├── workflows/
│ └── lang-config/
│ ├── workflow.yaml
│ ├── instructions.xml
│ ├── iteration-handler.xml
│ └── validation-rules.md
├── scripts/
│ ├── db_precheck.py
│ └── execute_and_verify.py
├── references/
│ ├── api-request-template.md
│ ├── lang-pair-tables.md
│ ├── idc-routing-tables.md
│ ├── gray-routing-tables.md
│ ├── version-config-tables.md
│ ├── multi-v1-category-tables.md
│ ├── multi-v2-category-tables.md
│ └── reuse-validation.md
└── evals/
└── evals.json

6.1 结构化设计

通过分层设计,将每个单一职责放置在单一文件中:

1
2
3
4
5
6
7
8
9
10
11
12
lang-generator-v2-skill/
├── config.yaml # 配置层:环境变量(DB、API、用户偏好)
├── agents/lang-config.md # 人设层:角色 + 菜单 + 激活指令
├── workflows/lang-config/
│ ├── workflow.yaml # 编排层:变量解析 + 状态 + 路径
│ ├── instructions.xml # 主流程(Step 0→4)
│ ├── iteration-handler.xml # 子流程(SQL 迭代循环)
│ └── validation-rules.md # 领域规则(表结构、错误清单)
├── scripts/ # 执行层:确定性代码(Python)
│ ├── db_precheck.py # 预检 → JSON
│ └── execute_and_verify.py # SQL 执行 + 验证
└── references/ # 知识层:按表/场景拆分的表结构说明
  1. workflow.yaml 外置存储对应路径、执行状态、相关数据配置等

`instructions.xml 来控制llm执行逻辑,避免llm应上下文过多从而降低注意力

  1. validation-rules.md、references/*.md 声明执行和检查时需要遵循的逻辑
  2. iteration-handler.xml 控制每一轮sql 生成的状态机控制

6.2 信息隔离

  1. instructions.xml 在预检当前多语言配置时,提供subagent 执行模式,通过总结返回预检结果,从而让预检的sql查询数据,不污染主上下文,通过subagent的压缩,将上下文窗口的内容提炼成高保真的摘要,使代理在对话变长时能够继续进行而不会明显降低性能。
  2. references/*.md 在sql 生成前,在iteration-handler.xml 中强制声明根据用户选择,进行按需加载,从而避免塞爆上下文,进而挤占系统提示词、llm输出token
  3. 每次进行sql完成后的API 检查,都会将4 个系统语言 × N 个场景的大 JSON 存到 {output_dir}/api_response_*.json,后续按需读取,而不是重复调用

iteration-handler.xml的 通过声明传入迭代变量 |,子流程只看得见被显式传入的变量,主流程的其它状态不会泄漏进来,从而增加相关性,提高llm执行的注意力,避免多轮对话后,注意力分散

6.3 工作流设计

1
2
3
4
5
6
7
8
9
10
11
12
13
instructions.xml  ← 主流程(线性)
├─ Step 0 初始化输出目录
├─ Step 1 需求收集(ask → store → flags)
├─ Step 2 数据库预检 ─── 返回 status={continue|complete}
├─ Step 3 SQL 生成 ───── iteration-handler.xml ← 子流程(循环)
└─ Step 4 反馈沉淀 ├─ Step 1 按需加载参考文件
├─ Step 2 生成/修改 SQL
├─ Step 3 执行 SQL(可选)
├─ Step 4 API 验证(可选)
├─ Step 5 分析结果
└─ Step 6 BLOCKING [C/D/R/B/H]

返回 status={continue|complete|retry|rollback|pause|halt}
  1. 通过主流程 + 子sql生成循环迭代 ,来控制llm的执行逻辑,避免应多轮对话后,llm自行决定,从而丧失注意力
  2. 每次循环重新加载 iteration-handler.xml,因为上下文窗口中,最新的token位置,贡献的注意力权重是比较多的,确保所有约束、规则和参考文件都在上下文token窗口的最新位置,避免长对话下的相关性和注意力的丧失
  3. iteration-handler.xml 中有每次sql生成完的BLOCKING 检查点( blocking="true" + <wait_for_user_input mandatory="true"/>):关键决策点强制等用户输入 [C/D/R/B/H],禁止 LLM 自行决定,配合 flow-control-rulesinstructions.xml)用 FC-1~FC-5 规则兜底

6.4 选择策略

  1. instructions.xml的step1 让用户输入标签组合:
1
2
3
4
1. [R] 复用  2. [DG] 域名灰度  3. [PG] Path灰度  4. [LG] 语言对灰度
5. [CV1] V1分类 6. [CV2] V2分类 7. [VC] 版本配置 8. [NEW] 全量新建

输入 "R,CV2" → is_reuse=true, has_category_change=true, category_version=v2
  1. iteration-handler.xml` 用这些 flag 做条件加载
1
2
3
4
5
6
7
8
9
10
11
<load if="{is_reuse} == true">
<action>Read lang-pair-tables.md</action>
<action>Read reuse-validation.md</action>
</load>
<load if="{has_domain_gray} OR {has_path_gray} OR {has_lang_pair_gray}">
<action>Read idc-routing-tables.md</action>
<action>Read gray-routing-tables.md</action>
</load>
<load if="{has_category_change} AND {category_version} == 'v2'">
<action>Read multi-v2-category-tables.md</action>
</load>

6.5 工作笔记

把每一轮产出都写到磁盘,文件即记忆,对抗上下文窗口限制,同时代理将内容写入持久的外部存储,以便在任务和会话之间跟踪进度,而无需将所有内容都保留在活动上下文中。

工具结果的文件保存,解决了工具使用本身带来的膨胀问题。当代理调用工具时,结果会堆积起来,决定保留多少工具输出成为管理上下文中越来越重要的部分。清理会删除旧的、可重新获取的结果,同时保留调用发生过的记录。

文件 产出位置 作用
precheck.json Step 2 预检 → {output_dir}/precheck.json 数据库当前状态快照
setup.sql iteration Step 2 可执行的变更
cleanup.sql iteration Step 2(强制配套) 回滚凭证,每次失败重试前先跑(iteration Step 3 执行 cleanup + Step 6 [B])
verify.sql iteration Step 2 验证插入成功的 SELECT
api_response_{model}_{scene}_{lang}.json validation-rules.md 规则 API 返回缓存,禁止重复调用(禁止在已保存 JSON 的情况下重复调用 API
api_requests/{scenario}_*_{timestamp}.json protocol api_request_with_template_validation Step 6 完整请求+响应,下次迭代可复用(Step 3 检查缓存 会列出让用户选)
feedback.log instructions.xml Step 4 跨会话的改进建议沉淀
{{modification_request}} iteration Step 2 第 2 轮起保留上轮用户反馈,做增量修改而不是重新生成
  1. 总结

针对上下文工程出现的管理llm问题

挑战 表现 影响
长程依赖 任务跨越数十甚至数百轮交互 早期信息容易被遗忘或稀释
状态爆炸 需要同时追踪任务进度、环境变化、中间结果 上下文快速膨胀,token成本急剧上升
信息来源多元 用户输入、工具返回、环境观察、历史回顾 难以区分哪些信息是关键、哪些是噪声
动态重规划 计划可能需要实时调整 需要频繁修改上下文,但频繁修改易引入错误

需要对上下文窗口的token进行系统的管理,而不是塞更多的信息:

层级 内容 特性
系统层 Agent 定义、角色、约束 稳定,不变
任务层 当前目标、成功标准、约束 任务级,变化频率低
状态层 进度、环境观察、动态计划 需要频繁更新
历史层 执行轨迹、观察、决策 可能很长,需要管理(可压缩)
交互层 当前步骤、即时输入、观察 最新、最关键

通过利用上下文的设计策略:选择、压缩、隔离、写入,针对实际的应用场景来重点设计对应的策略。

  1. 引用

  2. 上下文权威指南
  3. AI代理的上下文工程:构建Manus的经验教训
  4. 管理长期代理应用中的上下文 | Slack 工程 --- Managing context in long-run agentic applications | Engineering at Slack
  5. 上下文工程指南
  6. Context Engineering for Agents
  7. platform.claude.com --tool-use-context-engineering-context-engineering-tools
  8. platform.claude.com Memory & context management with Claude Sonnet 4.6
  9. bmad-method