PythonTypeScript经营分析与问数

项目目录

项目简介

DB-GPT 是面向数据库和文件的数据分析 Agent 平台,可以调用 SQL 与代码工具完成计算,生成图表和报告。当前分析入口将执行结果保存为可引用产物,向模型提供受限预览;报告子代理按产物取数,缺少必要计算时交回主代理补算。

如何写进简历

店析 · 连锁门店活动复盘平台 | 场景化示例

项目描述:基于 DB-GPT,供区域运营按活动与门店对比销售、优惠及退款数据,结合活动说明生成带数据依据的复盘报告。

技术栈:Python、FastAPI、SQLAlchemy、sqlparse

主要工作:

  • 数据产物与受控预览:基于 DB-GPT 的产物捕获,将 SQL 实际返回的完整结果保存为内容哈希文件,仅向模型提供限行、限长预览;报告按产物 ID 和字段路径取数,使门店分析结果可复用、可回查。
  • 报告交接与有限补算:复用独立报告代理与共享产物状态,报告缺少计算时保存草稿并交回源产物和计算要求,由主代理在次数预算内补算,再以结果产物继续生成报告。
  • 查询约束与异常状态:复用单条只读校验与结构化执行结果,区分合法空结果、查询失败和等待超时;在 SQLite 路径传递取消信号,为报告生成提供明确的执行状态与失败原因。

