2026年8月14日 1 分钟阅读

Eva 实战:把 AI 对话先写成可查询事件,再把它接进脚本流水线

tinyash 0 条评论

终端里的 AI 聊天工具通常把注意力放在“回答得更快”上:提示词发出去,流式文本显示出来,历史记录则是一个附加功能。Eva 反过来选择了更严格的顺序:问题、输出、重试和 token 用量先追加到本地 Trace,终端界面只读取这份记录再显示。它是 Missing studio 在 2026 年 8 月发布的 MIT 许可 Go 项目;当前仍处于早期阶段,官方明确说明它还没有文件、shell 或测试工具。

这个边界很重要。不要把 Eva 当成能替代 Claude Code、Codex 一类编程 Agent 的工具:它现阶段是一个“先记账、再呈现”的终端聊天客户端。恰好因为不带工具调用,它适合用来理解另一类基础能力——当模型输出要进入脚本、审计、成本分析或之后的 Agent 平台时,怎样避免把瞬时屏幕文本误当成唯一事实来源。

问题不在聊天记录,而在可复核性

普通终端程序可以把一段回答打印到 stdout,但后续系统仍会遇到三个问题:这段文本对应哪个提问?模型是否中途失败或重试?token 用量和缓存读写分别是多少?如果这些信息散在 UI 状态、日志和调用方脚本里,后续很难还原一次运行的完整边界。

Eva 的做法是将每次交互写入 ~/.eva/trace.jsonl。官方教程把它描述为按事件追加的 JSONL 流:一次运行会出现 startedtextusagefinished 等记录;界面上的转录内容是这串事件的 fold(折叠结果),而不是另一份单独维护的会话真相。

这不是“多存一个日志文件”的小差异。事件中含有运行、会话、父级关联和序号等信息,因而调用方可以从同一份数据里重新构建对话、筛选失败、计算用量,或者关联未来的子任务。官方示例还把缓存写入和缓存读取 token 分开保存;两者价格可能不同,不能为了好看合并成一个数字。若提供商没有返回推理 token 或美元成本,字段应保持未报告状态,而不是填成 0。

从本地构建到第一条可验证 Trace

Eva 支持 macOS 的 Homebrew、安装脚本和 Go 安装;想直接检查源码并构建,可以使用官方教程中的路径。项目要求 Go 1.26 或更高版本:

git clone https://github.com/missingstudio/eva.git
cd eva
go build -o eva ./cmd/eva

export ANTHROPIC_API_KEY="${ANTHROPIC_API_KEY}"
./eva

Anthropic 是默认提供商。若使用 OpenAI,官方 README 的路径是先执行 eva init 生成配置,再在 ~/.eva/config.toml 选择 provider;有 ChatGPT 或 Codex 订阅时,也可以通过 eva login 登录,并用 eva auth status 查看实际采用的认证方式。这里不应把密钥写进项目配置或命令历史。

在交互界面里发出一个问题,再输入 /cost,可以看到会话累计用量。退出后,先别急着相信屏幕上的汇总,直接检查 Trace:

wc -l ~/.eva/trace.jsonl
jq -r '.kind' ~/.eva/trace.jsonl
jq 'select(.kind == "started") | .payload.intent' ~/.eva/trace.jsonl

最后一条命令会取出每次运行记录中的原始意图。这个最小验证比“我看见回答了”更有价值:它证明提问和后续输出确实被落在同一个可读取的事件流中。生产环境还应为 JSONL 设置轮转、备份和访问控制;提示词、输出和元数据都可能含有内部代码或业务信息,本地优先不等于无需治理。

让 AI 输出成为流水线里一个会失败的步骤

Eva 的 -p 参数适合非交互调用:它把回答写到 stdout 后退出;失败时退出码非零,错误原因写到 stderr。这个约定避免了半截回答悄悄流入下一步。一个审阅暂存 diff 的例子如下:

git diff --staged | ./eva -p "为这份差异拟一条 Conventional Commit 提交信息" > commit-message.txt
status=$?

if [ "$status" -ne 0 ]; then
  echo "Eva 请求失败,停止后续提交流程" >&2
  exit "$status"
