阿里巴巴 · 淘天

AI 应用研发工程师一面面经

完整信息

44 条问法 · 43 道题

本篇目录

大家好,我是Yuka。

9.14下午面的,9.17官网流程终止。阿里味很重,面试官不开摄像头,开口就是Skill、MCP、Harness、MetaHarness,我像在报菜名,报着报着就卡壳了。

上来没太多寒暄,自我介绍后直接项目拷打。手撕最长有效括号,第二道岛屿数量先DFS再BFS。后面全程场景题,从Agent架构问到缓存一致性,从RAG排查问到线程池配置。

总结下来,我输在Harness和一致性场景上,答得太虚了。这篇文章把28道题全部复盘一遍,每道都附上我现场的回答和事后补的思考。准备阿里Agent岗的朋友,建议收藏。

手撕一:最长有效括号
用栈。栈底放一个-1作为哨兵,遍历字符串,遇到左括号入栈,遇到右括号先弹出,如果栈空就把当前索引入栈作为新的哨兵,否则当前索引减栈顶就是当前有效长度。

时间复杂度O(n),空间O(n)。也可以用动态规划,dp[i]表示以i结尾的最长有效括号长度。现场我写了栈版本,面试官没追问。

手撕二:岛屿数量,先DFS再BFS
DFS:遍历矩阵,遇到'1'就岛屿数加一,然后递归把相连的'1'都标记为'0'。BFS:遇到'1'就入队,然后层序遍历把相连的'1'标记为'0'。

DFS用递归,BFS用队列。两个版本都写了。面试官追问:如果矩阵很大,DFS递归会不会栈溢出?答:会,所以大规模场景用BFS或者迭代式DFS。

  1. 自我介绍
    常规。我重点讲了CR Agent项目,强调了对Agent架构、工具调用、上下文管理的理解,以及实际踩过的坑。

  2. 你这个CR Agent具体解决什么问题
    CR Agent是代码审查Agent,解决的是人工Code Review效率低、容易漏检的问题。它自动扫描代码变更,检查代码规范、潜在bug、安全漏洞,生成审查报告。

具体流程是:监听Git webhook,拉取diff,解析变更文件,对每个文件做静态分析加LLM审查,最后汇总成报告推送到PR评论区。我负责的是审查策略设计和多Agent协作部分。

踩过的坑:早期全量扫描,大仓库一次要跑半小时。后来改成增量扫描加高风险区域聚焦,降到3分钟。

  1. 为什么用Agent,不用固定Workflow
    固定Workflow适合流程固定的场景,但代码审查的复杂度在于不同类型的代码需要不同的审查策略。比如SQL注入检测需要看数据库操作,XSS检测需要看前端渲染,并发bug需要看锁的使用。这些不是固定步骤能覆盖的。

Agent的优势是动态决策——它能根据代码类型自动选择审查策略,遇到不确定的还能追问或查文档。我实际对比过,固定Workflow的漏检率是Agent的2倍多,因为Workflow只能覆盖预设规则,Agent能发现规则之外的问题。

当然Agent也有代价,延迟更高、成本更贵。所以我的设计是混合:简单规则用Workflow快速过,复杂逻辑用Agent深度审。

  1. Workflow和自治Agent的区别是什么?什么场景更适合Workflow
    Workflow是预设路径,步骤固定,稳定高效可预测。自治Agent是动态决策,灵活但成本高、不可预测。

Workflow更适合:流程标准化程度高、步骤明确、不需要动态推理的场景。比如订单处理、数据ETL、定时报表、CI/CD流水线。这些场景用Agent是浪费,Workflow又快又稳。

自治Agent适合:任务复杂多变、需要动态推理、工具组合不固定的场景。比如代码审查、复杂问题解答、行程规划。

我踩过的坑:早期把定时报表也用Agent做,结果每次跑都要调LLM,成本高还不稳定。后来改回Workflow,成本降了90%。

  1. ReAct和Plan-and-Execute怎么选
    ReAct是边走边看,Think→Act→Observe循环,灵活但效率低,容易死循环。Plan-and-Execute是先规划再执行,效率高但规划可能不准。

