> ## Content Index
> Fetch the complete content index at: https://andybase.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# 当代码不再稀缺 - 06
- URL: https://andybase.com/dang-dai-ma-bu-zai-xi-que-06/
- Published: 2026-08-02T03:33:36.000Z
- Updated: 2026-08-02T03:33:36.000Z
- Author: andy

## Prompt 不是新的 Source Code

> **A prompt can generate an answer. It cannot, by itself, preserve why the answer should be true.**

> 提示词可以生成一个回答，但它自己并不能证明这个回答为什么是对的

AI coding tools 刚开始流行时，有一个说法很有吸引力：

> Prompt 是新的 source code。

听起来很合理。

以前我们写 Python、Java、TypeScript；以后我们写自然语言，让模型完成 implementation。既然 prompt 决定 output，那就像管理代码一样把 prompt 保存、version、review，不就行了吗？

我也理解这个比喻为什么流行。它把一个陌生工作套进了工程师熟悉的框架。

问题是，它把 generation instruction 和 system truth 混在了一起。

一个 prompt 可以生成正确答案，却未必保存答案为什么应该正确。

## 同一段 Prompt，不一定生成同一个系统

假设我们保存了一段表现不错的 prompt。

几周后：

- Model version 变了；
- Repository 多了几个 abstraction；
- Retrieval 拿到的文件不同；
- Tool permission 变了；
- Database schema 更新了；
- Agent workflow 从单轮变成多 agent；
- 原来存在人脑里的 domain context 没有人补进去。

Prompt 文本一字没改，输出仍然可能不同。

因为真正决定结果的从来不只是 prompt：

```text
Output = Prompt
       + Model
       + Tools
       + Repository state
       + Retrieved context
       + Runtime configuration
       + Hidden assumptions

```

Prompt 很重要，但它只是一次运行中被选中的 context 投影。

把投影当 source of truth，就像把一次 SQL query 当成整个 data model。它确实能拿到结果，但没有解释结果为什么应该这样。

## AI-polished Ticket 的问题不是“用了 AI”

PM 用 AI 整理 ticket，不一定是在污染 context。

有时 AI 能把一段散乱讨论整理得更清楚，补齐格式，找出矛盾，甚至提示遗漏的 acceptance criteria。

真正危险的是 provenance 消失。

整理后的 ticket 往往把这些东西混成一段非常顺滑的文字：

- 客户原始问题；
- PM 已经确认的决定；
- Engineer 提出的 constraint；
- 尚未验证的 assumption；
- AI 为了让文本完整而补出的内容。

后面的 engineer 和 agent 看到的是一份“看起来已经想明白”的需求，却不知道哪句话具有哪种 epistemic status。

这就是 false clarity。

文本质量提高了，事实边界反而模糊了。

## Prompt 混合了五种不同的东西

大多数工作 prompt 同时包含：

1. **Facts：** 当前系统和业务中已经成立的事实；
2. **Decisions：** 团队明确选择了什么；
3. **Assumptions：** 为了继续工作暂时相信什么；
4. **Instructions：** 希望 agent 这一次做什么；
5. **Examples：** 用来帮助模型理解的样本。

对模型来说，它们都是 tokens。

对工程责任来说，它们完全不是同一种东西。

Fact 错了要修正；decision 变了要记录原因；assumption 需要验证；instruction 可以重写；example 可能只是帮助理解，不应该被当作规则。

如果所有内容都埋在一个 prompt 里，团队很难回答：

> 这次实现依据的是哪一条事实？哪个 assumption 还没有被验证？

## Prompt 也很难表达完整 State Space

自然语言特别适合描述 intent，也很容易只描述 happy path。

软件真正麻烦的地方往往藏在：

- 状态转换；
- 权限组合；
- 时间和 timezone；
- 并发；
- Migration；
- Data integrity；
- Partial failure；
- Recovery。

“判断某天床位是否被预约”是一句非常自然的需求。

但系统需要知道“某天”究竟是 calendar day、business day，还是一个绝对时间区间。这个 invariant 如果只靠 prompt 里的某句话，很容易在下一次摘要、润色或 retrieval 中消失。

它需要进入更耐久的表达：domain model、state-transition rule、acceptance example、regression test，或者至少一个明确有 owner 的 decision record。

## Tests 也不能单独承担 Source of Truth

一个常见反驳是：不用纠结 prompt，tests 才是 specification。

Tests 确实比自然语言更可执行，但也不是天然正确。

如果 tests 和 implementation 都由同一个 agent、根据同一份失真 ticket 生成，它们可以共同通过，然后一起回答错误的问题。

