面试题库
共 328 题,当前筛选 1 题。
课程全部30 天从前端工程师到 Agent 工程师5 天提示词工程零基础Claude 高效使用:从对话到 Claude CodeCodex 与 OpenAI Agents SDK 高效使用7 天 MCP:把工具接进任何 Agent7 天 Agent Skills:把经验做成可复用能力5 天上下文工程14 天 RAG:从检索到可信回答14 天用 Agent 搭一条 AI 短剧生产线
标签
全部#orchestration1#reliability10#cost9#observability7#architecture5#streaming5#api-design4#deployment4#distributed-systems4#error-handling4#idempotency3#message-bus3
还有 92 个标签收起标签
#operations3#rag3#security3#tool-calling3#cost-control2#langgraph2#latency2#mcp2#model-routing2#multi-agent2#ordering2#protocol2#react2#redis-streams2#routing2#sse2#system-design2#agent-design1#agent-loop1#agent-quality1#async1#atomicity1#auth1#behavioral1#capacity-planning1#checkpointing1#chunking1#communication1#compression1#concurrency1#context-compression1#context-engineering1#data-modeling1#database1#debugging1#deliberate-practice1#docker1#documentation1#engineering-tradeoffs1#evaluation1#event-driven1#fan-out1#forking1#framework-design1#framework-selection1#interrupt-merge1#interview-prep1#isolation1#knowledge-organization1#lease1#loop-guard1#mobile1#multi-tenancy1#nodejs1#performance1#persistence1#pgvector1#portfolio1#prompt-engineering1#provider-abstraction1#quiet-hours1#ranking1#rate-limiting1#redis1#reflection1#reporting1#rerank1#retrieval-quality1#retry1#retry-semantics1#rrf1#sandboxing1#scalability1#schema-design1#secrets-management1#self-assessment1#self-presentation1#service-architecture1#session-management1#sharding1#state-machine1#state-management1#stateless1#structured-output1#system-prompt1#testing1#tool-execution1#tracing1#trade-offs1#transport1#ux1#vector-database1
30 天从前端工程师到 Agent 工程师
D15 多 Agent 模式全景(Router/Supervisor、Planner-Executor、Critic、Swarm、Blackboard)与何时不该用;LangGraph 入门
LangGraph 里节点、边、状态分别扮演什么角色?如果不用框架,你自己会怎么实现?In LangGraph, what roles do nodes, edges and state play? If you had no framework, how would you implement it yourself?
国内高频海外高频进阶#langgraph#orchestration#state-management分析过程 · 先想清楚再作答
- 题眼在后半句。只答三个概念的定义,面试官会认为你读过文档;能说出「不用框架会难受在哪」,才证明你知道框架替你解决了什么。这类题的通用解法是:先讲自己手写的版本,再讲框架把哪几处收敛了。
- 先给手写版:一个循环,里面一串条件判断决定下一步走哪,中间用一个大对象在各步之间传数据。写到第三个分支就会撞上三件事——两步都往同一个字段写,是覆盖还是追加,你要在每个分支里手写一遍合并逻辑;中间过程全在局部变量里,出错只能靠打印;进程一挂就从头重来,已经花掉的模型调用钱白付。
- 然后一一对上:节点是一个普通函数,读全量状态、返回只含改动字段的增量;边是节点之间的连接,无条件边写死顺序,条件边在运行时决定去哪;状态是一张字段表,每个字段是一条独立通道,通道上挂着合并规则。
- 重点讲第三条,因为它是最容易被略过、也最值钱的一条:**合并规则是声明在字段上的,不是写在节点里的**。这意味着新增节点时不需要考虑「我该怎么和别人的写入合并」,字段自己知道;也意味着并行写同一个字段时行为是确定的,而不是取决于谁先返回。
- 配两个具体的坑,证明你真跑过:一是在节点里原地修改状态(比如直接往数组里 push)会绕过合并规则,单线程时察觉不到,并行时变成偶发覆盖;二是加了节点没连边不会报错,表现只是那个节点永远不执行,只能靠逐节点追踪发现。
- 可以预期的追问:那你为什么不直接自己写?答:三要素本身很轻,核心逻辑几十行就能手写出来——框架真正值钱的是检查点与恢复、并行执行、以及每一步的可观测,这三样自己写的成本远高于三要素本身。顺带说明 Java 和 Swift 没有官方 LangGraph,真要在这两门语言里做,就是把这三要素手写一遍。
How to reason about it · think before answering
- The hinge is the second half. Defining the three concepts only proves you read the docs; explaining what hurts without a framework proves you know what it buys you. The general move for this family of questions is: describe your hand-rolled version first, then name what the framework collapsed.
- Hand-rolled version: a loop, a chain of conditionals picking the next step, and one big object carrying data between steps. By the third branch you hit three walls — when two steps write the same field, is it overwrite or append, and you hand-write that merge in every branch; intermediate state lives in local variables so debugging means print statements; a crash restarts from zero and the model calls you already paid for are wasted.
- Then map them: a node is an ordinary function that reads the whole state and returns a delta containing only what it changed; edges connect nodes, unconditional ones fix the order and conditional ones decide at runtime; state is a table of fields where each field is its own channel carrying a merge rule.
- Dwell on the third, which is the most skipped and most valuable point: the merge rule is declared on the field, not written inside the node. Adding a node therefore requires no thought about how to combine with other writers, and parallel writes to one field behave deterministically instead of depending on who returns first.
- Add two concrete traps to show you have actually run this: mutating state in place inside a node bypasses the merge rule — invisible single-threaded, an intermittent overwrite once things run in parallel; and adding a node without wiring an edge raises no error at all, it simply never executes, which only per-node tracing reveals.
- Expect: so why not just write it yourself? Because the three primitives are genuinely light — a few dozen lines. What the framework actually sells is checkpointing and recovery, parallel execution, and per-step observability, all of which cost far more to build than the primitives. Mention too that there is no official LangGraph for Java or Swift, so in those languages you do hand-roll exactly these three.
答题要点
- 节点是普通函数:读全量状态,返回只含改动字段的增量,不在节点里原地改状态
- 边决定执行顺序:无条件边写死,条件边在运行时决定下一步去哪(Supervisor 就靠它)
- 状态是一张字段表,每个字段一条通道,通道上挂合并规则——规则声明在字段上而不是写在节点里
- 不用框架会撞三堵墙:合并逻辑在每个分支手写一遍、中间过程只能靠打印、进程挂了从头重来
- 两个真实的坑:原地改状态绕过合并规则(并行时偶发覆盖)、加了节点没连边不报错只是永不执行
- 框架真正值钱的不是这三要素,而是检查点恢复、并行执行和逐步可观测
Key points
- A node is a plain function: read the full state, return a delta of changed fields only, never mutate in place
- Edges set execution order: unconditional edges are fixed, conditional edges decide the next hop at runtime — that is what a supervisor uses
- State is a table of fields, each field a channel carrying a merge rule declared on the field rather than inside nodes
- Without a framework you hit three walls: hand-written merges in every branch, no visibility into intermediate steps, and full restart after a crash
- Two real traps: in-place mutation bypasses the merge rule and causes intermittent overwrites under parallelism; an unwired node raises no error, it just never runs
- What the framework really sells is checkpoint recovery, parallel execution and per-step observability — not the three primitives themselves