选型看任务特征:任务明确、步骤可预测的用Plan-and-Execute。任务模糊、需要动态探索的用ReAct。

我项目里用的是混合模式:Planner先生成粗粒度计划,每个步骤内部用ReAct执行。如果执行不下去,回退到Planner重新规划。这样既有规划的效率,又有ReAct的灵活性。

踩过的坑:纯ReAct在复杂任务上容易路径震荡,反复调同一个工具。后来加了规划层才解决。

  1. Skill、MCP、Function Calling三者区别是什么
    Function Calling是模型输出结构化调用指令,框架解析后执行。它是模型层面的能力,不涉及工具怎么发现、怎么管理。

MCP是标准化协议,定义了工具怎么暴露、怎么发现、怎么调用、怎么传参。它解决的是工具集成的标准化问题——一个MCP Server写一次,所有支持MCP的Agent都能用。

Skill是面向场景的能力封装,一个Skill可能包含多个Tool调用,加上Prompt模板和业务逻辑。比如“查天气”是Tool,“规划行程”是Skill。

三者关系:Function Calling是底层机制,MCP是标准化协议,Skill是业务封装。2026年MCP已经演进到无状态核心,支持云原生水平扩展,Agent Plugins 1.0.0规范用plugin.json标准化了Skill打包。

  1. 你项目里的Skill怎么设计?输入输出契约是什么
    每个Skill是一个独立模块,暴露name、description、inputSchema、execute。inputSchema用JSON Schema定义,明确参数名、类型、是否必填、枚举值。输出统一格式,包含status、data、error、metadata。

契约设计的关键是稳定——一旦发布,参数不能随便改,要加版本号。我踩过坑:Skill参数从query改成search_query,结果所有调用方都挂了。后来加了版本兼容层,旧参数名自动映射到新参数名。

另外,Skill要有超时和重试配置,这些也在契约里定义,调用方不用关心底层实现。

  1. Skill怎么渐进式加载?工具特别多怎么办
    渐进式加载分两步:先加载Skill索引,只包含名称和一句话描述,总token控制在5000以内。模型判断需要哪类Skill后,再加载该类下所有Skill的完整Schema。

工具特别多的时候,用向量检索做筛选。每个Skill的brief做embedding存向量库,用户query进来算相似度,取Top-20加载完整描述。这样1000个Skill也只加载20个,token控制在2000以内。

我项目里Skill多的时候Prompt从8000 token降到1500 token。2026年Agent Plugins规范让Skill可以跨框架复用,不用为每个框架维护独立包装层。

  1. MCP获取工具列表的完整流程讲一下
    MCP Client启动时连接MCP Server,发送initialize请求,Server返回能力声明,包括支持的工具列表。Client收到后缓存工具列表,后续调用时直接引用。

如果Server支持动态工具发现,Client可以发tools/list请求获取最新工具列表。工具调用时,Client发tools/call请求,带上工具名和参数,Server执行后返回结果。

2026年MCP无状态核心设计让Server可以水平扩展,Client通过标准HTTP header路由,不需要深度包检测。负载均衡用标准轮询,比自研路由协议更可靠。

  1. 如果有100个MCP工具,Agent怎么选?怎么保证稳定性
    100个工具不能全塞进Prompt。分层路由:第一层按类别粗筛,第二层在类别内用向量相似度精排,取Top-5加载完整描述。

稳定性保障:工具调用前加参数校验,格式不对直接拦截。工具调用后加结果校验,返回异常就重试或降级。加熔断机制,连续失败就切断该工具,避免拖垮整个Agent。

我踩过坑:100个工具全加载,Prompt爆炸,模型选错工具。后来加了分层路由,准确率从60%提到90%。

  1. 你怎么理解Harness?Harness和Agent框架的关系是什么
    Harness是Agent的运行时框架,负责管理执行循环、工具调用、状态管理、异常处理。它比Agent框架更聚焦在“运行”这一层。

Agent框架更宽泛,可能包括Harness加开发工具加部署工具。Harness是Agent框架的核心组件,但不是全部。

