开源 · Apache 2.0 · Java 17+
代码即日志。
别再写日志语句了。
NarrativeTrace 把运行中的代码变成可读的叙事:给调试者看的执行追踪、给写代码的 AI 代理用的无值结构化追踪,以及一条在行为漂移时让构建失败的基线。
implementation("ai.narrativetrace:narrativetrace-core:0.1.0")
# Customer places order- OrderService.placeOrder("C-42", qty: 5) — 4.2ms - Customers.verifyGoodStanding("C-42") → true - PricingService.calculate(5) → 49.95 - PaymentService.charge(card: [REDACTED]) → PaymentConfirmation(txId="T-9") - OrderRepository.save(Order{…}) → Order{id=ORD-1001, total=49.95} // 这一切没有写过一行日志语句。
前后对比
删掉日志,留下故事。
一个典型的服务类里,三分之一是日志语句——而它们仍然漏掉了你真正需要的那一条。 NarrativeTrace 自动捕获方法名、参数、返回值和调用结构。你已经写好的代码,就是叙事。
之前 — 到处都是日志
public Order placeOrder(String customerId, int qty) {
log.info("Placing order for {} qty {}", customerId, qty);
customers.verifyGoodStanding(customerId);
log.debug("Customer in good standing");
var price = pricing.calculate(qty);
log.info("Calculated price: {}", price);
var order = repository.save(new Order(customerId, price));
log.info("Order saved: {}", order.getId());
return order;
}
之后 — 代码即日志
public Order placeOrder(String customerId, int qty) {
customers.verifyGoodStanding(customerId);
var price = pricing.calculate(qty);
return repository.save(new Order(customerId, price));
}
// 零行日志。
// NarrativeTrace 自动捕获叙事。
生成的追踪 — Markdown、JSON、散文、时序图,以及给 AI 的无值 .nt
- OrderService.placeOrder("C-42", 5)
- Customers.verifyGoodStanding("C-42") → true
- PricingService.calculate(5) → 49.95
- OrderRepository.save(Order{…}) → Order{id=ORD-1001, total=49.95}
同一条追踪的散文版 — 用于 bug 报告、业务沟通和 LLM 上下文
The order service places an order for customer id "C-42", quantity 5:
Customers verify good standing for customer id "C-42", returning true.
The pricing service calculates for quantity 5, returning 49.95.
The order repository saves the order Order{…}, returning Order{id=ORD-1001, total=49.95}.
Returns Order{id=ORD-1001, total=49.95}.
散文的可读性,恰好等于你命名的质量。DataProcessor.process(a, b) 会渲染成
The data processor processes a: 0, b: 0:准确,却毫无用处。这正是清晰度评分存在的理由:它根据运行时叙事给每个名字打分,让代码学会讲自己的故事。
清晰度诊断 →
叙事审批测试 0.2.0 · 下一版本
测试能抓住错误的值。
叙事能抓住错误的行为。
每次运行之后,NarrativeTrace 都会把每个场景的调用结构与上一次绿色运行比较,用一行话说明变了什么。 打开审批模式,未经审批的变化(多了一次调用、少了一次调用、结果不同)会以一份可读的 diff 让构建失败,直到有人审批为止。测试是绿的,行为却变了。现在你知道了。
NarrativeTrace — Suite complete
5 scenarios recorded
Clarity: 100% high | 0% moderate | 0% low
Reports: build/narrativetrace
Since last green: 4 scenarios unchanged · 1 changed:
"Customer places order" (−1 call Customers.verifyGoodStanding)
Narrative changed against the approved baseline
src/test/narratives/OrderServiceTest/customer_places_order.approved.nt
- OrderService.placeOrder(customerId, qty) → value
- - Customers.verifyGoodStanding(customerId) → value
- PricingService.calculate(qty) → value
- PaymentService.charge(card) → value
- OrderRepository.save(order) → value
审阅 .received.nt,然后执行:./gradlew approveNarratives
每次运行后一行话
无需任何设置。每个测试本来就会写出的 .nt 文件就是上一次绿色运行的基线;测试失败时打印的是
自那以后变了什么——通常就是通往 bug 的最短路径——而不是整条追踪。
审批的是行为,不只是代码
为每个场景提交一份基线。任何改变结构的重构——你的,或者你的代理的——都会失败,直到有人审阅 diff 并运行
approveNarratives。代码 diff 是实现细节;叙事 diff 才是评审。
面向 AI 辅助开发
你的 AI 代理能读代码。
现在它还能看代码运行。
Vibe coding 一直很顺,直到出了问题——没有人,无论是人还是代理,知道运行时到底发生了什么。 NarrativeTrace 给编码代理提供事实:真实的调用树,而不是靠静态阅读拼凑出来的猜测。
运行时的事实,而非猜测
只靠源码调试的代理会推断行为——而且推断错。一条叙事追踪展示了什么运行了、按什么顺序、带着什么参数和结果。 把它贴进任何代理的上下文,或者直接附上你的 CI 已经生成的每个测试的追踪文件。
每个上下文窗口装下更多逻辑
日志语句是噪音 token。去掉它们之后,代理阅读一个服务类的成本降低 15–30%——而追踪的每一行都是信号, 因为它是从名字生成的,不是从散文生成的。
一条无法毒害代理的追踪 0.2.0
每个测试还会写出一个 .nt 结构化追踪:调用树,去掉了所有运行时的值。零提示注入面、零 PII、
只用一小部分 token——可以安全地贴给代理,或提交到仓库。安全来自构造,而不是过滤。
MCP 服务器 Pro 即将推出
Claude Code、Cursor 和 Copilot 将通过 Model Context Protocol 直接查询追踪、运行时依赖图和清晰度数据——只读, 输出级别分层,默认只给结构。
预览 MCP 设计这个网站对代理同样友好:把你的助手指向 llms.txt 或 llms-full.txt,它就能替你接入 NarrativeTrace。
面向遗留系统现代化
迁移那个没人懂的系统 — 而且有凭有据。
AI 代理让重写变得便宜;昂贵的是验证。给遗留系统套上追踪,你就得到了它真实的运行时行为——在改动之前, 以及改动之后的等价性证明。
给你真正拥有的架构拍一张 X 光
把 Java Agent 挂到一个未经修改的应用上——参考示例是一个部署在 WildFly 上、不带任何依赖的 EJB WAR,
只用一个 -javaagent 参数就完成追踪——或者直接跑你已有的 JUnit 4 套件。不改源码,不做文档考古。
证明行为没有改变
在动手之前,先把每个场景的行为固定在一份无值基线里——免费。然后比较移植或 AI 重写前后的整套追踪, 每一处差异都按风险分类 Pro。等价性不再是一种感觉,而是一份报告。
迁移差异找出最难读的代码
如果追踪读不通,说明代码在撒谎。清晰度评分根据运行时叙事给命名打分,并解释每一个分数:每个元素一条说明、
重命名建议、缩写展开(chk → check)。让你的重构——或你的代理的重构——先从最糟的角落开始。免费。
领域语言 0.2.0 · 下一版本
从真实运行中采集你的通用语言。
名字就是追踪。NarrativeTrace 把它们变成一份由团队维护、在 CI 中强制执行的活术语表——并把同一次运行 渲染成你的团队语言的散文。数据本身从不被触碰。
订单服务 为顾客编号 "C-42" 下单,数量 2:
顾客服务 按顾客编号 "C-42" 查找顾客,返回 顾客[编号=C-42, 等级=GOLD]。
库存服务 为商品编号 "SKU-KB" 预留 2 件,返回 预留记录[商品编号=SKU-KB, 数量=2]。
支付服务 向顾客编号 "C-42" 扣款,金额 179.98,返回 支付确认[交易编号=TXN-1]。
返回 订单结果[订单编号=ORD-1, 总扣款=179.98]。
El servicio de pedidos realiza un pedido para el id de cliente "C-42", cantidad 2:
El servicio de clientes busca el cliente con id de cliente "C-42", devolviendo Cliente[id=C-42, nivel=GOLD].
El servicio de inventario reserva el id de producto "SKU-KB", cantidad 2, devolviendo Reserva[id de producto=SKU-KB, cantidad=2].
El servicio de pagos cobra al id de cliente "C-42" el importe 179.98, devolviendo Confirmación de pago[id de transacción=TXN-1].
Devuelve Resultado del pedido[id de pedido=ORD-1, total cobrado=179.98].
The order service places an order for customer id "C-42", quantity 2:
The customer service finds the customer with customer id "C-42", returning Customer[id=C-42, tier=GOLD].
The inventory service reserves product id "SKU-KB", quantity 2, returning Reservation[productId=SKU-KB, quantity=2].
The payment service charges customer id "C-42" the amount 179.98, returning PaymentConfirmation[transactionId=TXN-1].
Returns OrderResult[orderId=ORD-1, totalCharged=179.98].
采集术语表
glossaryScan 从编译后的类和测试运行中,为每个仓库生成一份 glossary.json,按限界上下文划分。
定义、翻译和已弃用的同义词由你来维护;采集永远不会覆盖它们。
在 CI 中强制执行
使用了已弃用同义词的方法会在运行输出中被标记——
openAccountWithOverdraft → use openOverdraftAccount——而且
clarityCheck 可以因此让构建失败。词汇漂移是构建错误,而不是代码评审里的一句评论。
用你的语言写成的散文
整次运行读起来就是一段段句子——服务、动作、参数——用中文或西班牙语。类型名和字段名来自同一份术语表; 数据本身保持逐字节一致。简体中文和西班牙语率先发布;更多语言即将到来。
术语表与翻译后的追踪工作原理
三步得到你的第一条叙事
添加两个依赖
dependencies {
implementation(
"ai.narrativetrace:narrativetrace-core:0.1.0")
implementation(
"ai.narrativetrace:narrativetrace-proxy:0.1.0")
}
包装一个服务 — 或自动包装
var context = new ThreadLocalNarrativeContext();
var service = NarrativeTraceProxy.trace(
orderService, OrderService.class, context);
// 或者在 Spring 中:
@EnableNarrativeTrace(
basePackages = "com.example.app")
读故事
service.placeOrder("C-42", 5);
System.out.println(
new IndentedTextRenderer()
.render(context.captureTrace()));
// JUnit 5/4:每个测试都会写出
// 自己的追踪文件。
版本
给人用的免费。AI 规模化与合规付费。
边界很简单:作为开发者阅读追踪永远免费,Apache 2.0。跨运行分析、规模化的 AI 集成、团队审批流程和合规级审计是付费的。
开源版 现已可用
一位开发者需要的一切,核心零运行时依赖。
- 自动追踪:代理、Java Agent、Spring、Servlet
- 全部五个捕获级别,可在运行时切换
@Narrated、@OnError、@NotTraced注解 + 脱敏- JUnit 5 和 JUnit 4 的逐测试追踪文件:Markdown、JSON、散文、时序图
- 清晰度评分、
clarityCheck门禁与 SLF4J 桥接 - 审批测试与无值
.nt追踪 — 0.2.0 - 领域术语表、翻译后的追踪、OpenTelemetry、Micronaut — 0.2.0
Pro 抢先体验
面向团队的跨追踪分析、AI 集成与合规。
- 流程摘要与路径频率分析
- 带风险分类的迁移差异
- 运行时依赖图
- 带策略引擎的审计与 SecOps 事件
- 面向编码代理的 MCP 服务器与分层 AI 输出 — 即将推出
- 审批治理:语义 diff、PR 评审机器人、签名基线 — 规划中
完整对比见 Pro 概览。
开源构件发布在 Maven Central 的 ai.narrativetrace 之下。
集成
与你现有的技术栈无缝对接
不止 Java
一套架构,每个运行时
叙事捕获、双消费者输出和清晰度诊断——同一套设计,移植到各个平台。.NET 移植版已经能生成同样的无值 .nt 构件,所以审批基线可以在平台之间通用。
让你的代码开口说话。
五分钟得到你的第一条叙事。这个库的诞生过程中没有写过一行日志语句。