百度一面:链路追踪、Agent 诊断评测与 RAG 管理
- 轮次
- 一面
- 时间
- 2026-09
- 来源
- 牛客网
《面试题目》
- 项目深挖:既然说沿 trace,如果你们不同的服务用的是不同的代码,那 trace 里面应该能把这些信息揉进来,这个底层你了解过吗?
- 正常说一些请求打过来,过了网关,从 A 调 B、调 C,最后可能是 MQ、TDDL、Redis,因为一个服务可能挂了多个 MySQL,你们怎么知道现在对应的是哪个实例?
- 你说你们做了评测,说一下具体是怎么评测的?模型怎么知道你的结果是对的?
- 怎么提高 Agent 效率?
- 一个告警出来到你拿到的时候可能已经 10 分钟了,你的 Agent 诊断还需要时间,你们的 RT 有多少?
- 这个 RT 应该是一个正态分布,肯定也有长尾的一些,长尾有测吗?
- 你们 RAG 怎么管理的,怎么控制新旧?
- 定位到 DB 的时候,你们会具体执行 SQL 吗?让模型直接执行吗?
- 脱敏最好怎么做呢?
- 如果某些服务响应变慢了,但是实际大盘使用率又不高,这个情况怎么定位?
- 某段时间 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 层不取就不取,其次在工具层掩码,模型只看脱敏结果。