DeepSeek Harness的核心理念是“一切皆插件”,模型适配器、工具注册表、会话管理都是可替换的插件。和LangChain的区别是,LangChain是框架优先,你按它的方式写代码;Harness是组合优先,所有组件都是插件,你可以替换任意模块。

2026年Harness Engineering成为Agent工程化的主流思路,不是从零搭框架,而是在成熟运行时上做插件化扩展。

  1. 看过DeepSeek Harness吗?和Claude Code有什么区别
    看过。DeepSeek Harness是开源的Agent运行时,基于Cordis元框架,所有组件都是插件。Claude Code是Anthropic的闭源Agent产品,聚焦在代码场景。

核心区别:Harness是运行时,Claude Code是应用。Harness提供基础能力,Claude Code提供开箱即用的体验。Harness可以定制,Claude Code不能。

我实际用下来,Harness适合需要深度定制的团队,Claude Code适合快速上手。2026年Harness生态里有个ViNote项目,用SQLite做会话恢复,流式交互串联视频检索、下载、转写和笔记生成,架构很干净。

  1. Agent上下文超限怎么处理?滑动窗口和摘要压缩各自牺牲了什么
    滑动窗口牺牲了早期上下文,保留最近对话。优点是简单快,缺点是会丢失早期的重要信息。摘要压缩牺牲了细节,保留关键结论。优点是不会丢关键信息,缺点是摘要本身可能丢信息,而且有生成开销。

我项目里用的是组合策略:滑动窗口保留最近N轮,超出部分做结构化摘要——实体、事件、结论、待办分开存。实体和结论保留原文,事件和待办用简短描述。检索时按需召回。

踩过的坑:纯摘要压缩,结果关键数字被压缩没了。后来改成结构化摘要,关键信息保留原文。

  1. 工具调用失败怎么兜底?重试策略怎么设计
    三层兜底。第一层:区分可重试和不可重试错误。超时、网络抖动、限流可重试。参数错误、权限错误不可重试。

第二层:重试策略用指数退避,第一次延迟1秒,第二次2秒,第三次4秒,最多3次。

第三层:重试失败后降级。主工具挂了切备用,备用也没有就返回缓存或默认值。

我踩过坑:重试没加去重,结果下单接口重试导致重复下单。后来加了request_id做幂等键才解决。另外,重试要有全局限流,避免重试风暴打垮下游。

  1. 多Agent写同一个文件怎么避免冲突
    用分布式锁或乐观锁。分布式锁用Redis,文件路径做key,获取锁才能写。乐观锁用版本号,写之前检查版本,不匹配就重试。

我项目里用的是乐观锁加重试。因为分布式锁在Agent场景下容易死锁——一个Agent持有锁但挂了,其他Agent一直等。乐观锁没这个问题,版本不匹配就重试,最多重试3次。

更细粒度的是分段锁,不同Agent写不同区域。2026年A2A协议里有任务编排和状态管理,多Agent协作可以通过A2A的任务锁机制避免冲突,比自研锁更标准。

  1. Agent长任务跑失败,怎么定位是模型、检索还是工具的问题
    分段排查。先看日志,每个步骤的输入输出都记下来。如果模型输出的Thought不合理,是模型问题。如果检索结果不相关,是检索问题。如果工具返回错误,是工具问题。

我实际项目里加了一个“决策链路追踪”,每个决策点记录四件事:输入状态、决策内容、备选方案、最终选择。复盘时按trace_id查询,就能看出哪一步出了问题。

踩过的坑:长任务失败,排查半天发现是中间某步工具返回了脏数据,模型基于脏数据做了错误决策。后来加了工具结果校验才解决。

  1. 长任务从5分钟变成20分钟,怎么分析延迟
    分段计时。把任务拆成子步骤,每个步骤记录耗时,找出最慢的步骤。

常见原因:模型调用变慢(上游限流或模型升级)、工具调用变慢(下游服务慢)、检索变慢(向量库索引膨胀)、上下文变长(token多了推理慢)。

