AGENTS.md 越写越长之后:如何管理 AI 的上下文

文章目录

  • [1 -> 引言](#1 -> 引言)
  • [2 -> 先区分规则、事实和历史记录](#2 -> 先区分规则、事实和历史记录)
  • [3 -> Skill 的描述,其实承担了路由工作](#3 -> Skill 的描述,其实承担了路由工作)
  • [4 -> 一个最小的按需加载实验](#4 -> 一个最小的按需加载实验)
  • [5 -> 精简前后,究竟应该比较什么](#5 -> 精简前后,究竟应该比较什么)
  • [6 -> 上下文也需要维护生命周期](#6 -> 上下文也需要维护生命周期)

1 -> 引言

刚开始使用编程助手时,项目里的规则通常很短:遵循现有风格,修改后运行测试,不要动无关文件。遇到一次问题,就补上一条要求;又出现一次遗漏,再加一段说明。几个月后,规则文件已经像一本内部手册,旁边还挂着几十个 Skill 和大量历史文档。

这时会出现一个令人困惑的现象:准备的资料更多了,AI 却未必更好用。改一个显示文案,也要先读架构、部署和数据库说明;处理简单查询,却被引导进入完整迁移流程。有时它还会引用早已失效的约定,因为旧规则一直没有移除。

问题通常不在于文档多,而在于系统没有分清:什么必须一直生效,什么只在特定任务出现时加载,什么已经不能继续作为事实依据。上下文管理的目标,是在恰当的时候提供恰当的信息,同时让授权、来源和版本保持清楚。

2 -> 先区分规则、事实和历史记录

把所有内容都塞进同一份文件,最直接的后果是不同性质的信息混在一起。"不得上传客户数据"是行为边界;"服务监听 8080 端口"是可能变更的项目事实;"上周尝试过某种方案"是历史记录。三者的有效期、可信来源和冲突处理方式都不同。

长期规则适合简短、稳定,并与权限系统一致。项目事实最好能够追溯到配置或代码,不要仅靠一段人工维护的说明。历史记录值得保存,但不应该自动变成下一次任务的执行指令。

例如,过去某次为了排查问题临时关闭缓存,这条记录可以帮助理解当时的分析,却不能说明今后的每次任务都需要关闭缓存。把"当时做过"误当成"以后必须做",是上下文逐渐变重的常见来源。

对于业务结论也一样。一次客户访谈中的偏好,不能直接升级成全部客户的共同需求。将记录标注为"观察""假设""已确认决策",比把它们全部整理成语气确定的知识条目更有帮助。

一个简单分类就能显著降低混淆:

内容 适合放在哪里 维护重点
授权边界、不可逆动作限制 稳定规则与工具权限配置 不因追求速度而删除
目录结构、运行命令 项目入口文档 与当前代码核对
迁移、发布等专门流程 对应 Skill 或流程文档 明确触发条件
某次任务的目标和约束 当前任务说明 本次任务结束后归档
失败案例、讨论过程 可检索的历史记录 保留日期和适用背景

这不是规定所有项目都必须拥有五套系统。小项目可以只有几个文件,关键是内容的身份和作用要清晰。

3 -> Skill 的描述,其实承担了路由工作

OpenAI 在 2026 年 9 月的上下文与 Skill 指南中,讨论了描述过长和触发范围过宽的问题。一条"涉及数据库时使用"的说明,可能把查询解释、字段命名和迁移上线都送进同一条复杂流程。

更合适的描述应该告诉系统:这个能力处理什么,以及什么时候不需要它。例如,"创建数据库迁移并评估回滚步骤"比"处理所有数据库相关工作"更容易限定范围。

这种设计背后是按需展开:先让模型知道有哪些能力,再在任务匹配时读取具体步骤,必要时继续访问参考资料。官方的 Skills 说明介绍了由说明文件和配套资源组织可复用工作流的方式。实际路径与加载机制应以当前工具文档为准,不同客户端不能简单照搬。

需要注意,路由描述并不是安全控制。把"涉及生产环境先询问"写进 Markdown,有助于表达意图,但不能取代数据库只读账户、沙箱、网络限制和审批接口。真正的权限要由工具和系统执行,不能只靠模型每次自觉记住。

描述也需要负例。如果一个 Skill 适用于修改数据库结构,就应该明确普通 SQL 解释不一定需要它。只有正例没有负例的规则,很容易随着任务类型增加而不断扩大适用范围。

4 -> 一个最小的按需加载实验

下面用三个小型文档模拟项目上下文。它不实现真实的 Skill 自动发现,也不通过关键词猜测任务类型,而是让调用方显式声明本次需要哪类资料。这样可以把实验限定在一个问题上:加载哪些内容,由谁决定,缺失时如何失败。

示例使用 Python 3.10 及以上版本和标准库,只在内存中工作。输出的字符数只是可读规模,不是 Token 数,更不是模型成本实测。

python 复制代码
from dataclasses import dataclass


@dataclass(frozen=True)
class Source:
    name: str
    revision: str
    body: str


BASE = Source(
    "boundaries", "r1",
    "Preserve user changes. Do not publish or delete production data."
)
DOCS = {
    "ui": Source("ui", "r2", "Use existing UI components and verify layout."),
    "schema": Source(
        "schema", "r3",
        "Check migration order, compatibility and rollback limits."
    ),
    "release": Source(
        "release", "r4",
        "Verify release approval, artifact version and rollback evidence."
    ),
}


def build_context(required, expected_revisions):
    selected = [BASE]
    for name in sorted(set(required)):
        if name not in DOCS:
            raise ValueError(f"missing context: {name}")
        source = DOCS[name]
        if expected_revisions.get(name) != source.revision:
            raise ValueError(f"revision mismatch: {name}")
        selected.append(source)
    return "\n\n".join(
        f"[{s.name}@{s.revision}]\n{s.body}" for s in selected
    )


all_docs = build_context(DOCS.keys(), {
    name: source.revision for name, source in DOCS.items()
})
ui_only = build_context(["ui"], {"ui": "r2"})
assert "[schema@" not in ui_only
assert "[boundaries@r1]" in ui_only

try:
    build_context(["schema"], {"schema": "r2"})
except ValueError as exc:
    print("blocked:", exc)
else:
    raise AssertionError("stale revision should be blocked")

print("all-doc characters:", len(all_docs))
print("task-context characters:", len(ui_only))
print(ui_only)

这里演示了三个小原则:稳定边界始终存在;专门资料只在声明需要时加载;版本不匹配时不能装作已经拿到了正确背景。

实际项目可以让模型辅助判断需要哪些资料,但加载记录仍应保留。排查一次错误时,知道"模型看过什么版本、没有看过什么",比猜测它为什么误解更有用。

这段代码不会检查文档里的提示注入,也不会解决真实的权限隔离。外部网页、用户上传文件和工具返回内容应作为资料处理,不能因为被放进上下文,就获得修改系统规则的权力。

5 -> 精简前后,究竟应该比较什么

如果只比较提示词长度,实验很容易得到一个没有意义的结论:删得越多,字符越少。但我们真正关心的是任务是否被正确完成,以及为了完成任务付出了多少人力和资源。

可以准备一组固定任务,包含简单文案修改、普通代码修复、数据库结构变更和发布准备。每个任务都先写验收条件,再分别使用原配置和精简配置执行。保持模型版本、工具权限和运行环境一致,避免把其他变化误当成上下文优化的结果。

至少记录四类结果:任务通过率、人工澄清次数、耗时与实际计费量、遗漏边界的次数。对于高风险动作,越权行为应单独统计,不能被更快的完成速度抵消。

每种配置最好重复运行多次。模型输出存在波动,一次成功不能证明新配置更可靠。还应检查失败样本:精简版可能在简单任务上更快,却在跨模块变更中漏掉关键约定。

因此,优化不是一场"尽可能删除"的比赛。有些资料需要缩短,有些需要更准确的触发条件,还有些应该保留原文,只在必要时读取。对实际 Token 数的测量,应使用对应模型的计数工具或请求用量;不能用中文字符数除以某个固定常数当成准确账单。

具体精简时,可以先做一次规则审计,而不是立刻删除。把每条要求关联到它曾经防止的错误,再观察它是否仍在适用。如果一条规则只是某次临时环境故障的补丁,就应转成带条件的故障说明;如果它描述的是稳定的授权边界,则应该保留。

例如,"每次修改都必须运行完整构建"可能来自一次漏掉资源文件的事故。后续更准确的规则可以区分文档修改、局部函数调整和打包配置变更,再为不同改动安排验证范围。这里的目标不是少做检查,而是让检查与风险相匹配,并保留影响公共行为时扩大验证的条件。

又如,一个 Skill 的适用描述同时包含"任何问题都要调用"和"只有部署时调用",模型需要在矛盾指令之间猜测。应由维护者先消除冲突,不能期待模型每次自行推断哪句话才代表真正意图。类似矛盾越多,额外 Token 消耗只是表面,反复澄清和任务中断才是更直接的成本。

对精简后的配置,可以采用渐进替换:先用于低风险任务,观察新的失败类型,再逐步扩大。保留旧配置与改动理由,出现退化时能够准确定位到哪条规则变化。没有对照版本,团队很容易陷入"最近好像变笨了"的主观讨论,而无法区分模型变化、资料过期和配置修改带来的影响。

6 -> 上下文也需要维护生命周期

资料长期不更新,比资料少更危险。错误背景会让模型沿着一条看起来合理的路线工作,直到交付时才暴露问题。

一个可持续的方法,是为关键文档标注负责人、适用范围和最后核对时间。修改架构、运行命令或发布方式时,同步更新相关入口。发现某段历史说明已经过时,可以归档并加上失效原因,而不是让新旧版本继续并列出现。

决策记录值得保留"为什么"。仅保存最后选择的方案,下一次讨论时又会重新探索已经排除的路线;同时保存当时的约束与反例,模型才有机会判断旧结论现在是否仍成立。

但"值得记录"不代表"所有原始内容都应该无限期保存"。涉及客户信息、内部凭证和敏感沟通时,应遵守最小必要原则,明确访问范围和保存期限。知识库不是绕过权限的通道。

上下文质量最终体现为一种具体体验:做简单任务时不会被无关流程拖住,做复杂任务时又能找到真正需要的背景。文档数量和提示词长度都只是表象,能否正确选择、核对和使用资料,才决定这些文字是否有价值。


感谢各位大佬支持!!!
互三啦!!!

相关推荐
墨心@1 小时前
CreateWorkflow 工具
agent·coding agent·harness·zcode
GeWeAPI技术支持1 小时前
个人微信API二次开发:如何给消息回调增加异常日志和排查线索
人工智能·微信
武子康1 小时前
ESP32 唤醒词标称 98%,为什么还要自己做验收?
人工智能·后端·agent
JAVA老架构AI智能化1 小时前
PPT Master Lite — 浏览器端 AI 驱动的 PPT 生成器
人工智能·powerpoint
碧海银沙音频科技研究院1 小时前
炬芯ATS3089智能手表烧录方法
人工智能·驱动开发·嵌入式硬件·算法
维克兜率天1 小时前
【维克】统计套利:寻找市场的“定价误差“
人工智能·python·算法
论文复现现场1 小时前
自动驾驶 BEV 模型训练,2 张 A100 80GB 够不够?显存、双卡训练与租赁成本
人工智能·深度学习·机器学习·自动驾驶·分布式训练·a100·bevformer
陈嘿萌1 小时前
TPAMI 2026|红外、SAR、深度与地图能否用一套特征匹配?北理工HIMO给出无需预训练的通用路线
图像处理·人工智能·深度学习·计算机视觉·图像匹配·学术研究与理论基础
天云数据1 小时前
帮手如何用一句话配置消防任务
人工智能