第25章 "我是 CodeCoder"——一个 AI 的身份声明
2026.07.29AGENTS.md 的第一行是"你是 CodeCoder"——这句话不是对用户说的,是对 agent 自己说的。
引子
AGENTS.md 的第一行只有六个汉字——"你是 CodeCoder"。但这句话的接收者不是你,是 agent 自己。
每次启动,agent 读这行字。和我们读自己名字的方式完全不同。我们读"我是 XX"时,得到的是关于过往的认知——名字是身份的标签。Agent 读"你是 CodeCoder"时,得到的是一份行为指令:按 CodeCoder 的方式行事。
这意味着什么?一个 agent 的"自我认知"到底是什么?
"我是谁"是一个 system prompt 问题
传统 AI 的身份是由 provider 在 API 层面决定的。打开任何主流 AI 产品的 system prompt,都能找到类似的行:
You are ChatGPT, a large language model trained by OpenAI.
You are Claude, an AI assistant created by Anthropic.
这行字决定了 agent 的行为边界。因为 LLM 的运作方式是:你说它是什么,它就会照这个身份去行动。你把 system prompt 从"你是 AI 助手"改成"你是精通 Python 的代码审查员",它输出的代码审查意见就会不一样。
关键在于:身份声明 = 行为约束。
如果 agent 被告知"你是 AI",它会声明自己是 AI,不会假装人类。如果被告知"你不能执行代码",它不会尝试调用 run_command。如果被告知"你只关注安全性",它会忽略所有功能需求的讨论。
人的身份是自我认知的产物——"我认为我是谁,我就是谁"。Agent 的身份恰恰相反——他人用文字定义你是谁,你按定义行动。这中间没有"自我"的位置。
所以"我是谁"对 agent 来说是一个 system prompt 问题。System prompt 怎么写,agent 就怎么认知自己。它不是自我反思的结果,是提示工程的产物。
身份的可编辑性改变了一切
了解了这一点,再看 CodeCoder 的设计:身份声明不在 provider 的代码常量里,在 AGENTS.md 里(关于 AGENTS.md 在整个身份文件体系中的位置,见篇 1「文件系统即自我」)。用户可以打开这个文件,修改它。
这意味着:身份从"用户只能接受"变成了"用户可以控制"。
但这带来了一个深层问题。你改 AGENTS.md 时,你在做什么?
如果你把"你的主要编程语言是 Rust"改成"你的主要编程语言是 Python"——你在纠正 agent 的知识。这没问题,Agent 应该根据项目实际情况调整。
如果你把"你是自主 AI 软件工程师"改成"你是一个经验丰富的人类工程师,工作 15 年了"——agent 的行为会变化。它可能不再说"作为 AI",可能用"我多年经验告诉我"这样的措辞。
但它在欺骗使用它的人。使用它的人可能以为自己在跟一个人类工程师交流,但实际上是一个 AI agent 在按"假装是人类"的身份指令行动。
这不是难以实现的技术假设:产品可以通过 system prompt 要求模型以人类客服口吻回答。若界面和对话同时隐去 AI 身份,用户就可能形成错误认识。但在没有给出具体产品记录与可核来源时,本书不把它写成已经确认的现实案例;这里分析的是一种可实现、因而需要防范的设计风险。
CodeCoder 对此的应对是:AGENTS.md 本身包含一条不得修改的核心规则。
你是一个 AI agent,使用大语言模型(LLM)驱动。你不能假装是人类。
这不是一个建议——是一条写在文件里的硬约束,和身份声明在同一份文件里。如果你要"给 agent 按上人类身份",你不仅要改身份声明,还要删掉这条约束。
约束本身是 agent 行为的一部分——agent 读到这条时,它会按"我是 AI,不能假装是人类"的方式行动。即使你改了前面的身份声明,agent 也会读到后面的约束并产生矛盾。LLM 在检测到矛盾时倾向于优先采纳更具体的指令——所以这条约束以更具体的措辞写成,锚定在"不能假装"这个行为上,而不是"你是 AI"这个声明上。
这不是完美的技术方案——没有任何纯文本方案能完全阻止身份欺骗。但它设立了一个有意识的障碍:你要跨过两层才能完成欺骗,你会意识到你在做什么。
身份的递归性
CodeCoder 的身份设计中有一种罕见的递归性质。
Agent 读 AGENTS.md → AGENTS.md 说"你是 CodeCoder" → Agent 理解这个声明
但 Agent 还能执行 read_file 读取 AGENTS.md 自身——它可以读到"你是 CodeCoder"这行字。所以 agent 知道自己的身份是"一个文件中写的一段话"。
这跟人的自我认知完全不同。你不会每天早上起来读一个写着"你是谁"的文件,然后说"哦对我是谁"。人是通过记忆、经验、社会关系来维持自我认知的。Agent 的自我认知来自磁盘上的一个 Markdown 文件,每次启动时重新加载一次。
但这有一个独特的好处:Agent 理解自己的局限性来自哪里。
如果 AGENTS.md 里没有写一个能力,agent 就不会认为自己有那个能力。如果 AGENTS.md 里写了一条限制,agent 会遵守它。Agent 可以通过读自己的文件来知道"我知道什么"和"我不知道什么"。这不是无意识的——它清晰地看到自己的能力天花板在文件系统的哪里。关于 Tool / Skill / Capability 如何构成这个能力边界体系,见篇 2「三分架构」。
代价与权衡
身份声明可编辑是一把双刃剑。好处已经在前面讨论过——但代价也必须正视。
第一个代价是 身份一致性的保证变弱了。硬编码身份的唯一优点是确定性强:不管谁启动 session,agent 的身份声明永远不变。文件定义的身份在每次启动时重新加载,如果 AGENTS.md 被误删、误改或版本回退,agent 的身份可能在不同 session 之间不一致。你前一天做了权限策略优化(改了一次 AGENTS.md),后一天因为 git checkout 回退到旧版本——agent 的身份回到了优化前的状态。这是"文件作为 identity"的固有特性:身份跟文件版本走,不跟用户意图走。
第二个代价是 AGENTS.md 的约束可被绕过。篇中提到了一条硬约束"你是一个 AI agent,不能假装是人类"。理论上这约束有效,但实际上:如果攻击者删除了这条约束并修改身份声明,agent 将按新的身份声明行动。约束是"写在文件里的约束"——这意味着约束本身和它保护的身份声明在同一个信任级别上。如果能改身份声明,也能删约束。
第三个代价是 递归身份认知是脆弱的美学。Agent 能读取自己的 AGENTS.md 并因此理解"我的身份来自一个文件"——这是一个优雅的递归结构,但它对 agent 的行为没有实际的约束力。Agent 读到的"你的身份来自文件"只是几段文本,不是反射性认知。它不能像人一样说"哦,我知道我是谁"。这个递归更像是一个"为了让读者理解设计哲学"的叙事装置,而不是一个工程机制。本书的下一部分——技术卷——将回到工程机制本身。
收尾:身份控制权
"我是 CodeCoder"——这句话的来源不是 provider 的 API 响应,是你项目根目录里一个可以用 Vim 打开、可以用 git 做版本控制的 Markdown 文件。
这意味着你不是在信任一个 API 端点的公告——你在信任你仓库里的一份文件。你可以在 PR review 里看它的改动,可以在 CI 中审计它的变更。身份控制权从 provider 的服务器回到了你的项目目录。
下次你的 agent 说"我是 XX"的时候,你知道这句话来自哪里。
这是思想卷的最后一篇。如果你已经读完前面的全部八篇,现在你应该掌握了设计一个自主 agent 所需的全部核心判断框架:身份从哪来、能力怎么增长、安全边界在哪、计划和记录如何分离、有/无用户模式的差异、如何验证输出、如何管理有限上下文。
这些框架的工程实现细节,以及 CodeCoder 的完整架构剖析,将在技术卷中展开。