我踩过坑:任务变慢,排查发现是上下文越来越长,LLM推理时间线性增长。后来加了上下文压缩,延迟降回5分钟。

工具层面,用Prometheus记录每个步骤的P50/P95/P99,Grafana展示,一眼看出瓶颈在哪。

  1. 线上高并发场景,Agent服务怎么限流、降级、熔断
    限流用令牌桶,每秒生成固定令牌,请求消耗令牌,桶空就拒绝。降级分三级:一级切备用模型,二级从Agent降到Workflow,三级返回友好错误。熔断用Hystrix或Sentinel,连续失败超阈值就切断,过段时间半开试探。

我踩过坑:没做限流,突发流量把模型API打爆,所有请求都超时。后来加了令牌桶,超限请求排队或拒绝,系统稳定多了。

Agent场景的特殊性是单次调用成本高、延迟长,所以限流要更保守,降级要更果断。

  1. RAG召回高但答案不准,怎么排查
    召回高说明相关文档找到了,答案不对,问题在生成或上下文构建。

排查:第一,看Rerank后的Top-K有没有正确答案。第二,看上下文拼接顺序,关键信息是不是在中间,调整到开头结尾。第三,看Prompt模板,指令是否明确。第四,看LLM本身,换模型或调temperature。第五,看召回内容是否有冲突,多文档说法不一致时加冲突检测。

我踩过坑:召回文档有正确答案,但LLM被无关信息干扰答错。后来加了Rerank和上下文压缩才解决。

  1. 文档切分策略怎么选?Markdown没标题怎么切
    切分粒度看文档类型:技术文档512 tokens,法律合同256 tokens,代码按函数切分。重叠窗口10%-15%,保证跨chunk的句子不被截断。

Markdown没标题时,按段落和空行切分。连续两个换行视为段落边界,代码块和表格整体保留不切。如果段落超长,按句子边界切。

踩过的坑:统一用512,结果法律合同条款被切碎,召回效果差。后来按文档类型动态调整才解决。

  1. BM25和向量检索怎么融合?RRF的k值怎么设
    用RRF(倒数排名融合)。每路召回Top-K,按排名算分:score = Σ 1/(k + rank_i)。RRF不需要归一化分数,直接融合排名。

k值通常设60。k越小,排名靠前的权重越大;k越大,排名影响越平滑。我实际用60,效果稳定。融合后再用Reranker做二次精排,取Top-5送LLM。

踩过的坑:k值设太小,头部结果权重过大,长尾好结果被淹没。后来调回60才平衡。

  1. Java线程池核心参数怎么配?IO密集和CPU密集分别怎么设
    核心线程数:IO密集型设2倍CPU核数,CPU密集型设CPU核数+1。最大线程数设核心的2-3倍。队列用有界队列,避免OOM。拒绝策略用CallerRunsPolicy,让提交任务的线程自己执行,起到背压作用。

我调过线程池,核心数设太小任务排队,设太大上下文切换开销高。Agent的工具调用是IO密集型,核心线程数设为CPU核数的2倍。

2026年Java虚拟线程已经正式可用,单线程仅占几百字节内存,支持百万级并发,IO密集型场景用虚拟线程比传统线程池更合适。

  1. ThreadLocal原理,为什么会内存泄漏
    每个Thread内部有ThreadLocalMap,key是ThreadLocal对象(弱引用),value是存储的值(强引用)。线程池里的线程复用,ThreadLocal没remove,key被GC后value还挂在Entry上,导致内存泄漏。

解决:每次用完在finally里remove。我踩过坑:线上OOM,MAT分析发现ThreadLocalMap里堆了大量Session对象,后来在Filter里统一remove才解决。

虚拟线程场景下ThreadLocal的使用要更小心,因为虚拟线程创建成本极低,如果每个虚拟线程都创建独立ThreadLocal不清理,内存压力比传统线程池更大。

  1. MySQL深分页为什么越往后越慢?怎么优化
    LIMIT 100000, 10会先扫描前100000行再取10行,越往后扫描越多,所以越慢。