fi

cat commit-message.txt

不要把它理解为“自动提交”。这里的职责仅是生成候选文本;脚本先以退出码决定是否继续,人再检查 commit-message.txt 的准确性。对于需要机器可读结果的场景,官方建议读取 Trace,而非假设 -p 的自然语言 stdout 是结构化 API。换言之,stdout 是给管道的答案表面,Trace 才是保存事件上下文的材料层。

另一个容易忽略的边界是项目配置。eva init 会写出带注释的起始配置;仓库也可以包含 .eva/config.toml 来共享颜色和快捷键,但官方说明有 allow-list 限制它能改变的范围。团队把 AI 工具配置提交到 Git 时,应像审查 CI 配置一样审查它:明确允许哪些视觉与交互项,绝不让配置顺手变成凭据载体或隐式执行入口。

适用场景与不适用场景

Eva 适合三种起点。第一,团队想要一个本地可检查的对话/用量事件源,而不是只依赖终端滚屏。第二,脚本需要一个能明确失败的单次文本生成步骤。第三,正在设计更完整的 Agent 平台,想先验证 Trace、预算和审计数据模型,而不是一开始就把文件读写和外部操作交给模型。

它暂时不适合需要直接修改仓库、运行测试、浏览网页或调用 MCP 工具的自动化任务;官方 README 已明确这些工具能力尚未实现。也不应把本地 JSONL 直接视为企业级审计系统:多租户隔离、保留策略、加密和集中查询都仍是调用方要补齐的工程工作。

真正值得借鉴的是它的顺序:先定义什么事件发生过,再决定 UI 怎么显示、脚本怎么消费。无论以后换成哪家模型或给 Agent 加多少工具,只要运行记录、失败原因和资源用量仍可独立读取,工程团队就不会只能根据一段“看起来完成了”的文本做判断。

从终端 Trace 走向 Agent 系统前,先补齐哪些约束

Eva 的设计文档把 Trace 放在更长的工程链路里:模型、工作流、Agent、带验证器的环境、Harness、调度器与规格、软件工厂,最终才可能走向更高层的自动化。即使不接受这套阶段划分,其中的依赖关系仍值得采用:先有能判断结果的验证器,才有资格把更多控制权交给 Agent;先有预算、超时和权限边界,才谈得上并行调度。

因此,若准备把上面的单次问答接到 CI、工单或代码生成流中,建议增加四层外部约束,而不是只增加提示词:

  1. 输入边界:只把必要的 diff、报错或脱敏片段传给 eva -p。不要将 .env、生产配置和未审查的网页内容混在同一提示中。
  2. 结果验证:把模型生成的提交信息、说明文本或分类结果当作候选值;由 lint、测试、JSON Schema 或人工审阅决定能否进入下一步。模型输出成功不等于业务动作已经获准。
  3. 幂等与关联:调用方为每次任务保存自己的任务 ID,并将它与 Trace 中的运行记录、输入版本和产物路径关联。网络超时后先查询已有结果,再决定是否重试,避免同一变更被重复处理。
  4. 权限与成本:将 API key 放在运行环境的密钥管理中,为单次任务设置输入大小、超时和预算上限。Trace 能帮助解释用量,却不会自动替调用方阻止无限重试或越权发布。

这些规则也解释了为什么“没有工具”在早期不是纯粹的缺陷。工具调用会引入文件系统、网络和 shell 副作用;一旦把副作用放进流程,就必须同时回答谁授权、如何拒绝、失败后是否可恢复、怎样留下证据。先把纯文本运行的事件模型跑通,再把外部动作接在一个可审查的边界后面,通常比一开始就追求全自动更可靠。

在日常开发中,可以把 Eva 放在低风险的辅助位置:生成差异摘要、解释测试失败、起草提交信息,或验证团队是否需要更系统的 Trace 格式。等到输出开始触发部署、写数据库或修改权限时,应切换到具备明确审批、隔离执行和审计能力的工作流,而不是把一个聊天客户端的成功退出码扩大解释成授权凭证。

相关链接

发表评论

你的邮箱地址不会被公开,带 * 的为必填项。