
1. 策略复盘为什么需要 DataAgent做过运营或者数据策略的人都有一个共同的痛点复盘这件事说起来重要做起来次要忙起来不要。不是大家不想复盘而是复盘的链路太长了。一次完整的策略复盘通常要经历数据提取、指标计算、维度拆解、归因分析、结论输出这么几个环节每个环节都依赖不同的人、不同的工具、不同的口径。等到所有数据凑齐黄花菜都凉了业务节奏早就跑到下一个阶段去了。我在实际工作中观察到一个很典型的现象策略团队每周花在复盘上的时间至少有百分之六十消耗在“找数”和“对数”上真正用于思考策略为什么有效、为什么失效的时间少得可怜。这个比例是极其不健康的。DataAgent 要解决的核心问题就是把这百分之六十的机械劳动压缩到百分之十以内让策略同学把精力重新放回到判断和决策上。所谓 DataAgent你可以把它理解成一个“懂数据、懂业务、能自己动手干活”的智能体。它不是简单的报表工具也不是传统意义上的 BI 看板。报表和看板是被动的你问什么它答什么你不问它就静静躺着。DataAgent 是主动的你给它一个复盘目标它会自己规划路径先查哪张表、再算什么指标、发现异常后往哪个维度下钻、最后怎么组织结论。这个“自己规划”的能力就是 Agent 和传统工具最本质的区别。具体到货拉拉这个场景策略复盘涉及的对象非常复杂。平台上有乘客侧的策略、司机侧的策略、定价策略、调度策略、补贴策略每一条策略线背后都挂着几十个指标。如果靠人工一条条去拉一个策略的完整复盘至少需要半天。而 DataAgent 的目标是把这个过程压缩到分钟级并且保证口径统一、逻辑可追溯。这篇文章适合三类人看。第一类是做数据策略、运营策略的同学你们会看到一套可以直接借鉴的复盘自动化思路。第二类是做数据工程、Agent 开发的同学你们会看到 Workflow 编排、工具调用、上下文管理这些工程细节怎么落地。第三类是对 Agent 应用感兴趣但还没动手的人你们会看到一个真实业务场景下 Agent 是怎么被拆解和实现的而不是停留在概念层面。2. 整体架构设计与思路拆解2.1 为什么选择 Agent 而不是固定报表在动手之前我们认真评估过几条路线。第一条路线是做一套固定的复盘报表把常用指标全部预计算好策略同学自己去看。这条路线的优点是稳定、快、成本低但缺点是僵化。策略复盘的本质是“带着假设去验证”每次复盘的切入角度都不一样。今天想看看补贴力度对完单率的影响明天想看看调度半径对司机接单时长的影响。固定报表没法覆盖这种灵活多变的探索需求最后还是会退化成“找数据同学提需求”。第二条路线是做一套自助取数工具让策略同学自己写 SQL。这条路线的优点是灵活但门槛太高。大部分策略同学的业务 sense 很强但 SQL 能力参差不齐而且就算会写 SQL也不一定清楚底表的分区规则、字段口径、数据延迟这些工程细节。结果就是取出来的数经常对不上反而增加了沟通成本。第三条路线就是 DataAgent。它的核心思路是把“取数、算数、看数、归因”这一整套动作封装成一个由大模型驱动的智能体。策略同学只需要用自然语言描述复盘目标Agent 负责把它翻译成可执行的数据操作序列一步步执行最后输出结构化的复盘结论。这条路线的优势在于它同时兼顾了灵活性和低门槛。灵活性来自大模型的推理能力低门槛来自自然语言的交互方式。当然Agent 路线也有它的问题。最大的问题是“不可控”。大模型可能会理解错意图可能会选错表可能会算错指标。所以我们在架构设计上做了一个关键取舍Agent 负责规划和编排但不负责具体计算。所有的指标计算、数据查询都下沉到预先定义好的工具函数里。Agent 的职责是决定“什么时候调用哪个工具、传什么参数”而不是“自己动手算”。这样一来计算的准确性由工程代码保证规划的灵活性由大模型保证各司其职。2.2 核心模块拆解整个 DataAgent 的架构可以拆成四层。最底层是数据层包括数仓底表、指标平台、维度字典。这一层是既有的基础设施我们不重复造轮子而是通过统一的查询接口去对接。第二层是工具层把常用的数据操作封装成一个个原子化的工具函数比如“查询某指标在某时间段的值”“按某维度拆解某指标”“计算两个指标的相关系数”等等。第三层是编排层也就是 Agent 的核心负责理解用户意图、制定执行计划、调用工具、处理中间结果。最上层是交互层提供对话式的复盘入口支持多轮追问和结果导出。这里重点说一下工具层的设计。工具层的粒度很关键。如果工具太粗比如直接封装一个“完成一次完整复盘”的工具那 Agent 就没有发挥空间了退化成脚本调用。如果工具太细比如封装一个“执行 SQL”的工具那 Agent 就要自己写 SQL又回到了不可控的老路。我们最后选择的粒度是“业务语义级”的工具比如get_metric_trend(metric_name, start_date, end_date, filters)查询指标趋势breakdown_metric(metric_name, dimension, start_date, end_date)按维度拆解指标compare_segments(metric_name, segment_a, segment_b, period)对比两个分群detect_anomaly(metric_name, start_date, end_date)检测指标异常波动correlate_metrics(metric_a, metric_b, start_date, end_date)计算指标相关性这些工具的输入输出都是结构化的Agent 只需要决定调用哪个、传什么参数。工具内部则封装了完整的查询逻辑、口径校验、异常处理。这种设计的好处是即使 Agent 规划错了最坏的结果也只是“查了一个不相关的指标”而不会“算出一个错误的数”。2.3 Workflow 编排的设计原则Agent 的执行过程本质上是一个 Workflow。但和传统的固定 Workflow 不同DataAgent 的 Workflow 是动态生成的。传统 Workflow 是“if A then B else C”路径是写死的。DataAgent 的 Workflow 是“根据当前掌握的信息决定下一步做什么”路径是运行时决定的。我们在设计编排逻辑时遵循了三个原则。第一个原则是先广后深。Agent 拿到复盘目标后先做一轮宽泛的扫描看看哪些指标有异常、哪些维度有分化然后再针对异常点做深入下钻。这样做的好处是避免一上来就陷入细节错过全局性的问题。第二个原则是假设驱动。Agent 在扫描阶段会形成若干假设比如“完单率下降可能是因为补贴力度降低”然后针对每个假设去验证。验证通过的假设进入结论验证不通过的假设被排除。第三个原则是可中断可追问。Agent 在执行过程中如果发现信息不足或者存在歧义会主动向用户提问而不是自己瞎猜。用户也可以在任何时候打断调整复盘方向。这三个原则说起来简单落地的时候有很多细节要处理。比如“先广后深”的“广”到底多广我们的做法是Agent 首先会拉取复盘周期内所有核心指标的概览然后计算每个指标的环比、同比、波动率把波动超过阈值的指标标记为“异常候选”。这个阈值不是拍脑袋定的而是基于历史数据的统计分布来动态计算的。具体来说我们取过去九十天该指标的日度波动率计算其均值和标准差把超过均值加两倍标准差的波动定义为异常。这个规则在大部分指标上都表现良好既不会太敏感导致天天报警也不会太迟钝导致漏掉真实异常。3. 核心细节解析与实操要点3.1 意图理解把自然语言翻译成数据任务Agent 的第一步是理解用户想干什么。用户可能会说“帮我看看上周补贴策略的效果”也可能会说“最近完单率掉了帮我查查原因”。这两句话背后的数据任务是完全不同的。前者是效果评估需要对比策略前后的指标变化后者是归因分析需要拆解指标下降的贡献来源。我们在意图理解这一层做了两件事。第一件事是意图分类。我们把策略复盘常见的意图分成几类效果评估、归因分析、趋势监控、分群对比、异常排查。每一类意图对应一套预定义的执行模板。Agent 首先要判断用户的话属于哪一类意图然后再套用对应的模板。第二件事是槽位填充。每个模板都有若干必填槽位比如效果评估需要“策略名称、评估周期、核心指标”归因分析需要“目标指标、分析周期、候选维度”。Agent 要从用户的话里提取这些槽位提取不到的就要主动追问。这里有一个实操中的坑值得分享。最初我们试图让大模型一次性完成“意图分类加槽位填充”结果发现准确率不稳定。后来我们把它拆成两步先做意图分类再做槽位填充。意图分类的 prompt 里只放意图定义和几个示例槽位填充的 prompt 里只放当前意图的槽位定义和用户原话。拆开之后每一步的准确率都明显提升。这个经验在很多 Agent 场景下都适用不要让大模型一次做太多事把复杂任务拆成多个简单任务每个任务单独调一次模型整体效果反而更好。3.2 工具调用的参数构造Agent 决定调用某个工具之后下一步是构造参数。这一步看起来简单实际上很容易出错。比如用户说“看看上周的完单率”Agent 需要把“上周”翻译成具体的日期范围。这里涉及两个问题一是“上周”的定义是自然周还是滚动七天二是时区问题数据是按什么时区统计的我们的做法是在工具层之上加一层参数规范化。所有涉及时间的参数都统一转换成“开始日期、结束日期”的格式并且明确标注时区。所有涉及指标名称的参数都通过指标字典做一次映射把用户的口语化表达比如“完单率”映射到指标平台的标准名称比如“order_completion_rate”。所有涉及维度的参数同样通过维度字典做映射。这层规范化还有一个作用就是参数校验。如果 Agent 传了一个不存在的指标名或者一个超出数据范围的日期规范化层会直接拦截并返回错误信息而不是让工具去执行一个注定失败的查询。错误信息会返回给 AgentAgent 可以根据错误信息调整参数重新调用。这种“失败即反馈”的机制是 Agent 自我纠错能力的基础。3.3 上下文管理与记忆Agent 在执行复盘任务时会产生大量的中间结果。比如查了十个指标的趋势每个指标返回三十天的数据这就是三百个数据点。如果把这些全部塞进大模型的上下文很快就会超出窗口限制而且会稀释关键信息。我们的做法是分层记忆。第一层是原始数据层所有工具返回的原始结果都存在这里不直接进大模型上下文。第二层是摘要层每个工具返回结果后会生成一个简短的摘要比如“完单率在过去七天从百分之八十五下降到百分之七十八下降七个百分点主要下降发生在周三和周四”。只有摘要层的内容会进大模型上下文。第三层是结论层Agent 在每个阶段结束时会把当前阶段的发现凝练成一两句结论存入结论层。后续的推理主要基于结论层需要细节时再回查摘要层或原始数据层。这种分层记忆的设计灵感来自人做复盘时的思维过程。我们不会记住每一个数据点而是记住“哪个指标出了问题、大概什么时候出的、可能是什么原因”。需要确认细节时再回去翻原始数据。Agent 的记忆管理也应该遵循同样的逻辑。3.4 结果输出的结构化复盘结论的输出格式很重要。如果 Agent 返回一大段文字用户很难快速抓住重点。我们的做法是强制 Agent 按照固定结构输出包括复盘结论、关键发现、数据支撑、后续建议四个部分。复盘结论是一句话总结比如“上周补贴策略对完单率有正向影响但影响幅度低于预期”。关键发现是三到五条要点每条要点都要有数据支撑。数据支撑部分列出具体的指标数值和变化。后续建议部分给出可操作的下一步动作。这里有一个细节我们要求 Agent 在输出数据支撑时必须标注数据来源和口径。比如“完单率数据来自指标平台口径为当日完成订单数除以当日发单数统计时区为北京时间”。这样做是为了让复盘结论可追溯、可验证。策略同学看到结论后如果觉得哪里不对可以顺着数据来源去核查而不是只能选择相信或不信。4. 实操过程与核心环节实现4.1 环境准备与依赖梳理动手搭建之前先把依赖理清楚。DataAgent 的运行依赖三类资源。第一类是模型资源需要一个支持函数调用的大模型接口。我们选型时重点看三个指标函数调用的准确率、长上下文的稳定性、响应延迟。函数调用准确率决定了 Agent 能不能正确选择工具长上下文稳定性决定了能不能处理复杂的多轮复盘响应延迟决定了用户体验。第二类是数据资源包括数仓的连接权限、指标平台的查询接口、维度字典的读取权限。第三类是运行环境包括 Python 运行环境、依赖包管理、日志和监控。这里重点说一下模型选型的经验。我们测试过多个模型发现不同模型在函数调用上的表现差异很大。有的模型在简单场景下表现很好但一旦工具数量超过十个选择准确率就明显下降。有的模型对中文业务术语的理解更好但函数调用的格式经常出错。最后我们选择的方案是主模型加备用模型。主模型负责复杂的规划和推理备用模型负责简单的意图分类和参数提取。这样既保证了复杂场景的效果又控制了成本。4.2 工具函数的实现细节工具函数是整个系统的基石它的质量直接决定了 Agent 的上限。我们以get_metric_trend为例说一下实现细节。def get_metric_trend(metric_name, start_date, end_date, filtersNone): 查询指标趋势 metric_name: 标准指标名如 order_completion_rate start_date: 开始日期格式 YYYY-MM-DD end_date: 结束日期格式 YYYY-MM-DD filters: 过滤条件字典格式如 {city: 上海, driver_level: A} # 第一步参数校验 validate_metric(metric_name) validate_date_range(start_date, end_date) # 第二步口径解析 metric_config load_metric_config(metric_name) # 第三步查询构造 query build_query(metric_config, start_date, end_date, filters) # 第四步执行查询 raw_data execute_query(query) # 第五步结果格式化 result format_trend_result(raw_data, metric_config) # 第六步生成摘要 summary generate_summary(result) return {data: result, summary: summary}这个函数看起来简单但每一步都有讲究。参数校验确保输入合法避免无效查询。口径解析从指标平台加载指标的定义确保不同工具用的是同一套口径。查询构造根据指标配置生成 SQL屏蔽了底表差异。结果格式化统一了输出格式方便 Agent 消费。摘要生成是给大模型看的用自然语言描述趋势变化。实操心得工具函数的返回值一定要包含“摘要”字段。大模型直接读原始数据容易迷失读摘要则能快速抓住重点。摘要的生成规则可以很简单比如“指标从 X 变化到 Y变化幅度 Z”但一定要有。4.3 编排循环的实现Agent 的核心是一个循环观察当前状态、决定下一步动作、执行动作、更新状态。这个循环用伪代码表示大概是这样的def run_agent(user_query, max_steps20): context init_context(user_query) for step in range(max_steps): # 决定下一步 action decide_next_action(context) # 如果 Agent 认为可以结束了就退出循环 if action.type finish: break # 如果 Agent 需要用户补充信息就暂停 if action.type ask_user: return ask_user(action.question) # 执行工具调用 result execute_tool(action.tool_name, action.params) # 更新上下文 context update_context(context, action, result) # 生成最终结论 conclusion generate_conclusion(context) return conclusion这个循环的关键在于decide_next_action。它的输入是当前上下文输出是一个动作。动作有三种类型调用工具、询问用户、结束。decide_next_action的实现方式是把上下文和可用工具列表一起塞给大模型让大模型输出下一步动作。这里有一个技巧在 prompt 里明确告诉大模型当前处于哪个阶段。比如“当前处于扫描阶段请优先选择能覆盖多个指标的工具”或者“当前处于下钻阶段请针对已发现的异常指标选择拆解工具”。阶段信息能显著提升大模型决策的合理性。4.4 一个完整的复盘案例假设用户输入“帮我复盘一下上周上海地区的补贴策略效果。”Agent 的执行过程大致如下。第一步意图识别为“效果评估”槽位填充为策略名称等于补贴策略、地区等于上海、周期等于上周。第二步Agent 调用get_metric_trend查询核心指标完单率、应答率、司机在线时长在上周的趋势。第三步Agent 发现完单率在上周后半段有明显下降触发异常检测。第四步Agent 调用breakdown_metric按城市、司机等级、时段拆解完单率发现下降主要集中在上海郊区的低等级司机群体。第五步Agent 调用compare_segments对比补贴策略覆盖和未覆盖的司机群体发现覆盖组的完单率下降幅度小于未覆盖组。第六步Agent 综合以上发现输出结论补贴策略对完单率有正向作用但覆盖范围不足郊区低等级司机未被充分覆盖建议扩大补贴覆盖范围。整个过程 Agent 调用了大约八到十次工具耗时在三十秒左右。如果靠人工完成同样的复盘至少需要半天。这个效率提升是数量级的。5. 常见问题与排查技巧实录5.1 Agent 选错工具怎么办这是最常见的问题。Agent 面对十几个工具有时候会选一个看起来相关但实际上不对的工具。比如用户想查“完单率”Agent 却调用了查询“发单量”的工具。排查思路分三步。第一步看意图识别是否正确。如果意图识别错了后面的工具选择肯定错。第二步看工具描述是否清晰。工具描述是 Agent 选择工具的唯一依据如果描述含糊Agent 就容易选错。第三步看上下文是否提供了足够的信息。有时候 Agent 选错工具是因为它不知道当前处于哪个阶段。解决方法和排查思路对应。意图识别的问题通过优化意图分类的 prompt 和增加示例来解决。工具描述的问题通过重写工具描述来解决。我们的经验是工具描述要包含三个要素这个工具做什么、什么时候用、输入输出是什么。比如breakdown_metric的描述是“按指定维度拆解指标用于分析指标的构成和分化输入指标名和维度名输出各维度的指标值”。这样的描述比“拆解指标”清晰得多。5.2 数据口径不一致怎么处理策略复盘最怕口径不一致。同一个指标不同的人算出来不一样复盘结论就失去了可信度。DataAgent 处理口径问题的核心思路是单一数据源。所有指标的定义都来自指标平台Agent 不自己定义指标也不允许用户在对话中临时定义指标。如果用户问了一个指标平台上没有的指标Agent 会明确告知“该指标未在指标平台注册请先确认口径”。注意不要为了灵活性而允许 Agent 临时计算指标。临时计算意味着口径不受控今天算出来一个数明天算出来另一个数复盘就没法做了。宁可少支持一些指标也要保证支持的指标口径统一。5.3 多轮对话中上下文丢失多轮复盘时用户可能会追问“那再帮我看看司机侧的情况”。这时候 Agent 需要记住上一轮在分析什么策略、什么周期、什么地区。如果上下文管理没做好Agent 就会丢失这些信息重新问一遍。我们的解决方案是在上下文中维护一个会话状态记录当前复盘的策略、周期、地区、已发现的异常、已排除的假设。每次用户输入新指令时Agent 先把新指令和会话状态合并再决定下一步动作。会话状态是结构化的不是一大段文字这样既节省上下文窗口又方便程序处理。5.4 常见问题速查表问题现象可能原因排查方法解决方案Agent 选错工具工具描述不清或意图识别错误检查意图分类结果和工具描述优化 prompt重写工具描述数据对不上口径不一致或时区错误核对指标定义和统计时区统一数据源强制口径校验多轮对话丢失上下文会话状态未持久化检查上下文管理逻辑维护结构化会话状态Agent 陷入循环工具返回结果无法推进推理查看执行日志定位循环点设置最大步数增加循环检测响应太慢工具查询耗时或模型推理慢分别计时工具调用和模型调用优化查询缓存常用结果结论太空泛摘要生成质量差检查摘要是否包含具体数值优化摘要生成规则5.5 独家避坑技巧第一个技巧给 Agent 设置“止损点”。Agent 在执行过程中如果连续三次工具调用都没有获得有效信息就应该停下来向用户求助而不是继续瞎试。我们在实现中加了一个计数器连续无效调用超过阈值就触发人工介入。第二个技巧工具返回结果要带“置信度”。有些查询可能因为数据延迟或分区缺失而不完整这时候工具应该在返回结果中标注置信度。Agent 看到低置信度的结果可以选择重新查询或者提示用户。这个机制能有效避免基于不完整数据得出错误结论。第三个技巧定期回放历史复盘。我们每周会抽取几条历史复盘记录人工检查 Agent 的推理链路是否合理。这个习惯帮我们发现了不少隐蔽的问题比如某个工具在特定日期范围内会返回空结果导致 Agent 误判为“指标为零”。回放机制是持续优化 Agent 的重要手段。6. 后续可以扩展的方向DataAgent 在策略复盘这个场景跑通之后我们也在思考它还能用到哪些地方。一个自然的方向是实时监控。现在的复盘是事后分析如果把 Agent 接到实时数据流上它就能在指标异常发生的第一时间发出预警并自动生成初步的归因分析。另一个方向是策略推荐。Agent 在复盘过程中积累了大量“什么策略在什么场景下有效”的知识这些知识可以反过来用于新策略的生成和推荐。还有一个方向是多 Agent 协作。现在的 DataAgent 是单 Agent 架构一个 Agent 负责从头到尾。未来可以拆成多个专职 Agent比如一个负责数据查询、一个负责归因分析、一个负责结论生成它们之间通过消息传递协作。这样做的好处是每个 Agent 的职责更单一prompt 更简单整体稳定性可能更高。我在实际使用中最大的体会是Agent 的价值不在于它有多智能而在于它能把人从重复劳动中解放出来。策略同学的时间应该花在判断“这个结论合不合理”“下一步该做什么”上而不是花在“怎么把数据拉出来”上。DataAgent 做的就是把后面这部分工作接过去让人专注于前面那部分。这个定位想清楚了很多设计取舍就自然清晰了。