优化:第一,用游标分页,记录上一页最后一条的ID,下一页用WHERE id > last_id LIMIT 10。第二,用覆盖索引,SELECT id FROM table LIMIT 100000, 10先查ID再回表。第三,业务上限制最大页数,不允许翻太深。

我踩过坑:后台管理列表翻到后面几页直接超时,后来改成游标分页才解决。

  1. Redis缓存击穿、穿透、雪崩分别怎么解决
    穿透:查不存在的数据,缓存和数据库都没有。解决:布隆过滤器拦截,或者空值缓存设短TTL。

击穿:热点key失效瞬间大量请求打到DB。解决:互斥锁,只允许一个线程查DB,其他等待。

雪崩:大量key同时失效或Redis挂了。解决:过期时间加随机偏移,Redis高可用,本地缓存兜底,限流熔断。

我踩过坑:热点key没加互斥锁,失效瞬间DB被打爆。后来加了互斥锁才解决。

  1. 先更新数据库再删缓存,删缓存失败了怎么办
    这是Cache Aside模式的经典问题。删缓存失败会导致缓存里是旧数据,数据库是新数据,不一致。

解决方案:第一,删缓存失败就重试,用消息队列异步重试。第二,用binlog订阅,数据库变更后自动删缓存。第三,设短TTL兜底,即使删失败,过期后也会自动失效。

我踩过坑:删缓存失败没重试,结果缓存和数据库不一致持续了几小时。后来加了消息队列重试才解决。

  1. 如果消息队列重试删除缓存,但旧值又写回来了,怎么保证一致性
    这是并发场景下的经典问题。线程A更新数据库,线程B读数据库旧值,线程B写缓存旧值,线程A删缓存,结果缓存里是旧值。

解决方案:第一,延迟双删,更新数据库后删一次缓存,延迟几百毫秒再删一次。第二,用版本号,缓存里存版本号,写缓存时检查版本,旧版本不写。第三,串行化,同一数据的读写走同一个队列。

我踩过坑:没做延迟双删,高并发下缓存和数据库不一致。后来加了延迟双删才缓解。更彻底的是用binlog订阅,数据库变更后删缓存,保证顺序。

  1. AI Coding:写一个商品计价系统,优惠策略可以随时更新,你会怎么设计
    用策略模式加配置化。每种优惠策略是一个独立类,实现统一接口。策略配置存数据库或配置中心,运行时动态加载。

计价流程:基础价格→应用优惠策略链→计算最终价格。优惠策略可以叠加,也可以互斥,用规则引擎控制。

我踩过坑:早期优惠逻辑硬编码,改一次要发版。后来改成配置化,运营自己就能改,不用开发介入。

2026年AI Coding工具可以辅助生成策略类,但核心的规则引擎和边界条件还是要人工设计。优惠计算涉及金额,必须加校验和测试,不能全靠AI生成。

反问
我问了三个问题:团队主要做商家侧还是用户侧Agent?面试官说都有,商家侧偏工具,用户侧偏交互。技术栈是Java为主吗?答:Java为主,部分Python。这个岗位更偏平台还是业务落地?答:平台和业务都有,看具体项目。

写在最后
阿里淘天一面强度不低,但不像字节那样追着代码细节打,更像在考你有没有真正做过Agent工程。我输在Harness和一致性场景上,答得太虚了。

面试官问的都是“你怎么设计”“出问题了怎么办”,不是背概念能过的。尤其是缓存一致性那几道,问得很深,没有真正踩过坑的人根本答不上来。

祝大家面试顺利,别像我一样凉得这么快 🙏

本篇目录
  1. 01
  2. 02
  3. 03
  4. 04
  5. 05
  6. 06
  7. 07
  8. 08
  9. 09
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33
  34. 34
  35. 35
  36. 36
  37. 37
  38. 38
  39. 39
  40. 40
    AI Coding:写一个商品计价系统,优惠策略可以随时更新,你会怎么设计
  41. 41
  42. 42
  43. 43
  44. 44

同作者面经

展开其余 1 篇收起其余 1 篇

相关公司