实现回顾智能体:工作原理
原文由 Alex O'Callaghan 于 发布,订阅该博客
在上一篇博文中,我阐述了我们为何要度量工程时间的去向,以及一个小型 LLM 智能体如何帮助将这类度量融入团队的 Sprint 回顾会中。几个月后,我们已在各团队中推广了该智能体,它引发了一些以往不会出现的讨论。
本文将重点介绍该智能体的工作原理、数据的接入方式以及提示词的演进过程。至于底层的度量数据平台,包括 DORA 指标是如何推导的,将在下一篇中单独介绍。
概述
该智能体会从我们的效能度量数据平台中拉取指标和活动数据,并生成一份会前阅读用的回顾报告,用于总结本次 Sprint 并给出可能的讨论要点。
我们不会把所有原始数据一股脑塞给模型,而是为智能体提供横跨三个 Sprint 的指标摘要,并为其配备可查询具体工单、合并请求和失败发布详情的工具。
智能体设计
初始提示词
初始提示词汇总了三个 Sprint 的指标,并分别为其打上 [BASELINE] 或 [LATEST - FOCUS SPRINT] 标签。这些指标涵盖 Jira 交付指标和 DORA 指标:
| DORA 指标 | Jira 指标 |
|---|---|
| 部署频率 | 工单与故事点完成率 |
| 变更前置时间(编码 + 评审 + 部署) | 承诺范围与 Sprint 中期范围对比 |
| 变更失败率 | 结转 |
| 服务恢复时间 | 周期时间 |
所有指标均由数据平台通过确定性代码计算得出,我们不会让模型尝试基于原始数据自行计算。提示词对此有明确说明:“指标摘要具有权威性,请勿尝试重新计算或质疑其结果”。
摘要中还包含一份异常工单和合并请求清单(例如周期时间或前置时间超过 75 分位数的项),以及当前聚焦 Sprint 中所有失败发布的列表。智能体被要求以这些清单作为分析的起点。工单在正文中以 KEY (16.8d, 3.0SP) 的形式呈现,合并请求则为 project!iid (308.7h: coding 116.3h, review 170.0h, deploy 22.4h)。
查询工具
我们在 PydanticAI 智能体上注册了三个工具,供其查询详情:
@agent.tool
def lookup_jira_ticket(ctx: RunContext[AgentDeps], ticket_key: str) -> str:
"""Look up a Jira ticket by its key (e.g. PROJ-1363).
Returns summary, status, assignee, story points, sprint, dates, cycle time,
and full status transition history.
"""
@agent.tool
def lookup_merge_request(ctx: RunContext[AgentDeps], query: str) -> str:
"""Search merge requests by title substring, Jira key, or MR reference (e.g. !1049).
Returns up to 10 matching MRs with title, author, dates, lead time, and release info.
"""
@agent.tool
def lookup_failure(ctx: RunContext[AgentDeps], query: str) -> str:
"""Search detected failed releases by tag, project name, evidence, or alert tiny id.
Returns up to 10 matching failures with signal (alert/revert), evidence,
resolution time, and correlated alert detail where available.
"""这些 docstring 同时也是模型据以推理的 schema,而返回的数据则是智能体构建叙事的起点。工单会返回完整的 status_history,以可读的状态流转链形式呈现(例如“In Progress → Code Review → Awaiting Release → Done”),有助于识别那些在“Blocked”状态间反复横跳的工单。合并请求则会返回编码/评审/部署各阶段的时间拆分及其所属的发布,有助于发现合并请求之间的共性模式及其对发布周期的影响。
系统提示词鼓励智能体主动使用这些工具:“主动使用这些工具……在得出结论前先去查证”。
输出结构
智能体的输出类型就是普通字符串——没有结构化输出 schema,也没有后处理。唯一约束报告形态的是提示词中的任务定义:在三个固定标题 Sprint Summary、Notable Trends、Retrospective Talking Points 下,分别给出对最新 Sprint 的简要总结、2 至 4 条相较于基线的显著趋势(“包括正面和负面的”),以及 3 至 5 个具体的讨论要点或讨论问题。
将趋势限定为 2 至 4 条、讨论要点限定为 3 至 5 条,迫使内容必须有所取舍;而将第三部分设计为问题而非结论,则有助于让报告保持“会前材料”而非“定论”的定位,相信团队拥有完整的上下文来解读趋势并决定应对措施。
一次典型的运行
下图展示了一次典型的智能体运行过程。摘要中点名了 11 个工单和合并请求,智能体并行发起了 11 次查询以获取所需详情。报告在一次 LLM 调用中生成,输出为包含三个部分的 Markdown 报告。
这些查询为报告补充了更多细节。周期时间最差的异常项(16.8 天)实际上跨越了两个 Sprint,其对应的合并请求从首次提交到发布耗时 308.7 小时(其中编码 116.3 小时、评审 170.0 小时、部署 22.4 小时)。另一个合并请求在其 99.7 小时的总时长中,有 99.5 小时都耗在了评审环节。
报告指出瓶颈在于评审延迟(中位数 58 小时,约为上一个 Sprint 的三倍),而非部署,并能具体指向可供讨论的工单/合并请求。报告还指出发布次数从 23 次降至 6 次,同时变更失败率从 8.7% 降至 0,并提出问题:这种变慢的交付流是刻意的风险管控,还是仅仅因为变更在评审环节排队积压所致。
整个运行过程共调用 LLM 两次:约 11,400 个输入 token(其中三分之一在第二次调用时为缓存读取)和 2,200 个输出 token。按撰写本文时 GPT-5.4 的 API 定价计算,总成本约为 0.05 美元,其中大部分来自输出 token。
实践中的提示词工程
不要点名工程师
在最初的原型中,智能体在讨论进展较慢的工单时经常会直接点出工程师的姓名。为了维护无指责的回顾氛围,我在提示词中加入了一道护栏来避免这种情况。智能体被要求聚焦于团队整体的趋势和工作本身,而非个人表现。
这一点也可以通过确定性的评估来保障。该评估会从输入中提取所有经办人和合并请求作者,若其中任何一个出现在输出中即判定为不通过。提示词与评估共同强制执行这一规则。
Schema 也是提示词的一部分
智能体会基于你的字段名进行推理,因此命名至关重要。早期版本会基于 Jira 的 status_category 字段误判工单的状态以及是否已完成。在工单 schema 中增加一个布尔字段 is_done 后,这一问题得以解决——通过确定性逻辑和数据结构来编码语义,而不是依赖模型去解读含义模糊的字段名或取值。
结构胜于指令
尽管产出物本质上是假设,提示词中却从未使用“假设”一词。第三部分是讨论要点和讨论问题,而非结论。回顾会应由人来主导,报告的格式本身就体现了这一点,而不是要求模型去记住它。
最初的提示词还会要求生成一个一目了然的关键指标汇总表,但模型每次生成的表格格式都不一样。通过在智能体之外构建一个 Web 界面,汇总表变成了一个与生成式叙述并列的确定性组件。如果某部分输出每次都应该保持一致,就不要让 LLM 来生成它。
结语
回顾智能体对我们的团队来说是一个小而有用的工具,有助于在工程回顾会上激发讨论与反思。它展示了如何通过提示词工程和查询工具,打造一个既尊重团队协作氛围、又聚焦于可落地洞察的 AI 助手。
其实用性的很大一部分来自底层的度量数据平台,它为智能体提供了权威的数据基础。这需要在度量什么、以及如何从研发工作流中计算这些指标上做出审慎的选择。在下一篇博文中,我将深入介绍该平台的工作原理、我们如何推导 DORA 指标,以及它们如何协同支撑我们的工程团队。
随机一篇博客
评论
登录后参与讨论