外观
Q01–Q04:Agent 与模型边界
这组必学。回答中的源码入口指向交付包,先打开文件再解释;不要把“用了框架”当作已经回答实现。主问题参考答案可用 60–90 秒表达,追问用 30–60 秒。
Q01 Agent 到底是什么形式的代码?
**考察目的:**分清模型、Agent、工作流和执行器。**难度:**基础,但属于一票识别“只会术语”的问题。
**主问题:**你简历说有生成 Agent 和评审 Agent,它们是两个模型、两个服务,还是两个函数?
直接答案与 STAR
Agent 不是某一种部署单位。这里可以把它理解成:角色指令、被允许看见的上下文、模型调用、工具权限,以及处理模型结果的控制逻辑组合。两个 Agent 可以调用同一个模型,通过不同上下文和工具权限承担不同职责;也可以为了成本、能力或供应商隔离使用不同模型。进程数量不决定 Agent 数量。
教材系统的外层流程由 LangGraph 明确编排,生成和评审节点内部调用模型。它属于受约束的 Agent 工作流,不是让模型任意决定所有步骤。程序决定必须审校、最多修订几次、何时等待人工,模型决定具体内容或提出工具请求。
**STAR|简历事实 + 复现解释:**S:HanLink 需要制作课文、词汇、练习及素材。T:我的职责包括教材生成与审校。A:简历描述将生成和评审职责分开,由 LangGraph 编排,并隔离上下文与工具权限;在学习复现中可沿节点函数查看这个组合。R:简历记载教材制作从教研从零编写转为系统生成后复核,审核通过用于教学;没有可据此声称的准确率或降本百分比。
第一层追问:只是换一段 system prompt,就算职责隔离了吗?
**直接答案:**只隔离了角色描述,没有建立数据与权限边界。应分别构建消息列表,不把生成者的自我评价传给评审;评审看到候选教材、权威资料、规则和必要的历史版本。服务端工具白名单与参数校验才决定它能做什么。
**STAR|假设方案:**S:评审模型读到了生成者的“已经全部检查通过”。T:避免自我背书影响判断。A:重建评审上下文,删去生成者推理或评价,只保留待审内容与证据。R:验收是能对同一候选独立产生问题报告,且越权工具请求被服务器拒绝;不能据此推导评审一定正确。
第二层追问:两个 Agent 调用同一模型,会不会一起犯错?
**直接答案:**会。上下文隔离减少相互影响,不消除共享知识偏差和相关性错误。关键规则使用确定性校验;语义问题使用独立证据、固定评测集和人工复核。换模型可能增加多样性,但也引入成本和输出差异,需要评测,而不是默认越多越好。
**STAR|学习复现:**S:生成和评审都可能忽略地区禁用表达。T:发现相关性漏检。A:固定一条带违规词的样本,分别运行规则检查与模型评审,记录谁检出。R:用漏检记录判断是否需要补规则或换评审模型,不把“有两个 Agent”当作质量保证。
分支追问:如果流程完全固定,为什么还叫 Agent?
**直接答案:**应如实描述自主决策范围。固定流转本身是 Workflow;若节点仅一次生成,没有工具选择或行动循环,称角色化模型节点也准确。产品名称不是架构优劣证据。面试时可以说“外层确定性工作流,内部生成/评审角色受约束调用模型和工具”。
**STAR|假设方案:**S:团队把所有调用模型的代码都叫 Agent。T:让设计评审能够判断真实复杂度。A:画出程序分支和模型决策分别在哪里。R:评审者能据此定位责任与测试边界,不依赖名称判断能力。
**优秀回答:**能画出一次调用的数据流,说明角色与进程无必然关系,并承认双 Agent 的局限。常见误区:“一个 Agent 就是一个大模型”“换 prompt 就绝对独立”“Agent 必须自主循环”。
关联学习:Agent 代码形态、模型上下文。
实际源码:system/app/graph.py 的 context()、generate()、review();system/app/providers.py 的 run_model()。
验证与实验:system/tests/test_system.py::test_context_and_tool_permissions(角色上下文与权限);L07 工具越权。比较两角色实际拿到的字段,不只看角色提示词。
Q02 Function Calling 是模型在执行函数吗?
**考察目的:**工具调用协议、权限、安全和副作用。**难度:**核心。
**主问题:**从模型提出“生成图片”到实际得到图片,中间发生了什么?
直接答案与 STAR
模型返回结构化的工具名、调用标识和参数。服务器解析请求,校验工具是否在该角色的白名单内、参数 Schema 是否合规、内容版本是否仍有效,然后调用执行器或创建异步任务。执行结果再关联回调用标识,必要时交给模型继续处理。真正的网络请求、文件写入和数据库变更由程序执行。
Function Calling 通常指这种模型提出函数调用的机制;Tool Calling 是更宽的术语,不同厂商对内置工具和自定义函数的分类不同。本系统的图片/TTS/视频是受控工具接口,耗时执行交给后台任务。模型说“已完成”不等于任务真的完成。
**STAR|学习复现:**S:素材工具有成本和外部副作用。T:让模型能申请制作,但不能直接修改任意文件或版本。A:用服务端注册表分发工具请求,参数校验后关联已审核内容版本创建任务。R:证据是工具审计记录、素材任务记录和真实文件校验;模拟服务的结果只证明编排,不证明外部图片或 TTS 能力。
第一层追问:模型请求了一个未注册函数,怎么办?
**直接答案:**拒绝,记录角色、工具名和错误类别,返回受控错误。不能 eval 工具名,也不能把模型参数拼成 shell。是否让模型重新选择由有限次数的控制逻辑决定;权限错误不能靠扩大权限解决。
**STAR|学习复现:**S:让评审角色请求素材生成。T:验证权限在服务器端生效。A:通过与真实模型相同的分发入口发送越权请求。R:应出现权限拒绝,且素材任务表没有新增记录;若仅 prompt 写了禁止而任务仍创建,实验失败。
第二层追问:工具参数符合 Schema,为什么还可能不允许执行?
**直接答案:**类型正确不代表业务合法或有权限。version=1 是合法整数,但教材可能已更新到第 2 版;文件路径是字符串,也可能越出允许目录。还要校验对象归属、审核状态、版本、配额、允许值和请求时效。
**STAR|假设方案:**S:延迟到达的图片请求携带旧内容版本。T:防止为过期内容交付素材。A:在提交任务和接收结果时都核对版本,旧结果保留审计但不挂到新版本。R:当前版本资源清单不会被旧请求改变。
分支追问:要不要用 MCP 实现这些工具?
**直接答案:**不必。MCP 解决工具、资源等能力的标准化接入与通信;模型何时请求哪个工具仍属于工具调用与应用编排。单一应用内部直接注册函数足够;多个客户端需要共享能力时再评估 MCP。接入 MCP 不自动提供业务授权、幂等或正确性。
**STAR|假设方案:**S:多个应用计划复用同一素材服务。T:减少重复接入。A:评估在现有受控接口外增加 MCP 适配层,保留服务器授权和任务机制。R:以客户端互通测试和审计一致性判断价值,不为简历增加不必要组件。
**优秀回答:**能描述请求、校验、调度、执行、回传五步,并定位费用发生在哪里。**常见误区:**模型会直接执行 Python;工具描述就是权限控制;MCP 等于 Agent。
实际源码:system/app/tools.py 的 ToolSession.specifications()、ToolSession.execute();system/app/providers.py::run_model()。
验证与实验:system/tests/test_system.py::test_context_and_tool_permissions;system/tests/test_adapters.py::test_real_model_tool_roundtrip_and_usage(HTTP MockTransport 契约,非在线调用);L07。
Q03 JSON 合法,就能直接入库吗?
**考察目的:**区分语法、结构和业务正确性。**难度:**核心。
**主问题:**模型返回了一个合法 JSON,你怎样确认它是一份可用教材?
直接答案与 STAR
至少分三层:第一层解析 JSON,确认语法;第二层按 Schema 校验字段、类型、枚举、长度和嵌套结构;第三层检查业务语义,例如答案是否对应题目、引用是否存在、人物是否一致、目标语言是否满足要求、地区规则是否被违反。还要把拒绝、截断、空响应和网络错误与“输出内容错误”分开处理。
服务商支持的结构化输出可以减少不合规形状,但不会证明教材知识正确。应用仍需本地校验,因为能力子集、模型版本和适配器可能不同。校验失败应保留可诊断信息并有限重试或转人工,不能静默填充默认答案冒充成功。
**STAR|学习复现:**S:练习必须有稳定 ID、题干和参考答案。T:避免错误数据进入审校和素材环节。A:准备缺字段样本和“字段齐全但答案错误”样本,分别经过结构校验和内容评审。R:前者应在解析/Schema 阶段失败,后者应形成业务问题报告;两类错误不能共用一个“重试成功率”掩盖差异。
第一层追问:Schema 已经很严格,为什么还做本地校验?
**直接答案:**应用边界不能把外部输出当成可信对象。本地校验还保证自定义模型适配器、人工编辑和历史版本迁移遵守同一个数据契约。严格模式支持范围可能随服务不同,代码需要以实际锁定版本为准。
**STAR|假设方案:**S:从一个供应商切换到兼容接口。T:保持业务数据契约稳定。A:在适配器后统一运行 Pydantic 校验,并对不支持的结构化参数明确报错。R:兼容接口不能绕过验证,切换前能发现契约差异。
第二层追问:模型一直产生不合法字段,你会无限要求它修复吗?
**直接答案:**不会。先判断输入截断、Schema 冲突或服务能力不支持等确定性原因,再给有限次数修复机会。只返回必要的错误位置和约束,避免泄露无关信息。耗尽预算后保存错误并转人工;拒绝与鉴权失败通常不能靠重复提示修好。
**STAR|假设方案:**S:输出长度不足导致 JSON 多次截断。T:避免费用不断增加。A:定位结束原因与 token 预算,缩小生成粒度或调整限额,而不是重复同样请求。R:以合法版本是否产生、调用次数是否受限作为验收,未解决则清晰失败。
分支追问:一边流式输出一边给教研看,什么时候可点击“通过”?
**直接答案:**可以展示临时文本,但不能把未完成对象当成已校验版本。完成接收、解析、结构校验并保存不可变版本后,才能进行针对该版本的审核。界面应区分预览与正式候选;中途断流不得保留“通过”状态。
**STAR|假设方案:**S:长教材流式输出中途断线。T:避免审核半份教材。A:将预览状态与已持久化候选版本分开,审核接口校验完整版本和期望版本号。R:断流后只保留可诊断记录,不出现可交付版本。
**优秀回答:**会举“JSON 正确但答案错误”的反例,能说明拒绝、截断与业务错误分别如何处理。**常见误区:**正则截取 {} 就足够;校验失败自动补空字符串;结构化输出消除了幻觉。
实际源码:system/app/schemas.py 的 Lesson、Review;system/app/providers.py::run_model();system/app/content.py::business_review()。
验证与实验:system/tests/test_system.py::test_schema_error_separate_from_business_error;system/tests/test_adapters.py::test_bad_structured_output_budget;L02 格式与业务错误。
Q04 为什么选 LangGraph?LangChain 必须一起用吗?
**考察目的:**抽象选择、复杂度和可替代性。**难度:**中等。
**主问题:**直接写几个 Python 函数能实现流程,为什么还引入 LangGraph?
直接答案与 STAR
简单的一次调用可以直接写函数。教材流程包含状态更新、条件分支、修订循环、人工暂停与持久化恢复,显式图有助于观察和管理这些关系。选 LangGraph 的价值是这些编排能力,而不是让生成质量自动变高。
LangChain 更侧重模型、工具、消息、检索等应用抽象与集成,LangGraph 更侧重有状态执行。可以组合,也可以在 LangGraph 节点中直接调用模型 SDK 或 HTTP 适配器。本项目不要求引入完整 LangChain 包;依赖中出现 langchain-core 也不等于应用使用了所有 LangChain 功能。选择要基于锁文件和实际调用链。
**STAR|学习复现:**S:内容评审可能通过、修订或进入人工处理。T:让每条路径都可测试且可恢复。A:将检索、生成、评审、修订和人工处理划为节点,把业务数据保持为明确结构。R:验收看分支是否可观察、进程重启后能否继续,而不是节点数量多少。
第一层追问:LangGraph 会自动帮你保存所有业务数据吗?
**直接答案:**不会。Checkpointer 保存图运行所需的状态与执行进度;教材版本、审核记录、素材文件和任务租约仍有各自的数据模型。某些数据可以放进图状态,但不能因此省略业务查询、版本控制和副作用去重。
**STAR|学习复现:**S:图已保存到“等待人工”,教研需要查询历史教材。T:同时满足恢复与业务管理。A:将正式教材版本和审校记录入业务表,图状态保留关联 ID。R:界面查询不依赖反序列化整个 checkpoint,恢复也能定位相同版本。
第二层追问:什么时候会放弃 LangGraph,改用普通状态机或 Temporal?
**直接答案:**简单稳定的短流程可用普通状态机;大量跨服务、长时间业务活动、严格运维要求时可以评估持久工作流引擎。LangGraph 与这些工具不是能力完全重叠的替代品。要比较恢复语义、任务调度、人员经验和运维成本,不按流行度选型。
**STAR|假设方案:**S:未来流程变成数天的人工审批并跨多个业务系统。T:判断当前编排是否够用。A:列出崩溃窗口、补偿、队列公平性和可观察性要求,做小范围验证。R:用缺口决定是否迁移,不因规模想象提前堆叠引擎。
分支追问:如果禁用框架,你还能解释系统吗?
**直接答案:**能。把图还原成状态结构、节点函数、转移条件、持久化和调度五部分即可。先讲业务不变量,再讲框架如何承载它。无法离开框架名解释设计,通常意味着只掌握了 API。
**STAR|学习复现:**S:面试官要求在白板上描述一次修订。T:证明理解而非背接口。A:写出输入版本、评审问题、允许修改路径、新版本和循环终止条件。R:即使不写 LangGraph API,也能定位失败后的恢复点。
**优秀回答:**能指出引入框架后仍由自己负责的事情,并给出不使用它的合理场景。**常见误区:**LangGraph 必须安装完整 LangChain;框架自带一次且仅一次副作用;所有工作流都该 Agent 化。
关联学习:LangGraph、Agent 与 Workflow。
实际源码:system/app/graph.py 的 State、build_graph()、run_workflow();system/app/db.py::save_version()。
验证与实验:system/tests/test_system.py::test_new_process_resumes_checkpoint、test_complete_revision_approval_delivery;L01 与 L09。把图结束与媒体交付完成分别定位。
官方核对资料
核对日期:2026-11-03。概念适用于本包锁定版本;具体 API 以锁文件和对应版本文档为准。