AX Development — Agent Experience Framework
Software is increasingly consumed by AI agents, not just humans. AX (Agent Experience) is the discipline of designing code, APIs, and interfaces that agents can operate reliably and autonomously.
The 8 Principles
1. Fast Fail Early
Reject invalid inputs before expensive operations. Validate at the boundary, not deep in the call stack.
CODEBLOCK0
2. Deterministic Outputs
Same inputs → same outputs. No wall-clock dependencies, no random IDs in deterministic paths, no hidden state mutations.
CODEBLOCK1
When non-determinism is necessary (UUIDs, timestamps), isolate it and make it injectable.
3. Machine-Readable Errors
Structured errors with codes, not just string messages. Agents parse error codes, not prose.
CODEBLOCK2
4. Explicit Over Implicit
No magic defaults that silently change behavior. Every configuration has a visible default. No hidden heuristics.
CODEBLOCK3
5. Composable Primitives
Each function does one thing. Pipeline steps are independent and recombinable. Agents can use each step separately.
CODEBLOCK4
6. Narrow Contracts
Minimal required inputs, maximal type safety. Accept only what you need. Return only what's useful. Avoid God objects.
CODEBLOCK5
7. Co-located Documentation
Docs live next to the code they describe. Each module has its own contract. Agents find docs by exploring the file tree, not by searching a wiki.
CODEBLOCK6
8. Test-First Invariants
Every behavior has a test. Tests are the executable specification that agents read to understand contracts. Prioritize boundary tests over happy-path.
CODEBLOCK7
Applying AX — Decision Checklist
Before shipping any module, verify:
- - [ ] Can an agent call this function with zero ambient knowledge?
- [ ] Are all errors machine-parseable (code + structured data)?
- [ ] Does the output change if I run it twice with same inputs?
- [ ] Is there any implicit behavior not visible in the function signature?
- [ ] Can I use this module without importing unrelated modules?
- [ ] Do the tests cover invalid/edge inputs, not just happy paths?
- [ ] Is there documentation within 1 directory level of the code?
- [ ] Would an agent need to read source code to understand the contract, or are types + tests sufficient?
CLI Contracts (for CLI tools)
When building CLIs that agents will invoke:
- - Default to machine-readable output (JSON/JSONL), human-readable opt-in via INLINECODE0
- Include stable keys in output (not just pretty-printed text)
- Use exit codes consistently (0 = success, 1 = user error, 2 = system error)
- Version output format — breaking changes to JSON structure need a flag or migration path
- Prefer explicit flags over positional arguments for agent discoverability
See references/cli-contracts.md for detailed patterns.
Error Taxonomy
Standard error code prefixes for AX-compliant projects:
| Prefix | Domain | Example |
|---|
| INLINECODE2 | Input validation | INLINECODE3 |
| INLINECODE4 |
Required data absent |
MISSING_RESOURCE_URI |
|
ORPHAN_* | Reference to non-existent entity |
ORPHAN_SYNC_TARGET |
|
CONFLICT_* | Contradictory configuration |
CONFLICT_LAYOUT_CHILDREN |
|
UNSUPPORTED_* | Valid but not implemented |
UNSUPPORTED_LAYOUT |
Adopt this taxonomy or define your own — the point is consistency within a project.
AX 开发 — 智能体体验框架
软件正越来越多地被AI智能体而非人类所消费。AX(智能体体验)是一门设计代码、API和接口的学科,使智能体能够可靠且自主地运行。
八大原则
1. 快速早失败
在昂贵操作之前拒绝无效输入。在边界处验证,而非调用栈深处。
typescript
// ✅ 在构建复合体之前验证同步规则
const errors = validateSyncRules(rules, knownSources);
if (errors.length > 0) throw new AXError(INVALIDSYNCRULES, errors);
// ❌ 在HTML渲染过程中才发现无效规则
2. 确定性输出
相同输入 → 相同输出。无时钟依赖,确定性路径中无随机ID,无隐藏状态变更。
typescript
// ✅ 纯函数,可预测
function buildDescriptor(resources, orchestration) { ... }
// ❌ 结果静默依赖于 Date.now() 或 Math.random()
当非确定性不可避免时(UUID、时间戳),将其隔离并使其可注入。
3. 机器可读的错误
带有代码的结构化错误,而非仅字符串消息。智能体解析错误代码,而非文字描述。
typescript
// ✅ 结构化,可解析
{ code: ORPHANSYNCTARGET, target: viz:render, available: [postgres:query] }
// ❌ 仅一个字符串
throw new Error(Target not found in resources);
4. 显式优于隐式
没有静默改变行为的魔法默认值。每个配置都有可见的默认值。无隐藏启发式规则。
typescript
// ✅ 默认值显式且已文档化
function render(descriptor, { theme = auto } = {}) { ... }
// ❌ 从环境变量静默检测主题
5. 可组合的原语
每个函数只做一件事。流水线步骤独立且可重新组合。智能体可单独使用每个步骤。
Collector → Composer → Renderer // 完整流水线
Collector → custom logic → Renderer // 智能体跳过composer
6. 窄契约
最小必需输入,最大类型安全。只接受所需内容。只返回有用内容。避免上帝对象。
typescript
// ✅ 精确获取所需内容
function resolveSyncRules(rules: UiSyncRule[], sources: string[]): ResolvedSyncRule[]
// ❌ 仅需两个字段却接收整个配置对象
function resolveSyncRules(config: FullAppConfig): ResolvedSyncRule[]
7. 就近文档
文档位于其描述的代码旁边。每个模块有自己的契约。智能体通过浏览文件树而非搜索Wiki来查找文档。
src/sync/
├── mod.ts # 公共导出
├── resolver.ts # 实现
├── resolver_test.ts # 测试即文档
└── contract.md # I/O契约、不变量(可选,用于复杂模块)
8. 测试优先的不变量
每个行为都有测试。测试是可执行的规范,智能体通过阅读测试来理解契约。优先边界测试而非快乐路径。
typescript
// 测试边界,而非仅中间路径
Deno.test(empty resources → empty descriptor, ...);
Deno.test(orphan sync target → validation error, ...);
Deno.test(broadcast rule → resolves to all-except-sender, ...);
应用AX — 决策检查清单
在发布任何模块之前,验证:
- - [ ] 智能体能否在零环境知识下调用此函数?
- [ ] 所有错误是否机器可解析(代码 + 结构化数据)?
- [ ] 使用相同输入运行两次,输出是否会变化?
- [ ] 是否存在函数签名中不可见的隐式行为?
- [ ] 能否在不导入无关模块的情况下使用此模块?
- [ ] 测试是否覆盖无效/边界输入,而非仅快乐路径?
- [ ] 代码的一级目录内是否有文档?
- [ ] 智能体是否需要阅读源代码来理解契约,还是类型+测试就足够?
CLI契约(针对CLI工具)
构建智能体将调用的CLI时:
- - 默认使用机器可读输出(JSON/JSONL),通过--human可选人类可读
- 输出中包含稳定键名(而非仅美化打印的文本)
- 一致使用退出码(0=成功,1=用户错误,2=系统错误)
- 版本化输出格式 — JSON结构的破坏性变更需要标志或迁移路径
- 为便于智能体发现,优先使用显式标志而非位置参数
详见 references/cli-contracts.md。
错误分类法
AX兼容项目的标准错误码前缀:
| 前缀 | 领域 | 示例 |
|---|
| INVALID | 输入验证 | INVALIDSYNCRULES |
| MISSING |
缺少必需数据 | MISSING
RESOURCEURI |
| ORPHAN
* | 引用不存在的实体 | ORPHANSYNC_TARGET |
| CONFLICT
* | 矛盾配置 | CONFLICTLAYOUT_CHILDREN |
| UNSUPPORTED
* | 有效但未实现 | UNSUPPORTEDLAYOUT |
采用此分类法或定义自己的分类法 — 关键在于项目内的一致性。