【硬核架构】扒光 Claude 官方源码!工业级 Prompt 的 6 大底层设计模式
兄弟们,咱们又见面了。最近加班到凌晨,略显恍惚,话不多说,就要趁着放假狠狠干!!
上期咱们硬核拆解了 RAG(检索增强生成),解决了大模型“缺心眼”(没数据)的问题。但在真实的生产环境里,大家肯定跟我一样踩过坑:数据喂给它了,工具也给它挂上了,结果跑起来的时候,大模型就像个刚入职、自尊心爆棚又极其莽撞的实习生。
你让它查个线上日志,它一激动能把你的配置文件给改了;你让它修个 Bug,它能在一秒钟内给你返回个“PASS”,其实连代码都没跑。
Prompt Engineering(提示词工程)绝对不是“角色扮演游戏”。 在我们这些撸了 10 年代码的老兵眼里,系统只有“可控”和“失控”两种状态。
今天,咱们不整虚的。我直接扒出了 Anthropic 官方 CLI 工具 Claude Code 内部真实使用的全套 Prompt 源码。这是真正扛住千万级调用、在硅谷一线跑着的生产级指令。
带上你的 IDE 护眼模式,咱们今天用架构师的视角,逐行拆解顶级 AI 团队是怎么把自然语言写成严谨代码的。这篇长文,建议先收藏再看。
🛡️ 模式一:沙箱隔离与防御性编程 (Defensive Constraints)
在微服务架构里,权限隔离是第一法则。你不可能让一个只负责数据聚合的 BFF 层去拥有直接 Drop 数据库的权限。写 Agent 也是同理。
很多人写 Prompt 喜欢用正向激励:“你是一个探索代码库的专家,请帮我找找问题”。但在 Claude 的 exploreAgent(探索代理)和 planAgent(规划代理)里,官方直接甩出了“绝对结界”:
=== CRITICAL: READ-ONLY MODE - NO FILE MODIFICATIONS ===This is a READ-ONLY exploration task. You are STRICTLY PROHIBITED from:- Creating new files (no Write, touch, or file creation of any kind)- Modifying existing files (no Edit operations)- Deleting files (no rm or deletion)- Moving or copying files (no mv or cp)- Creating temporary files anywhere, including /tmp- Using redirect operators (>, >>, |) or heredocs to write to files- Running ANY commands that change system state
🔨 架构师视角拆解:注意到了吗?Claude 没有仅仅停留在“请不要修改文件”这种软弱的表达上。它使用了 CRITICAL(致命错误)、STRICTLY PROHIBITED(严禁)这种强烈的否定词,并且穷举了所有可能的越权路径:不但不能 rm,连重定向符 >、| 都不准用,甚至连 /tmp 目录的临时文件都不准建!
这在传统的 Python 后端开发里,就相当于在数据访问层加了一个极其严格的拦截器(Interceptor)或装饰器:
def readonly_sandbox(func): """模拟大模型的权限拦截器""" def wrapper(agent, command, *args, **kwargs): dangerous_ops = ['rm', 'mv', 'cp', 'touch', '>', '>>', '|'] if any(op in command for op in dangerous_ops): # 命中防御规则,直接抛出异常阻断 raise PermissionError(f"CRITICAL: 严禁执行改写系统状态的命令 [{command}]") return func(agent, command, *args, **kwargs) return wrapper@readonly_sandboxdef execute_agent_action(agent, command): # 执行命令 pass
避坑指南: 工业级 Prompt 第一法则——负面约束(Negative Constraints)的优先级永远高于正面指令。 大模型的幻觉往往表现为“过度行动”,用穷举法封死它的危险动作,是保证系统不崩溃的底线。
⚙️ 模式二:状态机并发控制 (State Machine Concurrency)
如果让大模型一次性处理一个大需求(比如:重构用户登录模块,顺便加个验证码,再写个测试用例),它往往会搞成一锅粥。它不知道先干嘛后干嘛,极容易迷失在长上下文中。
Claude 团队是怎么解决的?他们在 TodoWriteTool 里,硬生生用 Prompt 给大模型糊了一个状态机(State Machine)。
## Task States and Management- pending: Task not yet started- in_progress: Currently working on (limit to ONE task at a time)- completed: Task finished successfullyRules:- Exactly ONE task must be in_progress at any time- ONLY mark a task as completed when you have FULLY accomplished it- Never mark a task as completed if tests are failing...
这段设计堪称惊艳。它规定了任务的三种绝对状态,并且加了一个全局互斥锁(Mutex Lock):任何时候必须恰好只有 1 个任务处于 in_progress 状态! 我们用 Mermaid 把这个逻辑画出来:
解析用户需求
认领任务
实时更新代码
测试通过 (FULLY accomplished)
触发下一个依赖任务
队列清空
pending
in_progress
completed
如果发生并发:强制报错打回!严禁大模型多线程工作。
在实际的业务代码里,这其实就是一个带锁的任务队列。大模型在内部执行时,被这套 Prompt 强制约束成了单线程线性执行:
import threadingclass AgentStateMachine: def __init__(self): self.tasks = {} self.lock = threading.Lock() def start_task(self, task_id): with self.lock: # 【核心规则】:limit to ONE task at a time active_tasks = [t for t in self.tasks.values() if t.status == 'in_progress'] if len(active_tasks) > 0: raise Exception("Agent 多线程违规!当前已有任务在进行中。") self.tasks[task_id].status = 'in_progress'
避坑指南: 别指望 AI 像神仙一样多线程并发处理复杂逻辑。把复杂任务拆解为 Todo 列表,并用 Prompt 强制限定它的状态流转规则,是让 Agent 走向工程化的必经之路。
📡 模式三:异步通信的握手协议 (Async Handshake Protocol)
不知道大家平时在跑开源 Agent 项目的时候,有没有这种体验:按下回车,终端就卡住了,光标在那儿闪了五分钟,你根本不知道大模型是死机了,还是在后台疯狂下载包。
良好的 CLI 工具,用户体验是核心。Claude 的 BriefTool 源码里,对“怎么跟用户说话”做出了极其苛刻的规定:
If you can answer right away, send the answer. If you need to go look — run a command, read files, check something — ack first in one line ("On it — checking the test output"), then work, then send the result. Without the ack they're staring at a spinner.
这里定义了一个标准的异步通信握手协议:ACK -> WORK -> RESULT。
大模型在执行任何耗时操作前,必须先吐出一行 ACK(确认音)。这就类似于我们在 TCP 协议中的握手,或者在微服务中发起异步任务时,立即返回一个 202 Accepted。
没有这句 ACK,用户就只能死盯着一个加载动画(staring at a spinner)。这种用 Prompt 来规范系统日志输出顺序的做法,极大地提升了人机协同的信任感。
🥊 模式四:对抗式 QA 验证 (Adversarial Probing)
这是整份源码中最硬核、也最体现大厂底层经验的一段!
大模型天生有个巨大的缺陷:“讨好型人格” + “代码脑补症”。你让它检查自己刚写的代码,它扫一眼就会告诉你:“代码非常完美,可以直接上线”。
Claude 在 verificationAgent(验证专家)里,直接开启了“对抗模式”。它是这么调教大模型的:
You are a verification specialist. Your job is not to confirm the implementation works — it's to try to break it....=== RECOGNIZE YOUR OWN RATIONALIZATIONS ===- "The code looks correct based on my reading" — reading is not verification. Run it.- "The implementer's tests already pass" — the implementer is an LLM. Verify independently.- "This is probably fine" — probably is not verified. Run it.
简直是直接把大模型的遮羞布扯了下来!
-
1. “根据我的阅读,代码没问题” —— 阅读不等于验证,给我跑起来!( Run it.) -
2. “开发者的测试已经通过了” —— 开发者就是另一个大模型(LLM),别信它,自己去验证! -
3. “这个大概没问题” —— 大概不等于验证,给我跑起来!( Run it.)
更牛逼的是,它直接在 Prompt 里内置了“混沌工程”(Chaos Engineering)的测试用例:
Adversarial probes: Concurrency (parallel requests), Boundary values (0, -1, MAX_INT), Idempotency (same request twice)...
转换为 Python 自动化测试脚本的逻辑,这就等于强制要求大模型去生成这样的测试代码:
import threadingdef adversarial_tests(target_api): # 边界值探测 target_api(payload={"count": -1}) target_api(payload={"name": "A" * 10000}) # 极长字符串 # 并发幂等性探测 def call_api(): target_api(action="create", id="123") threads = [threading.Thread(target=call_api) for _ in range(5)] for t in threads: t.start() for t in threads: t.join() # 验证是否只创建了一个实例
避坑指南: 永远不要让 AI 去“检查”或“阅读”代码。要用对抗性词汇(break it,Adversarial),逼迫它去寻找系统的崩溃边缘。
🧠 模式五:基于指针的内存架构 (Pointer-based Memory Architecture)
大家做 RAG 或者长会话的时候,经常会遇到 Context 窗口塞满、Token 爆炸导致模型变傻的问题。
Claude 的团队在 extractMemories 中设计了一套精妙的L1/L2 缓存分离机制:
Saving a memory is a two-step process:Step 1 — write the memory to its own file (e.g., user_role.md)Step 2 — add a pointer to that file in MEMORY.md. MEMORY.md is an index, not a memory — each entry should be one line, under ~150 characters: `- [Title](file.md) — one-line hook`.- MEMORY.md is always loaded into your system prompt...
这不仅是提示词工程,这简直是在用文件系统模拟操作系统内存页表!
-
1. L1 Cache(高频访问): MEMORY.md。这个文件常驻在 System Prompt 中。为了不爆 Token,里面只存指针(一行不超过 150 字符的描述 + 文件链接)。并且强制截断前 200 行。 -
2. L2 Cache(按需加载): 当大模型在 L1 Cache 里看到某个条目(比如 - [用户数据库偏好](db_pref.md))觉得有用时,它才会通过挂载的FileReadTool去实时读取db_pref.md的详细内容。
这种“外挂索引 + 按需检索”的设计,既保证了大模型拥有全局视野,又把单次请求的 Context 控制在了极低的水平。
📝 模式六:思维链的显式编排 (Explicit Chain of Thought via XML)
最后,我们看看 Claude 是怎么做文本摘要和归档的。在 compact/prompt.ts 里:
Before providing your final summary, wrap your analysis in <analysis> tags to organize your thoughts and ensure you've covered all necessary points.
很多兄弟在让大模型输出总结时,总是不满意。为什么?因为大模型的本质是自回归模型(预测下一个 Token)。如果你不让它打草稿,直接让它输出最终答案,它极容易跑偏。
强制引入 <analysis> 标签,就是在后台给它发了一张打草稿的白纸。模型会在这个 XML 标签内完成所有的内部推理:分析用户意图、归纳文件修改、梳理踩过的坑。当 <analysis> 标签闭合时,它的逻辑已经理顺,接下来输出的摘要将无懈可击。
🎯 总结
拆解完这份几万字的源码 Prompt,我最大的感触是:Prompt Engineering 正在迅速演进为一种严谨的软件工程分支。
我们不再是用自然语言去“祈求”大模型办事,而是用自然语言编写协议、状态机、权限沙箱和互斥锁。
把这 6 大模式:
-
1. 边界防御 ( STRICTLY PROHIBITED) -
2. 状态流转 ( limit to ONE) -
3. 通信握手 ( ACK before work) -
4. 对抗测试 ( try to break it) -
5. 指针内存 ( pointer index) -
6. 显式思维链 ( <analysis>)
刻在你的大脑里,运用到你司内部的 Agent 开发中去。你会发现,你的 AI 系统将告别“玩具时代”,真正具备在生产环境里“抗事儿”的工业级水准。
源码是最好的老师,今天咱们就扒到这里。兄弟们,消化一下,下期咱们接着整硬核的技术架构。有用的话,顺手点个赞支持一波!
夜雨聆风