面试题与回答

  1. 工具返回值如何压缩并尽量保留信息?

    展开收起

    核心回答

    DB-GPT 的数据分析与报告链路采用完整结果产物化、工具返回受限预览、报告按产物取数:sql_query 先捕获本次查询返回的全部列和行,再只展示前 50 行,并默认限制表格预览为 20,000 个字符。模型拿到 artifact_id 后,可以定位所需结果;报告渲染器从产物读取数值和表格,避免让模型把大量单元格重新抄进提示词或报告参数。

    这里压缩的是进入模型的表示,原始执行结果另行保存。预览负责识别数据,产物负责提供完整依据;缺少汇总指标时交回分析环节计算,不能从前 50 行猜全量结论。

    完整结果与两层预览分别保存什么?

    查询成功后,sql_query 将 columns、完整 rows、执行的 SQL、数据库名和耗时交给 capture_sql_execution,取得 artifact_id,然后才生成给模型看的 Markdown 表格。超过 50 行会注明总行数,过宽的表格还会触发字符截断。这两个限制独立生效:即使不足 50 行,长文本列也可能超过字符预算。查询捕获与预览源码。

    产物内部还有另一层预览。summarize_tabular_artifact 遍历完整结果,规范化为 JSON、计算 SHA-256 并写入文件,同时只保留最多 100 行、256 KiB 预算内的内联预览。SQLArtifact 保存总行数、预览是否截断、完整结果哈希及内容地址。完整文件与内联预览因此是两份不同用途的表示,不能把内联数组长度当成查询总行数。完整结果捕获源码。

    这一保存链需要当前运行挂有产物接收器;没有接收器时,捕获函数返回 None。另外,“完整”指本次查询实际返回的结果,若原 SQL 自带 LIMIT,保存它并不会补出未查询的数据。

    报告怎样只取需要的信息?

    报告子代理有自己的消息历史,通过共享的运行状态访问已捕获产物,不需要重放主代理所有分析过程。它先调用 report_evidence_manifest 查看目录,再按真实 artifact_id 请求详情;详情选择限制为每次至多 12 个产物。需要某个嵌套结果时,传入 selectors,用 field、path 定位具体字段或数组位置。

    目录和详情仍有预览预算。选择器会先从完整产物解析目标值,再对返回给模型的内容做有界预览;一次选择整张大表,仍可能被截断。因此要继续缩小读取范围,而不是把“预览没显示”解释为“结果不存在”。read_artifact_result 优先读取 artifact:// 对应文件,并检查内容哈希;这使后续取数对应此次执行保存的内容,而非重新查询数据库的最新状态。

    最终报告中的一个指标用 artifact_id 和结果路径引用,一个表格用产物 ID 与列配置表达,由渲染器读取原始行并展开单元格,模型无需逐格输出。报告代理取数约定与表格展开源码给出了这两种交接方式。

    例如一次查询返回 300 行分组统计,聊天预览只显示前 50 行。若报告需要展示全部记录,就引用保存的表格产物;若要核对后面的某一行,就按该产物的实际结构定位读取。若报告还需要一个未计算的总体比例,则通过 request_report_calculation 提交公式和输入产物 ID,让主代理补算缺失项,再继续报告,不能把预览里的局部比例当成总体比例。

    这套方法的取舍

    它不额外调用模型生成查询结果摘要,数字、列和来源由程序保存,后续读取也能沿产物回查。代价是文件存储、额外读取和产物生命周期管理;行数与字符预算也不能代替整次请求的 Token 预算。预览适合判断结构和选择证据,全量统计仍应在完整结果上由查询或程序完成。验证时应覆盖关键记录在第 50 行之后、少行宽表、空结果和读取文件缺失等情况,比较原始结果与报告引用值,而不只检查返回文本是否变短。

    参考资料

    • 国内:JavaGuide:上下文工程:依据工具观察中保留参数、错误和原始引用的解释,说明查询预览为什么仍需关联执行信息与产物入口。
    • 国内:ranxi2001:记忆与上下文:参考中间结果外置、按需恢复与压缩后检查任务不变量的讨论,说明完整结果、模型预览和数值验证各自的职责。
    • 国内:DeepSeek Harness:压缩与裁剪:参考原始工具事件与裁剪后表示保留关联的设计,解释缩短模型可见内容不等于删除底层执行依据。
    • 国内:Datawhale:上下文工程,第 9.5 节:借鉴先检查数据规模与列结构、再定向读取文件的示例,说明预览应服务于定位,不能代替对完整数据的处理。
    • 国外:Anthropic:Effective context engineering:参考轻量引用与运行时按需加载,以及额外探索的延迟代价,解释产物 ID 取数如何减少一次性输入及其取舍。
    • 国外:LangChain:Deep Agents context engineering:参考大工具结果外置后返回位置与预览的机制,解释结果外置与历史消息摘要是不同层次;本文的具体行数和保存行为以 DB-GPT 源码为准。
  2. 子任务失败或返回空数据时,工作流如何重试和降级?

    展开收起

    核心回答

    DB-GPT 当前数据分析链路由主 Agent 执行 SQL 和 Python 分析,把结果保存为带标识的产物,再交给专职报告子 Agent 组织报告。报告缺数据时,先区分未捕获结构化结果、缺少计算、报告格式或引用错误,以及子 Agent 执行失败,再选择补结果、交回补算、局部修复或停止。 不需要把所有分析从头重跑,也不能把空数据或草稿当成完整成功。

    报告子 Agent 与主 Agent 共享产物及报告状态,但有独立会话、记忆和执行步数预算。它的工具用于读取证据、渲染报告和请求补算,没有直接执行 SQL、Python 分析的工具;缺少退款率等计算时,交回主 Agent 处理。子 Agent 构建与工具范围。

    空数据和缺少结构化结果怎样区分

    generate_report() 检查已成功执行的 SQL、Python 产物:如果存在这些产物,但它们的 result 全部为 None,返回 needs_analysis,要求主 Agent 捕获可绑定的结构化结果。只有打印文本,即使内容看起来像计算结果,也不足以让报告按字段取数。生成入口的结果检查。

    这不是“业务无数据”的通用判断器:空列表本身不等于 None。某门店活动期间确实没有退款、筛选条件错误、分析只打印了进度,需要主分析链根据查询条件和执行结果分别解释,不能都补成零,也不能都用同一请求重试。

    缺少计算怎样交回和恢复

    报告子 Agent 调用 request_report_calculation(),提交计算名称、计算步骤和源产物标识。程序要求名称、步骤非空,输入必须指向真实、成功的 SQL 或 Python 产物;随后读取其结果,保存补算输入和检查点,向主 Agent 返回 needs_analysis。补算请求与检查。

    同一个未完成请求再次到来时,直接返回已有请求,不新增计数;已有请求完成后再提出请求仍会消耗预算。这是待处理请求保护,并非根据公式内容实现了跨请求语义去重。当前实现累计最多交回三次缺失计算,每个待补算请求又限制最多三次代码执行尝试,两个限制分别控制不同阶段。

    主 Agent 用 code_interpreter 只完成缺失计算,并把结果赋给 REPORT_RESULT。代码成功、捕获到成功的 Python 产物且其结果不是 None 后,程序才回填 result_artifact_id、保存检查点;再次生成报告时,子 Agent 使用这个真实产物继续绑定。仅向标准输出打印一段 JSON 不满足这个捕获条件。补算执行预算、结构化结果捕获、补算完成条件。

    产物状态和输入标识的检查能确认计算确实产生了可读取结果,不能证明退款率公式、时间归属或分母选择已经正确;这些仍需按业务口径核对。

    修复失败时怎样停止和降级

    报告修复分别记录预检、文档组装、渲染和无效调用的失败,并设置总调用上限。错误与候选内容的指纹用于识别重复失败;没有进展时可以提前停止,不必等所有次数耗尽。修复主要针对已保存的报告结构与引用,保留成功产物,不重新执行整套分析。修复预算与无进展判断。

    若子 Agent 超时或抛出执行异常,程序先尝试从已保存内容确定性渲染;仍不能完成时,返回 failed、retryable=False,保留检查点和可能存在的草稿,提示本轮停止反复调用。执行异常与最后一次渲染错误分别记录,避免把所有问题都当成模板错误交给模型继续改。异常与失败返回、异常后的保存内容恢复。

    受控降级也会明确留下缺口:部分不可核验的显示数值可以标为 --,不可用的图表可以省略,并在报告和 warnings 中说明。它不会把缺失值替换成其他数字;其余引用与报告要求仍需通过校验。引用降级、警告与最终校验。

    最终状态根据正式报告内容与错误状态产生:未完成时返回 partial,预算耗尽时返回 failed;草稿预览不能变成正式报告。completed 也可能带降级警告,因此业务验收还要查看缺失项是否允许。报告完成状态。评估时应分别统计补算恢复、带缺口交付和停止失败,不能把所有“有报告输出”都计为任务完整成功。JavaGuide:错误恢复与最终状态评估。

  3. 工具超时或返回空结果时,如何约束 Agent 向用户反馈真实执行状态?

    展开收起

    核心回答

    先让执行层返回可判断的状态与证据,再让 Agent 解释结果。没有查到数据、查询失败、等待超时和结果无法归档,是四种不同情况。 超时尤其不能被翻译成“数据库已经停止执行”,也不能用上一次查询的数字补成这一次的答案。

    DB-GPT 的数据分析入口将 SQL 工具结果与报告产物关联:正常结果提供 artifact_id 和表格预览;失败返回 success: false 与具体 error_code。接入报告产物 sink 后,真实 SQL 尝试还会记录数据库、SQL、耗时和状态,供后续报告检查。这里约束的是执行事实,不靠提示词要求模型“诚实”来代替执行检查。

    空结果和失败如何区分

    sql_query 在执行前检查是否选择数据源、是否为单条只读查询,对应 SQL_DATASOURCE_REQUIRED 和 SQL_READ_ONLY_REQUIRED。只读检查遍历解析后的 token,拒绝写操作和 SELECT INTO,但不替代数据库权限,也不证明查询口径正确。执行前检查。

    执行成功而没有数据行,是合法的零行结果。返回值可能完全为空,也可能包含列头但没有行;两条路径都可以捕获成功产物,后者保留列和 row_count=0。Agent 应说明“按当前数据源和筛选条件未查到记录”,不能直接推导“该活动销售额为零”。缺少记录、聚合返回 NULL 与数值 0 也要根据具体查询区分。

    执行异常则返回 SQL_QUERY_FAILED,不能因为结果中存在一段文字或一个产物记录就当成查询成功。capture_sql_execution() 将带错误的 SQL 产物记为 failed;正常零行产物仍是 succeeded。数据库工具的当前返回结构与 MCP 的 isError 不是同一套字段,但两者都说明调用收到响应不等于业务执行成功。产物捕获、MCP 工具错误约定。

    等待超时为什么不能说查询已停止

    工具默认通过 asyncio.wait_for() 等待最多 30 秒,超时返回 SQL_QUERY_TIMEOUT,设置 cancel_event,反馈为“已请求中断”。上层任务取消也设置该事件、捕获取消记录,并继续抛出取消异常。

    真正能否停止,要看连接器:

    • 原生 SQLite 路径把超时和事件传给 query_ex(),通过连接上的 progress handler 检查截止时间及取消信号,并调整锁等待时间。若驱动缺少相应接口,代码会记录警告后继续执行,不能承诺所有 SQLite 环境都有硬中断。
    • 其他连接器走线程中的 connector.run();此处没有把同样的取消参数传入。取消等待协程不保证线程里的数据库调用已结束,连接器自身的超时能力需要另行确认。

    因此可以说“这次工具等待已超时,尚未取得可用结果,已请求中断”,不能说“查询已被数据库终止”。30 秒是默认等待预算,也不是所有连接器的统一数据库截止时间。工具超时分支、SQLite 协作中断。

    工具会提示检查执行计划和关联索引,优化查询后再尝试,而非原样反复提交。若要继续自动重试,应先核对原查询是否仍运行、还剩多少总预算,限制次数和并发;这些是接入时应补齐的运行策略,不能写成当前工具已具备完整查询对账与重试系统。

    查询完成但产物保存失败怎么办

    capture_sql_execution() 的归档异常会转为 ARTIFACT_CAPTURE_FAILED,说明 SQL 尝试完成,但结果快照没有保存,并明确提示不要重跑查询。Agent 既不能把它说成查询未执行,也不能编造一个可以给报告使用的产物 ID。应反馈“查询尝试已完成,结果归档失败,暂时无法提供可追溯结果”,再由系统恢复归档或人工排查。

    报告可以继续使用已经核实的成功产物,但应说明缺少的指标与结论。失败产物只能说明尝试发生过,合法空产物只能说明这次查询没有行,超时记录只能说明工具没有在预算内取得结果;三者都不提供可随意替代的业务数字。