数据流追踪与端到端可观测性面试题
这份题库关注的不是“给请求加一个 trace_id”这么简单,而是如何让一次 AI 请求从入口到最终业务事实都可关联、可重放、可审计、可脱敏。回答时要区分观测字段、业务主键、执行状态和外部事实,不能把日志、Trace、任务表和业务数据库混成一个系统。
一、先建立追踪模型
用户点击“提交报销”后关掉页面,后台仍可能在调用模型、查政策和写财务系统。追踪链要回答这次请求用了哪个版本、工具是否真实执行、金额是否已落账,而不能只留一个浏览器 request id。
Q1:一次企业 Agent 请求为什么需要多个 ID?
考察点
是否能区分调用关联、任务生命周期、工具调用尝试和业务幂等语义。
回答脉络
先定义 trace_id、task_id、span_id、tool_call_id、idempotency_key,再说明它们的生命周期和关联关系。
详细参考答案
我会至少使用以下几类标识:
trace_id表示一次请求或一次可观测调用树,贯穿 Gateway、模型、检索、工具和数据库访问,用于定位延迟、错误和成本。task_id表示一个可跨 HTTP 请求持续运行的业务任务。长任务断线、重试或人工接管后,新的网络请求仍然关联到同一个task_id。span_id表示 Trace 中的一个时间区间,例如一次模型调用、一次向量查询或一次工具执行;父子关系由parent_span_id表示。tool_call_id表示模型在某一轮输出中的工具调用意图。工具重试通常可以产生多个 execution span,但仍应保留同一个调用意图和 attempt 序号。idempotency_key表示一次外部业务动作的去重契约,例如创建付款、发送邮件或写入订单。它不应等同于trace_id,因为同一业务动作可能跨多个重试和任务恢复继续执行。
典型关系是 trace_id -> task_id -> step_id -> tool_call_id -> idempotency_key。每个实体都要记录租户、主体、配置版本和时间,但不能把用户输入、完整提示词或敏感结果直接拼进 ID。ID 应不可预测、不可包含隐私,并在跨服务传递时验证格式和归属。
常见追问及答案
- 为什么不能只用一个 request_id? 短请求的 request_id 无法表示断线后的长任务,也无法区分同一工具意图的多次执行和业务幂等键。
tool_call_id能直接当幂等键吗? 不能。一个模型调用可能因供应商重试或执行器重放产生多个业务动作,幂等键应绑定具体动作参数、资源和业务语义。
扣分点
- 只会在 HTTP Header 里生成一个 ID。
- 把
trace_id当作支付、退款等业务动作的唯一键。 - 不记录 attempt、父子关系和租户边界。
Q2:如何设计一份跨服务通用的 Trace Context?
考察点
是否能把标准传播、业务字段和安全边界分开设计。
回答脉络
先说 W3C Trace Context 或等价标准,再说明业务扩展字段、可信来源和跨异步边界的传递。
详细参考答案
同步 HTTP 调用使用标准的 traceparent 和可选 tracestate 传播采样和父子关系;业务字段单独放在受控 Header 或 RPC metadata 中,例如 tenant_id、task_id、actor_id_hash、config_snapshot_id。不要把所有业务字段塞进 tracestate,也不能依赖客户端传来的 tenant_id 作为授权依据。
进入队列时,把经过服务端确认的上下文写入消息信封,消息体中记录 trace_id、父 span、任务和租约版本。消费者创建新的处理 span,但保留关联上下文。跨服务边界要限制允许传播的字段,外部供应商只发送最少必要信息,通常不传播内部用户标识、完整租户名或原始 Prompt。
入口先生成或验证 Trace Context,禁止客户端伪造采样率、租户和权限范围。上下文大小应有上限,避免恶意请求利用 Header 或消息元数据造成资源耗尽。日志系统按 trace_id 查询,但权限系统仍要根据真实认证主体做访问控制。
常见追问及答案
- 队列消息没有父请求怎么办? 由发布者创建消息生产 span,并把消息 ID 和任务上下文写入消息;消费者以消息生产 span 作为链接或父 span。
- 是否应该传播完整用户 JWT? 通常不应该。服务之间使用短期服务凭证或受控的 actor context,避免在日志、队列和第三方请求中扩散长期令牌。
扣分点
- 只复制所有 Header,不做字段白名单。
- 把观测上下文当成授权上下文。
- 异步队列和回调没有关联关系。
Q3:Trace、日志、指标和业务事件分别解决什么问题?
考察点
能否说明四类信号的职责、关联方式和存储边界。
回答脉络
从单请求诊断、聚合趋势、业务事实和长期审计四个角度比较。
详细参考答案
Trace 描述一次请求在服务、模型、检索和工具之间的时序和耗时,适合定位链路瓶颈;日志记录具体异常、决策原因和结构化上下文,适合搜索诊断;指标是低维聚合,例如 P95 TTFT、工具错误率、缓存命中率、每租户成本,适合告警和容量规划;业务事件记录“任务已批准”“订单已创建”这类需要长期保留、可重放和对账的事实。
四类信号通过 trace_id、task_id、span_id、event_id 和资源 ID 关联,但不能互相替代。Trace 不适合保存大段文档和完整 Prompt,指标不能带高基数原始 ID,日志不应成为业务事实的唯一来源,业务事件也不应承担高频调试日志的成本。
例如一次退款请求可以有一棵 Trace、若干结构化日志、一次工具耗时指标、一个 refund_requested 事件和一个由支付系统确认的 refund_succeeded 事实。只有后者才能用于财务对账。
常见追问及答案
- 所有日志都带完整 Trace 吗? 关键日志应带;高频 debug 日志可采样,但不能采样掉安全和副作用事件。
- 业务事件能否只放 Kafka? 需要有可查询、可恢复和可审计的持久化语义,通常由事件表、Outbox 或可靠事件平台共同实现。
扣分点
- 只会说“把日志打全”。
- 用指标记录每个用户和每个文档 ID,造成高基数爆炸。
- 把模型输出日志当成业务成功事实。
Q4:如何定义一条 Trace 的开始和结束?
考察点
是否能处理同步请求、异步任务、流式连接和后台补偿。
回答脉络
分别说明入口 span、任务 span、流式 span、后台 span 和外部确认 span 的边界。
详细参考答案
同步请求的入口 span 从 Gateway 收到请求开始,到响应头或响应体完成结束;流式请求可以把网络连接作为 transport span,同时为模型生成和每个下游调用单独建子 span,避免连接被用户长时间打开掩盖真正计算耗时。异步任务的入口 span 只覆盖“接受任务并落库”,后台执行创建新的 trace 或 span link,并通过 task_id 关联同一业务任务。
任务的“成功”不能简单等同于最后一个 HTTP span 结束。对于外部异步动作,还要有查询、回调或对账 span,直到状态机确认业务事实。人工等待期间不应保持一个永不结束的 span,而应记录等待事件和停留指标。补偿、回滚和人工接管各自创建独立 span,并保留原任务的链接。
结束时要区分 request_completed、task_succeeded、artifact_published 和 external_action_confirmed。一个回答已经返回,不代表文件已经生成成功,更不代表外部付款已经完成。
常见追问及答案
- 流式连接断开就是 Trace 失败吗? 不一定。应记录客户端断开原因,判断模型和工具是否继续执行,并由任务状态确认最终结果。
- 等待人工审批时 Trace 保持 open 好吗? 通常不建议,长时间 open 会浪费观测资源;用事件、任务停留时间和恢复后的新 span 表示等待。
扣分点
- 用单个入口 span 覆盖数小时任务。
- 把返回 HTTP 200 当作业务完成。
- 不记录客户端断开和后台继续执行情况。
Q5:如何给 Span 设计字段,既能定位问题又不泄露数据?
考察点
是否能平衡可诊断性、高基数、隐私和成本。
回答脉络
先列稳定低维字段,再讲哈希、摘要、引用和受控采样,最后说明访问权限。
详细参考答案
通用字段包括服务名、环境、版本、区域、租户哈希、任务 ID、步骤类型、状态、错误码、模型名、配置快照、输入输出 token、缓存命中、工具名、检索索引版本和耗时。对于文档和 Prompt,不直接记录全文,而记录内容哈希、长度、schema 版本、引用 ID、页码、段落定位和必要的脱敏摘要。高基数字段如原始 URL、订单号和文档 ID 可以放日志或关联表,不应全部作为指标标签。
脱敏在采集前进行:识别邮箱、电话、身份证、密钥、Cookie、访问令牌、财务账号和自由文本中的个人信息;对需要关联的字段使用租户隔离的 HMAC,而不是可逆明文或无盐哈希。原文只在受控、加密、限时保留的证据存储中保存,并由少数角色按工单访问。
采样也要有规则:普通成功请求可采样,权限拒绝、越权、外部写入、未知结果、恢复失败和高额成本请求应强制保留最小必要证据。Trace 查询接口同样要做对象级授权,不能因为拥有观测权限就越过业务数据权限。
常见追问及答案
- 哈希后就不算敏感数据了吗? 不一定。可关联哈希仍可能属于个人数据,且字典攻击可能还原低熵字段,需要密钥隔离和访问控制。
- 调试时可以临时记录完整 Prompt 吗? 只能在审批、脱敏、时限和租户隔离条件下临时采集,结束后自动清理并记录谁访问过。
扣分点
- 把 Prompt、文档、JWT 和工具结果原文全部写进 Trace。
- 只用字符串替换几个固定字段,忽略自由文本和附件。
- 观测系统不做权限控制。
二、端到端链路追踪
Q6:请画出 Gateway 到最终 Artifact 的完整追踪链路。
考察点
是否能把入口、运行时、模型、RAG、工具、数据库和产物服务连成可执行的时序。
回答脉络
按阶段说明输入、输出、ID、版本、权限和失败点。
详细参考答案
我会把链路画成:
Gateway
-> Auth / Tenant / Rate Limit
-> Runtime Task + Policy
-> Prompt Assembly + Model Call
-> Query Rewrite / RAG Retrieve / Rerank
-> Tool Gateway + Approval + Idempotency
-> DB / External Service
-> Artifact Store / Citation
-> Response Stream / Task EventGateway 生成 trace_id、校验用户身份和幂等创建请求;Runtime 创建 task_id、锁定 Agent 和策略版本;Prompt 阶段记录模板、变量 schema 和上下文来源的快照 ID;RAG 阶段记录查询改写、检索器、过滤条件、索引版本和证据引用;Tool Gateway 负责工具授权、参数校验、tool_call_id、idempotency_key 和执行租约;DB 或外部系统返回业务事实;Artifact 服务以不可变对象保存文件、引用清单或结构化结果;最后通过流式响应或任务事件返回状态。
每一段都创建父子 span,并在状态变更、权限决策、版本发布和外部副作用处写领域事件。大对象只记录 artifact_id、哈希和大小。任何一段失败都要说明是“未执行”“执行中断”“结果未知”还是“业务拒绝”,不能只返回一个通用 500。
常见追问及答案
- 为什么 RAG 和工具不能共用一个 span? 两者的延迟、权限、重试和失败语义不同,合并会遮蔽瓶颈和泄露边界。
- 最终回答和 Artifact 如何关联? 通过
task_id、artifact_id、内容哈希和引用事件,确保下载的文件与回答宣称的版本一致。
扣分点
- 架构图只有 API、LLM 和数据库三个框。
- 没有把权限、版本和幂等放进链路。
- 只追踪成功路径,不描述中断和未知结果。
Q7:Gateway 层应该记录哪些字段,哪些字段不能信任客户端?
考察点
是否理解入口边界、请求幂等和用户输入的可信等级。
回答脉络
先说认证和请求元数据,再区分服务端生成字段与客户端声明字段。
详细参考答案
Gateway 应记录请求到达时间、路由、协议、客户端版本、认证主体、租户、权限版本、请求大小、限流结果、入口区域、trace_id、创建任务的幂等键摘要和响应状态。租户、主体、角色、权限范围、配置版本和采样策略应由认证、策略或服务端配置解析得到;客户端传来的 tenant_id、user_id、role、is_admin 和 trace_id 只能作为非可信输入或被覆盖。
请求幂等键要绑定租户和 API 操作,服务端保存请求摘要,发现同键不同体时返回冲突而不是复用旧结果。Gateway 先做 schema、大小、附件类型和速率校验,再把最小可信上下文交给 Runtime。认证失败、权限拒绝、限流和 body 解析错误也要生成足够的诊断信息,但不能把原始凭据写入日志。
常见追问及答案
- 客户端重试时如何避免重复创建任务? 使用租户范围内的 API 幂等键和请求摘要,已创建则返回原
task_id。 - 入口生成的新 trace 可以接受客户端 trace 吗? 可以作为链接字段保留,但内部主 Trace 应由服务端生成,避免伪造和串线。
扣分点
- 信任请求 body 中的租户和管理员标记。
- 没有请求摘要,导致幂等键被错误复用。
- 日志包含 Authorization、Cookie 或完整请求体。
Q8:Runtime 如何追踪一次多轮模型循环?
考察点
是否能区分轮次、步骤、模型调用和状态快照。
回答脉络
说明 loop、step、attempt、checkpoint 和事件之间的关系,避免把模型文本当状态。
详细参考答案
Runtime 为任务建立不可变的 run_id 或执行分支,循环中的每一轮有 step_id 和 iteration,模型请求、RAG 查询、工具执行分别创建子 span。每轮开始前读取当前 checkpoint,记录输入消息摘要、预算、策略版本和可用工具集合;模型返回后先进行 schema 校验和策略判定,再决定是生成回复、检索、调用工具、等待审批还是结束。
每次状态转移都写事件并更新带版本号的任务快照。模型输出的自然语言只是一种候选结果,不能直接覆盖任务状态。若同一轮发生网络重试,保留 attempt 序号和供应商 request ID;若执行器恢复,则从最近已确认的 checkpoint 继续,而不是重新猜测已经完成的步骤。
常见追问及答案
- 每一轮都保存完整上下文吗? 大上下文放加密对象存储,快照保存哈希、消息引用、token 统计和必要的结构化状态。
- 模型返回工具调用但参数不合法怎么办? 记录模型响应和校验错误,进入修正或失败状态,不能直接调用工具。
扣分点
- 只记录最终答案,不记录模型轮次和工具意图。
- 模型输出可任意改变任务状态。
- 重试覆盖原 attempt,导致无法判断是否重复执行。
Q9:Prompt 组装阶段如何追踪上下文来源和版本?
考察点
是否能做到 Prompt 可解释、可复现且不泄露原文。
回答脉络
从模板版本、变量来源、RAG 证据、工具结果和消息裁剪说明展开。
详细参考答案
Prompt span 应记录 prompt_template_id、模板版本、system policy 版本、变量 schema、模型路由、上下文预算和组装策略。每段上下文标注来源类型:用户消息、系统规则、RAG 证据、工具结果、历史摘要或人工输入,并记录来源 ID、内容哈希、权限判定、知识版本和截断原因。不要在普通 Trace 中存完整 Prompt,可以在受控证据存储中保存脱敏快照。
上下文组装必须是确定性的:同一版本、输入摘要和证据集合应能得到相同的消息结构。发生窗口裁剪、摘要替换、Prompt Cache 命中或安全指令覆盖时,写出决策字段和 token 变化。这样排查“模型突然答错”时,能判断是检索变化、上下文丢失、模板改动还是模型本身波动。
常见追问及答案
- 模板版本和模型版本哪个更重要? 两者都要。模板决定约束和字段,模型决定推理行为;还需记录工具 schema、索引和策略版本。
- 上下文快照是否可以永久保存? 受数据保留、用户删除和合规要求约束;保存摘要和哈希通常优于永久保存原文。
扣分点
- 只记 prompt 名称,不记版本和变量来源。
- 把所有用户文档拼进日志。
- 忽略上下文裁剪和缓存命中导致的输入差异。
Q10:如何追踪 RAG 检索到引用生成的证据链?
考察点
是否能把查询改写、候选、权限过滤、排序、上下文和引用逐层关联。
回答脉络
从 query、retrieval、rerank、evidence、claim-citation 五层展开。
详细参考答案
RAG 追踪至少包含:原始问题哈希和改写查询版本;检索器类型、过滤条件、索引 release、召回数量和延迟;候选文档/片段 ID、分数和被过滤原因;reranker 版本及最终上下文顺序;模型输出中的 claim 与引用 ID 映射。候选内容在进入模型前必须完成租户和 ACL 过滤,Trace 里只保存引用 ID、版本、页码、字符范围和摘要哈希。
如果答案包含多个声明,生成后应做 claim-citation 校验并记录支持、冲突、过期和无证据状态。引用链接指向 Artifact 或受控文档服务,由服务端再次检查权限和版本,不让前端根据一个裸 URL 绕过授权。检索缓存命中时仍记录命中的索引版本、权限版本和过滤摘要。
常见追问及答案
- 为什么要记录被过滤的候选? 可以记录数量和原因码,通常不记录未授权内容本身;这样能发现权限错误而不泄露文档。
- 模型引用了不存在的片段怎么办? 将其标记为无效引用,阻断高风险回答或触发重试/人工,而不是自动拼接一个近似链接。
扣分点
- 只记录最终引用 URL,不记录索引和版本。
- 先把未授权文档送给 reranker 或模型,再在输出阶段过滤。
- 用检索分数代替证据支持关系。
三、权限、版本与成本传播
Q11:权限上下文如何从 Gateway 传播到 RAG、Tool 和 Artifact?
考察点
是否能保证每个下游都基于可信身份和资源范围授权,而不是依赖模型或前端。
回答脉络
认证主体 -> policy snapshot -> 下游过滤/授权 -> 结果再次复核 -> 审计。
详细参考答案
Gateway 从身份系统解析主体、租户、组织、角色和权限版本,Runtime 将其固化为本次任务的 access_context_snapshot_id。RAG 查询使用该快照做文档、片段和附件过滤;Tool Gateway 根据主体和资源计算动作权限,必要时发放短期、最小范围的执行令牌;DB 访问使用数据库行级权限或服务端资源校验;Artifact 下载和引用解析再次检查当前权限,避免任务创建时有权限、交付时已撤权仍可读取。
权限上下文不能由模型输出、用户消息或 RAG 文档内容覆盖。权限变化要有版本号和失效时间,缓存键包含租户、主体/权限版本、资源范围、策略版本和知识版本。审计记录授权决策、策略版本、拒绝原因和资源摘要,但不记录完整敏感内容。
常见追问及答案
- 任务运行很久,权限变化怎么办? 高风险动作和 Artifact 交付时重新授权;对于长任务可配置快照权限或强制使用当前权限,必须明确产品语义。
- 为什么工具还要自己授权? Runtime 的策略不能替代资源服务的最终授权,纵深防御要求工具和业务服务拒绝越权。
扣分点
- 只在 Gateway 鉴权一次。
- 把权限信息放进 Prompt 让模型自行判断。
- 忽略撤权、缓存和产物下载阶段。
Q12:如何做版本快照,才能复现一次线上失败?
考察点
是否知道一次结果受哪些可变依赖影响,以及如何冻结和回滚。
回答脉络
列出模型、Prompt、工具、RAG、权限、代码、特性开关和数据快照,说明 manifest 与哈希。
详细参考答案
任务创建时生成不可变 manifest,至少包含应用和 Runtime 版本、模型供应商/模型版本、Prompt 模板与策略版本、工具 schema 和实现版本、RAG pipeline/embedding/reranker/index release、权限快照、特性开关、区域、采样参数、依赖服务版本和输入摘要哈希。manifest 自身有版本和内容哈希,事件、Trace、checkpoint、Artifact 和成本记录都引用它。
复现不等于把生产数据原样复制。应在脱敏隔离环境恢复输入、可用的知识版本和模拟工具响应;对于外部副作用只做 dry-run 或查询,不重放真实写入。若供应商模型不可冻结,记录响应、随机种子(若支持)、请求参数和供应商 request ID,并明确这是轨迹复现而非位级确定性复现。
常见追问及答案
- 只保存 Git commit 行不行? 不够,模型、索引、Prompt、工具 schema 和权限策略可能在代码之外变化。
- 用户删除数据后还能复现吗? 需要遵守删除和保留政策;可保留脱敏摘要、哈希和结构化证据,不应绕过用户删除永久保存原文。
扣分点
- 只记录当前应用版本。
- 线上排障直接调用真实写工具重放。
- 版本信息散落在文本日志中,没有可校验 manifest。
Q13:如何把缓存命中和成本计入端到端 Trace?
考察点
是否能区分模型、Prompt、RAG、工具和 Artifact 缓存,并避免用缓存掩盖权限或版本问题。
回答脉络
先列缓存层,再讲 key、命中事件、token/费用归属和失效。
详细参考答案
每个缓存层创建独立 span 或事件:Prompt Cache/KV Cache 记录前缀哈希、命中范围和节省 token;RAG 结果缓存记录 query 策略、权限版本、索引 release、TTL 和候选摘要;工具只读缓存记录资源版本和新鲜度;Artifact 缓存记录对象哈希和租户隔离。统一费用明细中区分输入 token、缓存命中 token、输出 token、工具调用费、检索资源费和存储/带宽费。
缓存 key 必须包含影响正确性和授权的字段,不能只用自然语言问题。命中后仍要校验当前权限、租户、数据版本和过期时间;权限撤销、文档删除、工具资源变化和策略发布应触发失效或版本隔离。Trace 记录命中/未命中、回源耗时、节省估算和失效原因,用于计算“每个成功任务成本”,而不是只看平均 API 账单。
常见追问及答案
- 缓存命中就不需要记录下游 span 吗? 可以不创建未发生的下游调用,但要记录 cache span、命中依据和版本,避免链路看起来像数据凭空出现。
- 为什么缓存命中率高但成本没有下降? 可能只缓存了低成本检索、命中的是短前缀,或重试、输出 token、工具费用占主导;需要联合分析。
扣分点
- 用用户问题作为全局缓存键。
- 缓存绕过 ACL 和版本检查。
- 只统计模型账单,不算检索、工具、存储和重试成本。
Q14:如何做跨租户和跨用户的 Trace 查询隔离?
考察点
是否把观测平台本身当作敏感数据系统治理。
回答脉络
主体授权 -> Trace 归属 -> 字段脱敏 -> 索引隔离 -> 导出审计。
详细参考答案
每条 Trace 和日志必须写入服务端解析出的 tenant_id、数据分类和访问域,查询 API 根据调用者的观测权限做对象级过滤。平台管理员也不应默认看到所有 Prompt 或附件正文;可以按职责提供指标、脱敏 Trace、受审批的证据查看和临时 break-glass。索引、对象存储、导出文件和缓存都要沿用租户隔离,不能只在前端隐藏字段。
脱敏策略在写入前执行并保留规则版本;涉及高风险数据的 Trace 默认只保存哈希、引用和错误码。查询、下载、恢复原文、批量导出和权限提升都写观测平台审计。跨租户聚合只展示统计结果,并限制小样本和高基数查询,防止通过差分推断泄露数据。
常见追问及答案
- 运维排障需要跨租户看一条链怎么办? 使用受审批的临时权限和最小字段视图,查询结果自动过期并记录工单、操作者和原因。
- Trace ID 猜不到就安全吗? 不安全。ID 不可预测只能降低枚举,真正保护来自授权、索引过滤和存储隔离。
扣分点
- 认为“日志平台只有内部人使用,所以可以全量明文”。
- 只在 UI 做租户过滤。
- 导出和 break-glass 没有审计。
四、Tool、DB 与外部副作用
Q15:如何把 tool_call_id、执行 attempt 和 idempotency_key 关联起来?
考察点
是否能处理模型重复意图、网络重试、Worker 恢复和业务去重。
回答脉络
意图记录 -> 参数规范化 -> 动作键生成 -> 执行尝试 -> 外部确认。
详细参考答案
模型输出一条工具调用时,Runtime 先持久化 tool_call_id、工具 schema 版本、规范化参数摘要、主体、资源、风险决策和当前 step_id。执行器根据业务动作生成稳定的 idempotency_key,例如由租户、动作类型、资源 ID、任务步骤和语义版本组成;不能把易变化的 Trace 或随机 attempt 放进键。每次网络请求有 attempt 和供应商 request ID,但所有 attempt 都引用同一动作记录。
动作表保存 PENDING、SENT、SUCCEEDED、FAILED、UNKNOWN 状态和请求哈希。超时后先用幂等键查询外部系统;若外部系统不支持幂等或查询,必须进入人工/对账流程,不能盲重试。参数摘要变化时返回冲突,防止同一键被用于不同资源。
常见追问及答案
- 同一个工具调用重放时是否生成新 tool_call_id? 如果是同一模型意图恢复执行,保留原
tool_call_id并增加 attempt;如果是人工确认后产生的新业务意图,才创建新的调用。 - 只读查询需要幂等键吗? 业务副作用较低,但仍应有请求关联和去重/缓存语义,避免昂贵查询风暴。
扣分点
- 每次重试都随机生成幂等键。
- 用工具名称和用户问题简单拼接键。
- 超时后直接再次扣款或发邮件。
Q16:Tool Gateway 如何保证权限、参数和资源边界可追踪?
考察点
是否能把模型的意图变成经过多层校验的受控动作。
回答脉络
工具注册信息 -> schema 校验 -> 业务授权 -> 风险/审批 -> 执行隔离 -> 结果校验。
详细参考答案
Tool Gateway 为每个工具维护 owner、版本、风险等级、允许主体、资源范围、网络/文件能力、预算、超时和审批策略。收到调用后依次做 JSON Schema 类型校验、业务规则校验、资源归属校验、租户/主体授权、敏感字段检查和高风险确认。所有决策写入 tool_policy_decision span,记录策略版本、拒绝原因和参数摘要。
执行环境使用短期最小权限凭证、网络白名单、文件目录隔离、CPU/内存/时间/输出大小限制。工具返回后校验 response schema、业务状态和副作用证据,不能仅凭 HTTP 200 宣称成功。工具结果进入 Prompt 前再次标记来源和不可信内容,防止外部文本改变控制流。
常见追问及答案
- 工具返回“已成功”就能更新任务吗? 还要根据业务系统事实或可验证回执确认,尤其是异步 202、超时和部分成功。
- 参数已通过 Schema 是否足够? 不够。Schema 只能保证形状,不能保证用户有权访问资源、金额在额度内或动作经过确认。
扣分点
- 让模型决定是否有权限。
- 把 schema 校验当成安全校验。
- 没有记录拒绝、审批和响应校验。
Q17:数据库读写如何在 Trace 中体现事务、版本和提交结果?
考察点
是否能区分 SQL 执行完成、事务提交和业务事实。
回答脉络
说明 DB span 字段、事务边界、乐观锁、Outbox 和提交后事件。
详细参考答案
数据库 span 记录服务名、数据库类型、操作类别、事务 ID 的不可逆摘要、表/逻辑资源、查询模板哈希、行数、锁等待、重试和耗时,不记录完整 SQL 参数中的敏感值。写操作必须携带 task_id、动作 ID、幂等键和当前版本条件;通过乐观锁或唯一约束防止旧 Worker 覆盖新状态。
业务状态、动作记录和 Outbox 事件在同一个事务中提交。只有提交成功后才发布“动作已记录”的事件;提交失败要明确是未生效还是结果未知。跨数据库或外部系统不能假设分布式事务,使用 Outbox、Saga、对账和补偿。Trace 中把“SQL 执行成功”“事务提交成功”“下游事实确认”分开记录。
常见追问及答案
- 数据库返回影响行数为 0 怎么处理? 可能是版本冲突、资源不存在或已幂等完成,应重新读取并按状态机判断,不能直接当成功。
- 事务回滚后需要保留日志吗? 要保留脱敏的失败事件和 Trace,说明未提交;不能让调试日志看起来像业务事实已发生。
扣分点
- 日志打印完整 SQL 和参数。
- 数据库更新成功就认为外部动作成功。
- 没有版本条件、唯一约束或 Outbox。
Q18:外部 API 超时但可能已经成功,如何追踪和收口?
考察点
是否能处理“未知结果”而不是把网络错误等同于业务失败。
回答脉络
记录发送事实 -> 标记 UNKNOWN -> 查询/回调/对账 -> 成功、失败或人工终态。
详细参考答案
发送前把动作和幂等键写入动作表,生成 outbound span;收到响应则记录状态码、供应商 request ID 和业务回执。若连接在响应前中断,动作转为 UNKNOWN,Trace 标记 outcome=unknown,不直接重试副作用。随后按退避查询接口、接收 Webhook 或对账文件,所有确认都关联同一动作和原 Trace/任务。
如果查询确认成功,写入事实事件并推进任务;确认失败才允许按政策重试;长期无法确认则进入人工队列,保留影响范围和停止自动执行的标记。客户端看到的是“处理中/待确认”,不能看到伪造的成功或失败。告警关注未知动作数量和停留时间。
常见追问及答案
- 外部 API 没有查询接口怎么办? 要求供应商提供幂等键、回执或对账能力;否则将动作列为不可自动重试的高风险能力,并设置人工收口。
- 任务超时就能取消外部请求吗? 只能取消本地等待;外部请求是否停止取决于供应商协议,不能把本地取消当成业务回滚。
扣分点
- 所有 timeout 都重试。
- 把 HTTP 连接断开当作未发送。
- 没有 UNKNOWN、查询或人工收口状态。
Q19:最终 Artifact 如何与输入、Trace、版本和权限关联?
考察点
是否能保证文件、报告、引用清单或结构化结果可验证、可撤销和可审计。
回答脉络
说明 Artifact manifest、内容哈希、来源引用、权限和交付事件。
详细参考答案
Artifact 使用不可变 artifact_id,manifest 记录 task_id、生成步骤、输入摘要、内容哈希、大小、媒体类型、创建时间、代码/模型/Prompt/RAG 版本、引用清单和数据分类。大对象存储只允许短期签名 URL 或受控下载服务访问;下载时再次检查租户、主体、权限版本和撤销状态。
Artifact 生成、上传、病毒扫描、索引和发布分别创建 span/事件,上传成功不代表已发布。回答中的引用必须指向对应 Artifact 版本或可验证的文档位置,不能因文件被覆盖而改变历史答案。删除请求通过 tombstone 和对象清理传播到缓存、搜索索引和下载链接,同时保留法规允许的审计摘要。
常见追问及答案
- Artifact 可以覆盖同名文件吗? 物理对象应不可变,使用新版本和别名指向当前版本,避免旧 Trace 解析到新内容。
- 如何防止用户篡改下载后的报告? 提供内容哈希、签名或 manifest,接收方可校验;高风险报告还应记录发布者和审批凭证。
扣分点
- 只保存一个可变文件路径。
- 签名 URL 长期有效或不检查权限。
- Artifact 没有来源、版本和哈希。
Q20:Checkpoint 应该保存什么,哪些内容不应该保存?
考察点
是否能设计可恢复而不过度持久化的执行快照。
回答脉络
任务/步骤状态 -> 已确认事实 -> 下一步意图 -> 版本预算 -> 引用和安全上下文。
详细参考答案
Checkpoint 至少保存任务和步骤状态、状态机版本、最近确认的事件序号、当前轮次、已完成的工具动作 ID、外部动作状态、剩余预算、截止时间、权限/配置/知识版本快照、消息和 Artifact 引用、重试次数以及下一步可执行条件。对大 Prompt、文档和工具结果保存加密对象引用、长度和哈希,避免每次复制大上下文。
不能把未验证的模型计划当作业务事实,也不应保存长期凭据、原始 JWT、完整敏感附件或随意可执行的 Shell 命令。写入 checkpoint 要原子化并带版本;只有数据库提交、Artifact 完成或外部回执确认后,才能把相应事实标为已完成。
常见追问及答案
- 每个 token 都 checkpoint 吗? 不需要。按步骤边界、外部副作用前后和可恢复粒度保存,流式 token 用短期缓冲或事件记录。
- checkpoint 和日志有什么区别? checkpoint 是恢复所需的权威状态;日志/Trace 是诊断证据,可能采样,不能单独驱动恢复。
扣分点
- 只保存最后一段模型文本。
- 把日志当 checkpoint 使用。
- 把未确认的外部写入标为成功。
Q21:Worker 恢复后如何判断从哪里继续?
考察点
是否能处理租约、fencing、重复事件和未知副作用。
回答脉络
租约校验 -> 读取快照 -> 检查动作事实 -> 选择重试/查询/人工 -> 新 checkpoint。
详细参考答案
恢复 Worker 必须先获取新的 lease/fencing token,旧 Worker 的迟到写入全部被拒绝。读取最新快照和事件后,按步骤分类:纯计算、幂等读和未开始步骤可以从 checkpoint 重试;已经提交数据库事务的步骤从提交后的状态继续;外部写入处于 UNKNOWN 时先查询或对账;审批、人工和外部回调步骤恢复到等待状态。
恢复决策写入 recovery_decision 事件,记录依据的 checkpoint、动作事实、重试次数、版本和操作者。若快照与事件不一致,以事务内的状态和业务事实为准,通过重放修复物化视图;不要让 Worker 自己根据模型文本猜测。
常见追问及答案
- checkpoint 丢了怎么办? 使用事件、动作表和 Artifact manifest 重建最近可确认状态;无法确认的副作用进入人工而不是盲目补做。
- 旧 Worker 恢复后还能继续吗? 不能直接写入,必须重新获取租约并从新快照重新判断。
扣分点
- 总是从头重跑。
- 没有 fencing token。
- 不核对外部动作就重放写操作。
Q22:流式输出已经发送一半,客户端断开时如何追踪?
考察点
是否能区分传输中断、任务取消、模型停止和业务副作用。
回答脉络
记录发送游标 -> 检测断开 -> 取消策略 -> 任务状态 -> 重连补发。
详细参考答案
流式响应中的每个 chunk 或事件带 task_id、event_id、单调 sequence 和 schema 版本,服务端记录已生成、已发送和客户端确认的游标。检测到连接断开时写入 client_disconnected 事件,随后按产品策略决定继续后台执行、协作式取消或进入可恢复任务;不能因为 socket 关闭就假定模型和工具已停止。
如果流中已经触发工具或外部写,按动作状态处理,必要时继续查询确认。客户端重连携带 cursor,服务端从事件存储补发,过期游标则返回当前快照和可用 Artifact。对不可重放的增量内容,记录最终完整结果或摘要,避免重连造成重复副作用。
常见追问及答案
- 客户端没收到最后一个 chunk,能否重发工具调用? 不能根据传输情况重发;先查
tool_call_id和动作状态,再决定是否只补发事件。 - 流式响应要不要保存全文? 依据隐私和产品需求,可以保存最终脱敏结果或引用,而不是永久保存每个 token。
扣分点
- 断线直接 kill Worker。
- 没有发送游标和重连协议。
- 以“用户没看到”为由重新执行副作用。
Q23:如何设计可重放的 Trace 和事件,而不重放真实副作用?
考察点
是否理解重放是诊断/评估工具,不是把生产任务再执行一遍。
回答脉络
固定 manifest 和输入 -> 替换外部依赖 -> dry-run -> 比较轨迹。
详细参考答案
重放前冻结原任务的 manifest、Prompt/RAG/工具版本、输入摘要、权限策略和事件序列,并在隔离租户生成新的 replay ID。模型可以使用录制响应或受控调用;RAG 使用脱敏的索引快照;数据库使用只读快照;外部工具全部替换为模拟器,按原始响应、延迟、错误、重复和超时注入。高风险动作只输出“将执行的参数和策略结果”,不发送真实写请求。
比较结果时同时比较状态转移、工具选择、参数、引用、成本、延迟和安全决策,而不只比较自然语言。重放产物标记为实验数据,不能污染线上任务、账单和业务事件。若为了事故取证需要访问原文,遵守临时授权、脱敏和保留期限。
常见追问及答案
- 模型有随机性,怎样判断回归? 固定可用种子和录制依赖,并使用轨迹级断言、关键字段和统计阈值,不要求自然语言逐字一致。
- 为什么不能直接复制生产数据库? 可能扩大敏感数据和副作用范围,且无法隔离回放写入;优先使用快照、脱敏和模拟器。
扣分点
- 用生产凭据重放工具。
- 只比较最终文本。
- 重放事件再次写入业务事件流。
Q24:流式中断、取消和超时如何形成一致的状态机?
考察点
是否能区分用户意图、传输状态和执行状态。
回答脉络
请求事件 -> 运行时取消 token -> 步骤边界 -> 外部动作收口 -> 终态。
详细参考答案
我会分别记录 client_disconnected、cancel_requested、deadline_exceeded、step_interrupted 和 external_action_unknown,而不是把它们都映射成 FAILED。客户端断开只表示传输层状态;用户主动取消表示业务意图;deadline 表示预算耗尽;步骤中断要说明是否可安全重试;外部动作未知需要查询或人工。
Runtime 通过取消 token 协作式通知模型、检索和工具,在安全边界检查后停止新步骤。不能中断的外部调用继续等待或进入 UNKNOWN,完成后由状态机决定 CANCELLED、SUCCEEDED 或 MANUAL_REVIEW。每次转移带当前版本和原因,终态不可被普通取消覆盖。
常见追问及答案
- 超时后一定失败吗? 不一定;要区分本地计算超时、等待外部回执超时和整体 deadline。
- 取消请求返回什么? 返回已受理和当前状态;只有状态机完成安全收口后才宣称已取消。
扣分点
- 把 socket 断开当作任务取消。
- 强杀进程造成未知副作用。
- 没有不可中断步骤和人工收口状态。
六、综合设计与故障排查
Q25:如何排查“用户说答案错了,但系统指标正常”的问题?
考察点
是否能从用户反馈反查版本、证据、权限、缓存和模型轨迹。
回答脉络
先锁定 task/trace,再按 manifest、Prompt、RAG、工具和输出校验逐层排查。
详细参考答案
先获取用户有权限的 task_id 和 trace_id,确认请求是否命中正确租户、主体、配置和知识版本。检查 Prompt manifest 是否发生裁剪、摘要或模板变更;RAG 侧查看原始/改写 query、候选数量、ACL 过滤、索引 release、rerank 和引用支持;缓存侧核对 key、权限版本和失效时间;模型侧检查响应 schema、停止原因、token 截断和工具调用。
如果答案声称执行了动作,继续查询 tool_call_id、动作表、DB 提交、外部 request ID 和 Artifact manifest,判断是文本错误、引用错误还是业务事实错误。最后将脱敏轨迹按根因分类,加入回归样本,并比较失败是否集中在某租户、语言、文档版本或缓存路径,而不是只看全局成功率。
常见追问及答案
- 用户没有 trace_id 怎么办? 通过认证主体、时间窗口、task_id、请求摘要和网关日志定位,但要防止把同一用户的请求混淆。
- 指标正常是否说明个案不重要? 不说明。长尾、高风险和少数租户的错误可能被总体均值掩盖。
扣分点
- 只重新跑一次问题。
- 只看模型输出,不查证据和业务事实。
- 为了修复个案直接改线上 Prompt,无回归样本。
Q26:如何定位 TTFT 高、但下游模型耗时正常的问题?
考察点
是否能沿 Gateway、排队、Prompt、RAG、网关缓冲和流式发送分解延迟。
回答脉络
先定义时间点,再比较各 span 和队列/网络指标,最后给出消融实验。
详细参考答案
我会记录请求到达、认证结束、任务入队、Worker 领取、Prompt 完成、RAG 完成、模型请求发送、供应商首 token、Gateway 首字节和客户端首个有效内容等时间点。若模型服务端耗时正常而 TTFT 高,重点检查队列等待、冷启动、Query Rewrite、Multi-Query、Rerank、串行检索、Prompt 过长、连接池、TLS、代理缓冲和流式 flush。
按路径做消融:关闭改写、改为并行检索、减少 top-k、跳过非必要 rerank、启用连接复用和 Prompt Cache,并比较 P50/P95、质量和成本。Trace 中标记快速路径/复杂路径、缓存命中、降级和取消,不能只优化平均值。若网关缓冲导致客户端看不到 token,要同时检查 TTFB 和首个有效内容时间。
常见追问及答案
- 首 token 快了但质量下降怎么办? 将延迟优化作为带质量门禁的实验;高风险问题保留复杂路径或按置信度升级。
- 只看模型供应商的 TTFT 可以吗? 不可以,它不包含本地排队、检索、Prompt 组装和网关传输。
扣分点
- 看到 TTFT 高就换更快模型。
- 不拆时间点和队列等待。
- 用首字节时间冒充用户看到有效内容的时间。
Q27:设计一个支持数据流追踪的企业 Agent Schema。
考察点
是否能把任务、步骤、动作、事件、证据和产物设计成可查询的数据模型。
回答脉络
先列聚合根,再列不可变记录、唯一约束、版本和保留策略。
详细参考答案
可以拆成以下核心表或等价集合:
tasks(task_id, tenant_id, actor_ref, status, version, manifest_id, deadline)
steps(step_id, task_id, sequence, kind, status, attempt, checkpoint_ref, lease_token)
tool_calls(tool_call_id, step_id, tool_name, schema_version, args_hash, status)
external_actions(action_id, tool_call_id, idempotency_key, request_hash, status, provider_ref)
trace_links(trace_id, task_id, span_id, parent_span_id, service, start_at, end_at)
evidence(evidence_id, task_id, source_id, source_version, acl_version, locator, hash)
artifacts(artifact_id, task_id, manifest_id, content_hash, classification, status)
events(event_id, task_id, sequence, type, payload_ref, schema_version, occurred_at)tasks 是当前快照,events 是可审计时间线,external_actions 用唯一 tenant_id + idempotency_key 约束副作用,evidence 保存引用和版本而非默认全文。Trace 明细通常放专业观测系统,通过 trace_id/task_id 关联;大对象放加密对象存储。状态更新、动作记录和 Outbox 事件在事务中提交,敏感字段采用引用、哈希和访问策略。
常见追问及答案
- 为什么不把所有字段放一张 JSON 表? 长期查询、唯一约束、并发更新、审计和局部保留都会变困难;结构化核心字段配合不可变引用更稳妥。
- Trace 表需要和业务数据库同库吗? 不必。重点是关联键、可靠投递和权限边界;业务事实不能依赖观测系统可用性。
扣分点
- 没有租户、版本、唯一键和状态字段。
- 把大 Prompt、附件和日志全文塞进任务表。
- 没有把动作和证据单独建模。
Q28:如何为数据流追踪系统设计容量和成本预算?
考察点
是否能识别 Trace、事件、日志、对象和索引的增长来源。
回答脉络
请求量 -> span/event 数 -> 字节量 -> 保留和采样 -> 查询/导出成本。
详细参考答案
先估算峰值 RPS、平均模型轮次、每轮下游 span、工具重试、流式事件频率、每个任务的 Artifact 和证据大小。粗略存储量为“请求数 × 每请求记录字节 × 保留天数”,再加索引、复制、压缩和高峰缓冲。流式 token 不应每个 token 写一条长期事件,可按时间或语义批量聚合;Trace 采用头部采样加尾部按错误/高风险保留。
成本拆成采集、传输、索引、存储、查询、导出、模型、检索和工具费用。对大租户设置配额和预算,超限时降低普通成功 Trace 采样,但强制保留安全、未知副作用、恢复失败和高成本样本。定期验证采样不会破坏故障定位,保留策略与合规删除策略要有明确 SLA。
常见追问及答案
- 为什么不把所有 Trace 永久保存? 成本、隐私和查询性能都会恶化;应按数据分类、风险和事故保留周期分层。
- 采样会不会漏掉偶发事故? 对错误、尾延迟、权限拒绝和高风险动作采用尾部采样/强制采集,不能只做固定比例随机采样。
扣分点
- 只按 QPS 估算,不算轮次、重试和事件频率。
- 为降成本删除安全证据。
- 没有保留、压缩、索引和查询预算。
Q29:一次 Trace 出现“权限允许但结果为空”,如何排查?
考察点
是否能区分权限误拦、数据新鲜度、索引版本、缓存和业务不存在。
回答脉络
比较权限快照、源系统、索引 release、缓存和删除事件,最后给出安全处理。
详细参考答案
先确认 Gateway 的主体、租户和权限版本,再检查 RAG/DB 查询使用的 ACL 版本和过滤条件。若源系统可见但索引无结果,查看同步延迟、解析失败、tombstone、索引 alias 和文档生效时间;若索引有候选但缓存为空,检查 cache key、TTL 和失效事件。若工具返回空,还要区分资源不存在、权限拒绝被统一隐藏和下游临时错误。
Trace 记录过滤数量、原因码、索引和缓存版本,而不记录未授权正文。高风险场景宁可返回“当前资料未找到或无权访问”,也不要通过错误消息泄露资源存在性。确认是系统误拦后补发索引或修复权限传播,并将样本加入回归。
常见追问及答案
- 能否告诉用户“你没有权限”? 取决于资源存在性和产品策略;避免通过错误差异泄露敏感资源。
- 为什么不能只扩大 top-k? 空结果可能来自版本、ACL、同步或缓存问题,扩大召回会增加成本和泄露风险。
扣分点
- 看到空结果就放宽权限过滤。
- 不区分源数据、索引和缓存。
- 错误消息泄露文档存在性。
Q30:如何把数据流追踪建设成发布门禁,而不是事后查日志?
考察点
是否能把追踪字段、质量指标、安全和回滚串成持续治理闭环。
回答脉络
字段契约 -> 采集验证 -> 评估与门禁 -> 灰度观测 -> 事故回流。
详细参考答案
首先为 Gateway、Runtime、Prompt、RAG、Tool、DB、Artifact 定义版本化 schema 和必填字段:Trace/Task 关联、租户、配置快照、权限版本、错误码、成本和副作用状态。CI 中跑 schema/契约测试,确保新服务不会丢失关键上下文;发布前用回放和故障注入验证 checkpoint、幂等、流式重连和脱敏。
灰度期间设置硬门禁:跨租户暴露为零、无审批高风险调用为零、未知副作用在阈值内、关键字段完整率达标、P95 延迟/成本不超过预算。异常自动停止扩容、禁用高风险工具或回滚配置;保留 manifest 和 Trace 证据。事故和用户反馈脱敏后进入回归集,持续更新字段、策略和检测规则。
常见追问及答案
- 字段完整率为何是质量指标? 缺少 task、版本或动作关联会让系统不可审计、不可恢复,即使最终答案看起来正确也不达标。
- 如何避免门禁过于严格影响迭代? 按风险分层:低风险字段可告警,高风险权限、幂等和脱敏字段必须阻断;用采样和灰度控制成本。
扣分点
- 只在事故后补日志。
- 发布门禁只有接口成功率。
- 没有 schema 版本、灰度、回滚和反馈回流。
结语
数据流追踪的目标不是收集越多日志越好,而是让系统能够回答四个问题:这次请求使用了什么版本和权限;模型和检索依据是什么;哪些工具和数据库动作真实发生了;如果中断或出错,怎样安全恢复并证明结果。把 trace_id、task_id、tool_call_id 和 idempotency_key 放进正确的状态、事件和业务边界,才能让 AI 应用从“能跑”变成可解释、可审计、可运营的企业系统。