面灵AI→

百度一面:链路追踪、Agent 诊断评测与 RAG 管理

轮次
一面
时间
2026-09
来源
牛客网

《面试题目》

  1. 项目深挖:既然说沿 trace,如果你们不同的服务用的是不同的代码,那 trace 里面应该能把这些信息揉进来,这个底层你了解过吗?
  2. 正常说一些请求打过来,过了网关,从 A 调 B、调 C,最后可能是 MQ、TDDL、Redis,因为一个服务可能挂了多个 MySQL,你们怎么知道现在对应的是哪个实例?
  3. 你说你们做了评测,说一下具体是怎么评测的?模型怎么知道你的结果是对的?
  4. 怎么提高 Agent 效率?
  5. 一个告警出来到你拿到的时候可能已经 10 分钟了,你的 Agent 诊断还需要时间,你们的 RT 有多少?
  6. 这个 RT 应该是一个正态分布,肯定也有长尾的一些,长尾有测吗?
  7. 你们 RAG 怎么管理的,怎么控制新旧?
  8. 定位到 DB 的时候,你们会具体执行 SQL 吗?让模型直接执行吗?
  9. 脱敏最好怎么做呢?
  10. 如果某些服务响应变慢了,但是实际大盘使用率又不高,这个情况怎么定位?
  11. 某段时间 TIME_WAIT 较多,这是一定有问题吗?如果是正常情况的话,业务上有什么表现?

《参考解析》

跨语言链路追踪的底层怎么拼

trace 的连续性靠的是上下文透传,跟服务用什么语言写的无关:入口处生成或解析出 traceId,同时为当前这段调用生成 spanId 并记住 parentSpanId,然后通过进程边界把这些字段带出去。带出去的方式分几类:HTTP 用请求头(W3C Trace Context 的 traceparent/tracestate,或 Jaeger 的 uber-trace-id、SkyWalking 的 sw8),RPC 框架挂在协议附件的隐式参数里,MQ 消息放进消息属性(发送时注入、消费时提取),跨线程和异步回调则靠上下文快照传递,否则新线程里取不到 traceId,链路就断了。

不同语言能拼到一起的前提是协议统一,而不是 SDK 统一:各语言各自实现自己的埋点 SDK,只要都把头部字段按同一套规范序列化和解析,就能拼成一棵树。真正容易出问题的地方是协议不一致(A 用 Zipkin 的 B3、B 用 sw8,需要网关或 sidecar 做字段转换)、自研中间件没做注入(MQ 尤其常见)、以及线程池/CompletableFuture 里上下文丢失。判断链路质量可以看采样率是否一致、跨服务 span 的时间戳时钟是否对齐(机器时钟漂移会让父子 span 时间乱序),以及有没有孤儿 span。

服务响应变慢但大盘利用率不高,怎么定位

大盘利用率是平均值,会掩盖局部热点,所以第一步是换维度下钻:按实例看(是不是只有一两个实例慢——可能是有慢 SQL、GC 频繁、磁盘坏道或宿主机被邻居挤占,负载均衡又没摘掉它)、按接口看(某个低频高耗时接口拖高了整体耗时)、按依赖看(数据库、缓存、第三方接口分位数的变化)。

典型的几种根因:① 连接池/线程池排队——CPU 不高但请求都在等,队列长度和等待时间会直接暴露;② 锁竞争与串行化点,比如全局锁、单分片热点 key、数据库行锁;③ GC 停顿或内存不足引发 swap,平均 CPU 看着不高但 STW 时全站卡顿,看 GC 日志和暂停时间;④ 下游依赖变慢被传导上来,自己这层只是被堵住;⑤ 网络层问题,重传、丢包、DNS 解析变慢、跨机房抖动。工具上就是「分位数 + 火焰图 + 依赖拓扑」三件套:先看 P99 而不是均值,再用链路追踪找到耗时占比最大的 span,最后对着那一段看线程栈和系统指标。

TIME_WAIT 多是不是一定有问题

不一定,先分清它出现在哪一侧。TIME_WAIT 由主动关闭连接的一方持有,持续 2×MSL(Linux 上固定 60 秒),作用是保证最后一个 ACK 能重传、并让本次连接的迟到报文在网络中消散,避免污染复用同一四元组的新连接。所以如果服务是主动关闭方,且业务用短连接、QPS 又高,那出现大量 TIME_WAIT 是正常现象——比如 HTTP 短连接压测机、反向代理到上游、爬虫类客户端。

真正要处理的情况是它开始影响可用性:netstat -s 里出现 TIME_WAIT 相关的端口耗尽、cannot assign requested address 报错,或者同机连接数逼近 ip_local_port_range 上限。业务侧的应对优先级应该是:改成连接池/长连接复用(收益最大)、让客户端而不是服务端主动关闭、用 SO_REUSEADDR 允许复用地址、必要时再把 tcp_tw_reuse 打开(对出向连接有效,tcp_tw_recycle 在 NAT 环境下会误伤、已被内核移除,不要提它)。业务上的表现通常是:新连接建立偶发失败、握手耗时上升、监控里连接数曲线呈锯齿但吞吐正常。

Agent 诊断的评测与 RT 长尾

评测首先要解决「什么算对」:把线上历史故障整理成带标准答案的评测集(known-item set),每条包含告警、指标/日志片段、最终根因和处置动作;指标上分别看根因定位准确率(Top-1/Top-3 命中)、证据引用正确率(结论里引用的指标/日志是否真实存在,防幻觉)、以及端到端耗时和人工节省时间。没有标准答案的部分可以用 LLM-as-judge 加人工抽检双轨:judge 只看「结论是否有证据支撑、是否与人工结论等价」,同时保留一批人工标注的锚点样本用来校准 judge 本身。

RT 的治理不能只看均值——告警诊断天然是长尾分布(有的告警要等窗口数据、有的要串好几次工具调用)。做法是:把耗时按阶段拆开(取数、检索、模型推理、工具调用)看各段的 P50/P95/P99,找出长尾主要落在哪一段;对慢在工具调用的做并行化与超时兜底,对慢在等数据的做提前预取和窗口裁剪,对慢在模型的做分级策略(先用小模型出初判、必要时再升级到强模型),并设定整条链路的时间预算,超预算就输出「当前能确定的部分 + 待人工确认」而不是无限等下去。同时要监控长尾比例这个指标本身,否则优化掉 P50 也不会改善值班体验。

让模型直接执行 SQL 的安全边界与脱敏

原则是「模型永远不持有可写权限,也不直接面向生产库」。落地分四层:① 权限层——给 Agent 单独开只读账号,只授权必要的库表,禁止 DDL 和写操作,生产库走只读从库;② 工具层(也就是 MCP / Tool 的实现里)——不把用户或模型给的字符串直接拼成 SQL,而是暴露结构化参数(表名白名单、时间范围、过滤条件)由工具自己拼装,并对结果强制 LIMIT、强制带时间条件、加执行超时和扫描行数上限,避免一条全表扫把库拖垮;③ 数据层脱敏——手机号、身份证、邮箱、地址、密钥在离开数据库前就处理掉,优先在 SQL 里直接不查这些列,必须查的用视图或在工具返回前做掩码(只留尾号/哈希),不要指望「到了模型再删」;④ 审计层——记录每一次 SQL、调用者、耗时和返回行数,异常访问可回溯、可熔断。

一个常被追问的点是:脱敏放在模型侧做一定不安全,因为原始数据已经进入了上下文,可能被写进日志、缓存或后续对话;所以脱敏要尽量靠前——能在 SQL 层不取就不取,其次在工具层掩码,模型只看脱敏结果。