文章标题:Show HN: Attest——测试 AI 智能体做了什么,而不只是它们说了什么
正文: Attest 1.1.0 是一个面向 AI 智能体的测试框架,支持 Python 和 TypeScript。用 pytest 或 Vitest 检查一条回复、一串工具调用或外部状态的变更。从确定性检查开始;只有当这些检查无法表达某些标准时,才加入模型评判。
rec → replay → gate
一个客服智能体在支付超时后向客户重复退款了两次。它仅检查输出的测试却始终保持通过。这起合成事故——INC-1042——通过三步变成一个回归测试:
捕获事故
attest capture 记录调用轨迹和模型交互,应用脱敏处理,并根据本次运行草拟契约。一个标记为与录制内容一致的 fixture 并不能证明行为是正确的:请审查该 fixture,并选择独立的业务不变量。
在 CI 中回放
严格回放会让你的智能体真实代码通过本地代理,对录制好的模型响应运行,对匹配的请求零实时模型调用。它消除的是实时模型带来的波动性,而非其他导致测试不稳定的来源;工具依赖和测试隔离仍需控制。
把关合并
检查会报告通过、失败或 not_evaluated,并附上原因。失败的测试默认阻断(tests_failed: block);not_evaluated 会发出警告,除非策略设置了 not_evaluated: block。在分支保护中要求该策略检查。这道关卡覆盖你提供的契约和基线,而不是所有可能的回归。
导览沿着双重退款账本、已审查的契约、被阻止的回滚 PR、变异分数和 HTML 查看器展开。其输出展示的是合成演示;演示 README 中有当前可执行的演练。
expect(trace).tool_cardinality("issue_refund", per="order_id", at_most=1)
attestExpect(trace).toolCardinality("issue_refund", { per: "order_id", atMost: 1 });
一行行为契约就陈述了 INC-1042 违反的规则——针对的是调用轨迹中的工具调用,而不是回复文本。
六个评估层加上插件
回放和把关运行在确定性检查之上。这些层是契约或测试可以使用的完整检查阶梯,从免费且即时到由 LLM 评判。插件可添加你自己的断言。该表由 attest-engine capabilities --json 生成。
它长什么样
Python
from attest import agent, expect
@agent("weather-agent")def weather_agent(builder, query: str) -> dict: # Recorded sample data: no model or weather API is called. builder.add_tool_call( "get_weather", args={"city": "Tokyo"}, result={"temperature_c": 22, "conditions": "Sunny"}, ) return { "message": "Current weather conditions in Tokyo: sunny, 22°C.", "structured": {"city": "Tokyo", "temperature_c": 22}, }
def test_weather_agent(attest): result = weather_agent(query="What's the weather in Tokyo?")
chain = ( expect(result) .required_tools(["get_weather"]) # L3, free .output_contains("Tokyo") # L4, free .output_matches_schema({ # L1, free "type": "object", "required": ["city", "temperature_c"], "properties": { "city": {"type": "string"}, "temperature_c": {"type": "number"}, }, }) ) attest.evaluate(chain)
将此保存为 test_weather_agent.py,用 uv add "attest-ai>=1.1.0" pytest 安装,然后运行 uv run pytest -v。上述每个断言都是确定性的,且不需要 API 密钥。如需语义检查,在配置好相应的嵌入或评判提供方后,添加 output_similar_to 或 passes_judge。
TypeScript
import { agent, attestExpect } from '@attest-ai/core';import { evaluate } from '@attest-ai/vitest';import { test } from 'vitest';
const weatherAgent = agent('weather-agent', (builder) => { // Sample data: no model or weather API is called. builder.addToolCall('get_weather', { args: { city: 'Tokyo' }, result: { temperature_c: 22, conditions: 'Sunny' }, }); return { message: 'Current weather conditions in Tokyo: sunny, 22°C.' };});
test('weather agent returns weather data', async () => { const result = weatherAgent({ query: 'What is the weather in Tokyo?' });
const chain = attestExpect(result) .requiredTools(['get_weather']) // Layer 3: Free .outputContains('Tokyo') // Layer 4: Free .outputNotContains('error'); // Layer 4: Free
await evaluate(chain);});
保存为 weather.test.ts,并用 npm install -D "@attest-ai/core@>=1.1.0" "@attest-ai/vitest@>=1.1.0" "vitest@^4" 安装。在运行 npx vitest run 之前,先执行一次 npx attest doctor 来下载并检查引擎:首次冷下载可能超过 Vitest 的默认超时时间。这个测试不会发起任何提供商调用。
功能
框架适配器
面向 Python 和 TypeScript 的提供商与框架适配器,每个都带有成熟度分级——下表列出了它们。
多智能体测试
Beta:追踪委派链,检查父子关系、顺序以及跨智能体的数据流。
模拟模式
Beta:使用 mock 工具、预设故障和用户画像。你的应用自身的网络调用仍然需要 mock 或回放。
持续评估
实验性:对应用 trace 采样,并通过 Slack 或 webhook 对硬失败或评分漂移发出告警。
稳定工作流包括捕获、严格回放、行为契约、世界效应以及 CI 策略和基线。概览中给出了每项功能及其成熟度分级的链接。
| Adapter | Python | TypeScript |
|---|---|---|
| OpenAI | 稳定 | 稳定 |
| Anthropic | 稳定 | 稳定 |
| Manual | 稳定 | 稳定 |
| Gemini | beta | beta |
| Ollama | beta | beta |
| LangChain | beta | beta |
| CrewAI | beta | 不可用 |
| OpenTelemetry | beta | beta |
| Google ADK | 实验性 | 不可用 |
| LlamaIndex | 实验性 | 不可用 |
- beta:已发布并经过测试,但接口或行为仍可能在次版本发布中发生变化。
- 实验性:已发布,但没有稳定性承诺,也没有已验证的需求;它可能在任何版本中变更或被移除。
- 稳定:纳入一致性与符合性测试套件;行为变化即属于破坏性变更。
来自 engine 1.1.1 的 attest-engine capabilities --json。
对比
| Capability | Attest | DeepEval | Promptfoo | Ragas | LangWatch | LangSmith |
|---|---|---|---|---|---|---|
| SDK 语言 | Python 和 TypeScript | Python(pytest)和 TypeScript(Vitest) | CLI 与库;“Use Python, Javascript, or any other language” | 未评估 | Python 和 TypeScript | 未评估 |
| 页面上列出的框架与提供商集成 | 10 个 Python 适配器和 7 个 TypeScript 适配器 | Python 11 个、TypeScript 6 个,包括 LangChain、OpenAI、Anthropic、LlamaIndex、CrewAI、Google ADK | 未评估 | LangChain、LlamaIndex、“and more” | 未评估 | OpenAI、Anthropic、CrewAI、Vercel AI SDK、Pydantic AI |
| 在单元测试运行器内运行 | pytest 和 Vitest | pytest 和 Vitest | 未评估 | 未评估 | 未评估 | 未评估 |
| LLM-as-judge | 是(第 6 层) | 是(GEval) | 未评估 | 未评估 | 未评估 | 未评估 |
| 确定性断言与按层级的成本分类 | 是(第 1-4 层免费;第 5-6 层取决于提供商) | 未评估 | 未评估 | 未评估 | 未评估 | 未评估 |
| 多智能体 trace 与模拟 | 是(beta) | 未评估 | 未评估 | 未评估 | 未评估 | 未评估 |
“未评估”表示所引用的页面没有说明。一手来源,访问日期如下:
- DeepEval: https://deepeval.com/docs/getting-started(访问于 2026-11-06)
- Promptfoo: https://www.promptfoo.dev/docs/intro/(访问于 2026-11-06)
- Ragas: https://docs.ragas.io/en/stable/(访问于 2026-11-06)
- LangWatch: https://langwatch.ai/docs/introduction(访问于 2026-11-06)
- LangSmith: https://docs.langchain.com/langsmith/observability.md(访问于 2026-11-06)
开始使用
图表:Terminal window
# Pythonuv add "attest-ai>=1.1.0" pytest
# TypeScriptnpm install -D "@attest-ai/core@>=1.1.0" "@attest-ai/vitest@>=1.1.0" "vitest@^4"npx attest doctor
完整演练请参阅 Python quickstart 或 TypeScript quickstart。