Tests 能证明被编码的规则得到满足，不能自动证明被编码的是正确规则。

更可靠的做法是让 evidence 来自不同来源：

- 历史 production case；
- Domain invariant；
- Ops workflow；
- 客户原始反馈；
- Independent oracle；
- Security / data constraint。

Source of truth 不是某一个万能 artifact，而是一套可追溯、互相制约的 context system。

## 我更愿意使用 Context Contract

Context Contract 不是要求团队写七份文档。

它只是要求几类不同信息不要静默混在一起。

### 1\. Original Problem and Provenance

用户到底遇到了什么？

保留客户原话、support case、operational observation，以及谁在什么范围内提出这个问题。

Raw source 很丑也没关系。它的价值不是文笔，是防止 normalized ticket 取代现实。

### 2\. Decisions and Non-goals

团队选择了什么，为什么？

同时写清楚这次明确不解决什么。AI 特别擅长在模糊 scope 里热心扩写，non-goals 可以减少“顺手多做一点”的 code inflation。

### 3\. Domain Model and Invariants

有哪些 entity、state 和 state transition？

哪些时间、权限、数据完整性和业务规则必须始终成立？

这部分是让局部实现重新连接系统语义的关键。

### 4\. Acceptance Evidence

什么行为算正确？

不仅是 happy path，还包括 negative example、boundary case、historical bug 和 independent oracle。

### 5\. System Constraints

Architecture、public contract、dependency、security、performance、migration 和 operability 有什么限制？

Agent 不知道的 constraint，不会因为 prompt 写得有礼貌就自动出现。

### 6\. Generation Recipe

这里才包括 prompt、model、tools、agent workflow、repository references 和 runtime config。

这部分当然可以 version，也应该 version。

但它是 recipe，不是 business truth。

### 7\. Decision and Evidence Trace

Candidate 引入了哪些新 assumption？

什么 tests、review、QA 和 production evidence 支持团队接受它？

如果未来出问题，团队应该能够从 change 追溯回 intent，而不是只剩一句“当时模型生成的”。

## 从 Prompt Engineering 到 Context Compilation

解决办法不是把所有信息塞进一个更长的 prompt。

Context 越长，不代表 context 越完整。无关信息也会稀释 attention，过期内容还会互相冲突。

更好的过程像 compilation：

```text
Durable context artifacts
→ 选择与当前 change 相关的事实、决策和 constraints
→ 编译成 agent 可消费的 instruction
→ 保留 source references 和 assumptions
→ 生成 candidate
→ 把新 decision 和 evidence 回写

```

目标不是 token 最大化，而是 context integrity。

这也意味着 prompt 可以自动生成。

如果 durable artifacts 足够清楚，团队完全可以让工具根据 task、repository 和 risk 组装不同 agent 需要的 context。真正值得长期维护的，不一定是那段最终 prompt，而是 prompt 背后的事实和约束。

## 最强的反对意见：Specs 也会过时

对。

Decision record 会过时，architecture 文档会过时，tests 也可能把旧行为固化成错误规则。

Context Contract 没有让任何 artifact 自动获得真理地位。

它的优势只是让团队有机会知道：

- 谁拥有这条信息；
- 它是什么类型；
- 何时更新；
- 哪些 change 依赖它；
- 什么 evidence 可以推翻它。

Version control 只能保存历史，不能保证内容正确。

但没有 provenance 和 ownership，团队连应该修哪一层都不知道。

## 另一个反对意见：这不就是重文档流程吗

如果每个小 change 都要求一份十页 spec，当然是。

Context Contract 是信息类别，不是 ceremony 数量。

一个低风险 change 可以只在 PR 里写：

```text
Fact
Decision
Assumption
Invariant
Acceptance Evidence

```

一个涉及账务、权限、迁移或复杂状态机的 change，才值得建立完整 state model 和 decision record。

Structure 应该随 risk 增长，不应该随组织对 framework 的热爱增长。

## 下周可以做的一个实验

找一个正准备交给 coding agent 的 ticket。

不要先改 prompt。先把内容拆成：

```text
Facts
Decisions
Assumptions
Open Questions
Invariants
Acceptance Evidence
Generation Recipe

```

然后交给另一个没有参加原讨论的 engineer。

让他只回答两个问题：

1. 哪些内容仍然无法判定？
2. 哪些句子看起来像 requirement，其实没有来源？

你可能会发现，很多所谓 prompt engineering 问题，真正缺的是 context ownership。

Prompt 当然值得优化。它决定 agent 这一次如何工作。

但团队真正需要保护的，不是某次对模型说过什么，而是：

> **我们为什么相信这个 change 应该这样工作。**