Agent 面试三面全景:21 道题深度拆解
Agent 面试三面全景:21 道题深度拆解
面试官想听的,从来不是标准答案,而是你对 Agent 体系的理解深度。
这是一套真实企业 Agent 岗位的三轮面试题,从底层原理到顶层战略,层层递进。下面逐轮拆解——不只是给答案,更是给思路框架。
本文提纲
- 技术一面:全链路与核心机制
- 技术二面:架构设计与容错体系
- 总裁面:方向判断与战略思维
一、技术一面:全链路与核心机制
Q1:整个 IT 完整链路是怎么运转的?
用户输入到完成任务,一条典型的 Agent 调用链分 8 个阶段:
用户输入 → 路由层 → 意图识别 → 任务拆解 → 规划引擎 → 工具调用循环 → 结果聚合 → 返回用户路由层是第一道网关。不是所有请求都走 Agent——简单的信息查询直接 RAG 返回,只有需要多步推理的才进 Agent。
意图识别把自然语言映射为结构化意图。"帮我写个登录接口" → {intent: "code_generation", domain: "auth", language: "python", framework: "fastapi"}。这里的关键不是"理解意思",而是"理解隐含约束"——比如用不用 JWT、要不要数据库、是不是 RESTful。
任务拆解环节决定了一个 Agent 是"真 Agent"还是"套壳 Prompt"。复杂任务被拆成 DAG(有向无环图),而不是简单的线性序列。每个子任务有明确的输入输出 schema和前置依赖。
工具调用循环是 Agent 的核心差异点。标准模式是 ReAct(Reasoning + Acting):LLM 输出 thought + action + action_input,执行环境返回 observation,LLM 继续推理,直到输出 final_answer。这个循环的质量直接决定 Agent 能不能干活。
关键数据流转:
# 一次完整的 Agent 调用 = 多层上下文拼接
context = {
"system_prompt": "...", # 角色定义 + 约束规则
"tools_schema": [...], # 可用工具的函数签名
"memory_recent": [...], # 最近 N 轮对话
"memory_long_term": [...], # 检索到的长记忆片段
"current_task": "...", # 当前任务拆解结果
"intermediate_steps": [...] # tool call history
}每一步中间结果都会持久化,供后续调试和审计。这不是可选项,生产环境 Agent 如果不可观测,出了事都不知道谁调了哪个 API。
Q2:Agent 如何理解用户意图并进行任务拆解?
意图理解分两层:显性意图和隐性意图。
显性意图是用户说了什么。靠的是领域分类模型 + 实体识别 + 槽位填充。"帮我查一下昨天的 GPU 价格" → 实体:GPU,时间范围:yesterday,操作:query。
隐性意图是用户没说的。"你这个价格不对啊"——他说的是"价格",但他真正要的是"纠正数据 + 给准确结果 + 不要再犯"。Agent 能不能把隐性意图补全,是"聪明"和"蠢"的分界线。
任务拆解的核心难点不是拆,而是拆到什么粒度。太粗了 LLM 搞不定,太细了 token 浪费 + 延迟爆炸。
一个实用的拆解策略:
Rule 1: 每个子任务必须有单一明确的输出物
Rule 2: 子任务之间优先并行,并行不了的才串行
Rule 3: 单子任务的复杂度不超过 LLM 单次高质量输出的上限
Rule 4: 关键子任务(涉及数据库写入、外部 API 调用)前置人工确认举个例子。"分析过去一周的用户增长趋势,找出异常点,发邮件给产品经理":
graph TB
A[User Input] --> B[Fetch Metrics from DB]
A --> C[Fetch User Events]
B --> D[Trend Analysis]
C --> D
D --> E[Anomaly Detection]
E --> F[Generate Report]
F --> G{HITL: Confirm?}
G -->|Yes| H[Send Email]
G -->|No| I[Adjust & Regenerate]
style A fill:#FF6B6B,color:#000000
style D fill:#4ECDC4,color:#000000
style E fill:#45B7D1,color:#000000
style F fill:#96CEB4,color:#000000
style G fill:#FFEAA7,color:#000000
style H fill:#DDA0DD,color:#000000
style I fill:#98D8C8,color:#000000B 和 C 可以并行(都是读操作),D 依赖 B+C,E 依赖 D,F 依赖 E,G 是 HITL 确认点(发邮件前必须人工看过),H 和 I 是条件分支。
Q3:任务拆解后,Agent 如何决定执行顺序和工具/模型选择?
执行顺序本质是拓扑排序——有依赖的串行,无依赖的并行。
但现实中比拓扑排序复杂:有些依赖是"软依赖"而不是"硬依赖"。比如分析用户增长,"拿到数据库数据"和"拿到埋点数据"是两个独立任务,一个慢了不该阻塞另一个——最多是最终聚合时少一个数据源。
模型选型的核心原则:
| 场景 | 模型选择 | 理由 |
|---|---|---|
| 意图分类 | 小模型(DeepSeek Flash) | 延迟敏感,任务简单 |
| 代码生成 | 旗舰模型(GLM-5.2 / Claude) | 质量优先,可容忍 3-5 秒延迟 |
| 信息检索 RAG | 中模型 + embedding | embedding 做相似度,LLM 做整合 |
| 工具选择决策 | 中等模型 | 需要推理但不值旗舰成本 |
| 最终输出润色 | 旗舰模型 | 面向用户,质量不可妥协 |
工具调用时机由一个显式的路由函数决定:
def should_call_tool(llm_output: dict) -> bool:
"""LLM 输出的 action 字段决定是否调用工具"""
if llm_output.get("action") == "final_answer":
return False
# 连续 3 次同一工具调用失败 → 放弃工具,转 LLM 直接输出
if consecutive_same_tool_errors >= 3:
return False
return True这里的核心洞察是:不要过度依赖 LLM 自己做"要不要调工具"的判断。在关键路径上,用确定性的规则做路由决策,LLM 只负责"怎么用工具"。
Q4:Agent 长短期记忆的设计及存储膨胀问题
短期记忆就是对话窗口内的 messages[]。它的上限是模型的 context window(现在主流是 128K-1M token)。问题不是"能存多少",而是"该保留什么"——无脑堆对话历史会让 LLM 注意力分散,反而变笨。
好的短期记忆策略:
1. 保留最近 N 轮完整对话(N=5-10,视业务而定)
2. 对于超出 N 轮的内容,保留"摘要"而非原文
3. 关键决策节点(任务拆解、工具调用结果、最终输出)永远不删,其余按时间衰减权重
4. 用户明确标记为"重要"的内容,提升保留优先级长期记忆是三件套:向量库(语义检索)+ 关系型库(结构化存储)+ 全文索引(关键词搜索)。
对应的存储膨胀来自三个方向:
| 膨胀来源 | 根因 | 解决方案 |
|---|---|---|
| 重复存储 | 相似的对话被多次写入 | 写入前去重(语义相似度 > 0.85 跳过) |
| 过期数据 | 时间相关的信息失效 | TTL 自动清理 + 时效性打分降权 |
| 无效摘要 | 多次摘要后内容稀释 | 3 次摘要后就标记为"超期",直接沉睡 |
| 检索精度下降 | 向量越来越多,召回质量下降 | 分层索引:热数据(7天)/ 温数据(30天)/ 冷数据(归档) |
分层索引是最有效的防膨胀策略。不是所有记忆都平等,80% 的检索命中在最近的 20% 数据上。热数据在内存,温数据在 SSD,冷数据离线归档——每次检索先查热的,命中率高就直接返回,不碰冷库。
Q5:上下文窗口总 token 是多少,触发压缩的上限阈值如何规定?
以 128K 窗口为例,一条实用的预算分配:
总预算: 128,000 tokens
├── System Prompt: 2,000 - 4,000 tokens (固定,包含角色+工具定义+约束)
├── RAG 注入 + Memory: 10,000 - 20,000 tokens (动态,按任务需求分配)
├── 对话历史: 60,000 - 80,000 tokens (动态,滑动窗口)
├── 当前任务拆解: 2,000 - 5,000 tokens (动态)
└── LLM 输出预留: 16,000 - 32,000 tokens (不可压缩)压缩触发阈值不能拍脑袋定一个"80% 就开始压缩"。实际需要三层阈值:
第一层: 预警阈值 (75%) — 启动对话摘要压缩,把旧消息换成摘要
第二层: 强制压缩 (85%) — 裁剪 RAG 注入内容,只保留 top-K 结果
第三层: 硬保护 (92%) — 拒绝新内容注入,提示"对话过长,请开启新会话"压缩策略不是一刀切砍掉旧消息。优先级:删除冗余重复信息 > 摘要旧消息 > 裁剪 RAG 注入 > 缩短 system prompt > 拒绝新输入。
为什么 system prompt 放在倒数第二?因为 system prompt 是 Agent 的"宪法",砍 system prompt 等于砍 Agent 的根本约束——这也解释了为什么 system prompt 长度必须严格控制,一开始就不能膨胀。
Q6:不同业务场景下,模型应该如何选型?
选型的三个维度:质量 × 延迟 × 成本,每个场景的权重不同。
质量优先 ←→ 成本优先
在线客服 ─────────────────→ 批量数据清洗
(需优质输出) (量大, 可粗)
代码生成 ─────────→ 简单问答
(一步错全错) (错了也没事)
实时对话 ─────────────────→ 离线分析
(延迟 < 1s) (延迟无感)实际选型决策树:
- 任务是否面向最终用户?→ 是:用旗舰模型,不可省
- 任务是否需要多步推理(>3 步)?→ 是:用强推理模型
- 任务是否可以接受 30% 的错误率?→ 是:用便宜模型批量跑,跑 3 次投票
- 任务延迟预算是多少?→ < 500ms:必须用小模型或本地推理
- 任务是否敏感数据?→ 是:本地部署模型,不上云 API
一个典型案例:做代码审查助手。代码理解用 DeepSeek-V4-Pro(够强且便宜),关键安全漏洞检测用 GLM-5.2(最准确),最终报告生成用 Kimi K2.7-Code(代码理解 + 报告生成一体)。三类模型协同,总成本比全用旗舰低 60%,准确率不降。
Q7:Agent 写一千行代码大概消耗多少 token,成本是多少?
以一次标准的代码生成为例,拆解 token 消耗:
输入侧(Input Tokens):
├── System Prompt: ~2,000 tokens
├── 项目上下文(相关代码文件): ~10,000 tokens
├── 任务描述 + 约束: ~500 tokens
├── 已有代码(迭代修改): ~5,000 tokens
├── 对话历史: ~3,000 tokens
└── 小计: ~20,500 input tokens
输出侧(Output Tokens):
├── 代码生成: ~3,000 tokens(1000 行,平均 3 token/行)
├── 代码解释/注释: ~1,000 tokens
├── 工具调用请求: ~500 tokens
└── 小计: ~4,500 output tokens但 1000 行代码实际很少一次生成完。一次真实的 Agent 任务通常需要 3-5 轮迭代:
总消耗 = 1 轮初始生成 + 3 轮修改迭代
= (20.5K in + 4.5K out) × 4
≈ 82K input + 18K output
= ~100K tokens成本计算(以国内主流 API 价格为基准):
| 模型 | 输入 ¥/1M tokens | 输出 ¥/1M tokens | 1000 行代码成本 |
|---|---|---|---|
| DeepSeek-V4-Flash | ¥0.84 | ¥3.36 | ~¥0.13 |
| DeepSeek-V4-Pro | ¥3.00 | ¥12.00 | ~¥0.61 |
| GLM-5.2 | ¥8.00 | ¥32.00 | ~¥1.24 |
| Kimi K2.7-Code | ¥6.00 | ¥24.00 | ~¥0.92 |
换句话说,用 DeepSeek Pro 写 1000 行代码的 token 成本不到 7 毛钱。但这是"理想情况"——如果 Agent 陷入无效重试循环(连续 5 次修同一个 bug),成本轻松翻 5-10 倍。这也就是为什么 Agent 的成本控制核心不是选便宜模型,而是避免无效迭代。
Q8:海外 token 计费规则是什么?
海外主流模型按 input/output tokens 分开计费,核心定价和特点:
| 模型 | Input ¥/1M | Output ¥/1M | 特点 |
|---|---|---|---|
| GPT-5.0-nano | ~¥3.50 | ~¥17.50 | 轻量级,适合简单任务 |
| GPT-5.0 | ~¥17.50 | ~¥87.50 | 旗舰,复杂推理 |
| GPT-5.0-mini | ~¥4.20 | ~¥28.00 | 性价比日常 |
| Claude Opus 4.5 | ~¥105.00 | ~¥525.00 | 最高质量,最高价格 |
| Claude Sonnet 4.5 | ~¥21.00 | ~¥105.00 | 性价比之选 |
| Gemini 3.0 Pro | ~¥10.50 | ~¥42.00 | 原生多模态 |
| LLaMA-4 (self-hosted) | 0 | 算力成本 | 数据安全优先场景 |
海外模型有个和国内最大的不同:Prompt Caching(提示词缓存)。
OpenAI 和 Anthropic 都支持长上下文的自动缓存。以 Claude 为例:如果你连续调用同一个 system prompt 或前缀相同的上下文,第二次开始 input 价格降 90%。这意味着构建一个"热 Agent"的成本远低于"冷启动"——一个反复使用的 Agent 系统,平均每次调用的缓存命中率能做到 60-80%,input 成本降到白菜价。
计费注意事项:
- Token 计数以模型 tokenizer 为准,不是字符数。同一个中文句子,token 数比英文字数多 1.5-3 倍
- 工具调用(tool calls)的输出 token 也计费——Agent 场景下工具交互可占总 token 消耗的 30-50%
- 图片输入按分辨率折算 token:一张 1024×1024 图片约 765-1105 tokens(因模型而异)
- 费率使用 $ 计价,实时汇率换算,批量 API 通常有 50% 折扣(延迟优先级的代价)
二、技术二面:架构设计与容错体系
Q1:如果从零到一设计一个企业级 Agent,怎么设计整体架构?
设计的起点不是画架构图,是想清楚三个问题:这个系统跑在哪?谁在用它?出了事谁负责?
基于这三个问题,企业级 Agent 的架构需要五个核心特征:可观测、可回滚、可审批、可降级、可审计。
graph TB
subgraph "Gateway Layer"
A[API Gateway] --> B[Auth & Rate Limit]
end
subgraph Orchestration
C[Intent Router]
D[Task Planner]
E[Execution Engine]
end
subgraph "Core Services"
F[Memory Manager]
G[Tool Registry]
H[Model Router]
I[HITL Middleware]
end
subgraph "Infrastructure"
J[Vector DB]
K[Relational DB]
L[Message Queue]
M[Observability]
end
B --> C
C --> D
D --> E
E --> F
E --> G
E --> H
E --> I
F --> J
F --> K
E --> L
E --> M
style A fill:#FF6B6B,color:#000000
style C fill:#4ECDC4,color:#000000
style D fill:#45B7D1,color:#000000
style E fill:#96CEB4,color:#000000
style I fill:#FFEAA7,color:#000000
style M fill:#DDA0DD,color:#000000各层职责:
- 网关层:限流、鉴权、请求来源标记。企业环境下的 Agent 权限不是统一的——运维 Agent 能重启服务器,客服 Agent 只能查知识库
- 编排层:意图路由(简单/复杂分流)、任务规划(DAG 生成)、执行引擎(ReAct 循环 + 超时控制)
- 核心服务层:记忆管理(分层存储 + TTL)、工具注册(函数签名 + 权限标签 + 版本号)、模型路由(按场景 + 成本 + 延迟分配)、HITL 中间件(敏感操作拦截)
- 基础设施层:向量库(语义检索)、关系型库(审计日志/状态快照)、消息队列(异步任务解耦)、可观测性(trace + metric + log 三件套)
为什么企业级必须三层分离? 因为和 ToC 场景不同,企业的 Agent 每条决策都可能涉及钱、权限、合规。编排层挂了不影响工具注册,HITL 中间件独立可插拔,观测系统与业务链路解耦——每个模块的故障半径是可控的。
Q2:Agent 系统的核心模块拆分
| 模块 | 职责 | 关键设计 |
|---|---|---|
| Intent Router | 意图分类 + 路由分发 | 快速通道(简单查询直达 RAG)vs 慢速通道(复杂任务进 Agent) |
| Task Planner | 拆解任务为 DAG | 输出确定性执行图,不是自然语言描述 |
| Execution Engine | ReAct 循环 + 工具编排 | 循环上限 + 单步超时 + tool call 重试策略 |
| Memory Manager | 短期/长期/工作记忆 | 三套存储 + 分层索引 + TTL 清理 |
| Tool Registry | 工具注册+发现+权限 | 函数签名 schema + 权限标签 + 版本管理 |
| Model Router | 模型选择 + 降级 | 场景→模型映射表 + 主模型故障时自动切备选 |
| HITL Middleware | 人工审批拦截 | 配置驱动:哪些操作必须审批、审批超时策略 |
| Observability Stack | 全链路追踪 | OpenTelemetry + 自定义 span(task/step/tool 三级) |
| Safety Guard | 内容安全 + 操作边界 | 输入输出过滤 + 敏感 API 调用频率限制 + 熔断 |
| State Manager | Agent 运行态快照 | 支持暂停/恢复/回滚到任意中间状态 |
Q3:Agent 如何做任务识别,怎么判断简单还是复杂?
判断一个任务简单还是复杂,不是 LLM 一句话的事,而是规则为主、模型为辅:
规则层(快速判定):
# 简单任务硬编码判定
SIMPLE_PATTERNS = {
"translation": "翻译", # 单步 LLM 直接输出
"summary": "总结", # 单步 RAG + LLM
"factual_qa": "什么是", # 单步检索
"greeting": "你好", # 不需要调用工具
}
# 复杂任务硬编码判定
COMPLEX_TRIGGERS = [
"帮我部署", # 多步骤、含外部 API
"分析并生成报告", # 多数据源 + 输出物
"对比并推荐", # 多源信息综合
"根据XX自动创建YY", # 创建操作,需要 HITL
]模型层(模糊判定):如果规则层没有命中,交给 LLM 做二分类。不是问它"是不是复杂",而是问结构化的三个判断维度:
1. 是否需要 2 个以上外部系统(数据库、API、文件)的交互?
2. 是否涉及"创建/修改/删除"操作(而非"读取/查询")?
3. 任务拆解后是否有条件分支或循环逻辑?
任一答案为是 → 复杂任务为什么规则为主? 因为判断简单/复杂是 Agent 路由的第一步,这一步不能犯错——把一个"重启服务器"的操作误判为简单任务,直接跳过了 HITL,后果不堪设想。规则层的召回率可以低一点,准确率必须 100%。
Q4:复杂任务如何进行任务拆解和执行计划生成?
拆解 = 把自然语言需求转为结构化 DAG。三种方法递进使用:
方法一:Few-shot 模板。 对于高频场景(代码生成、数据分析、文档处理),维护一套标准拆解模板。比如"数据分析"永远是"数据拉取 → 清洗 → 统计分析 → 可视化 → 解读报告"。
方法二:LLM 生成 + 验证。 对于模板不覆盖的新场景:
# 拆解 Prompt 的关键结构
system_prompt = """
将用户需求拆解为 JSON 格式的子任务列表。每个子任务必须包含:
- id: 唯一标识
- description: 一句话描述
- output_schema: 输出物的字段定义
- dependencies: 前置任务的 id 列表
- tool_hints: 可能需要调用的工具
- rollback_strategy: 回滚策略 (retry / skip / abort)
- max_retries: 最大重试次数 (默认 2)
"""输出的 JSON 需要经过验证器检查:有无循环依赖、有无缺失依赖、每个子任务是否都有明确输出物。
方法三:代码级规划(关键路径)。 对于复杂度极高的任务,用 Python 而不是 LLM 做规划。比如数据迁移 Agent——"从 MySQL 迁移 5000 万行到 PostgreSQL"——拆解逻辑是确定性的:分批读取 → 类型映射 → 批量写入 → 校验。这段规划代码本身就是 Agent 的执行逻辑。
执行计划的三个关键约束:
- 每个子任务必须有 timeout(防止 LLM 卡死或工具调用挂起)
- 敏感操作子任务前必须有 approval_checkpoint(HITL 确认点)
- 每 3 个子任务完成后必须写一次 状态快照(供恢复使用)
Q5:Agent 如何判断当前步骤成功或失败?
成功/失败不只有一个维度,需要多维度打分:
class StepResult:
status: Literal["success", "partial_success", "failed", "timeout", "rejected"]
# 三维度评分
output_valid: bool # 输出物 schema 校验是否通过
confidence: float # LLM 自评置信度 (0-1)
side_effect_check: bool # 副作用检查(数据库/API 调用是否成功)
# 失败元信息
error_type: Optional[str] # schema_error / timeout / tool_error / llm_hallucination
retry_hint: Optional[str] # 重试建议(换工具 / 换模型 / 补充上下文 / 放弃此步骤)判断逻辑:
- 首先检查
output_valid——输出物的 schema 校验是确定的,JSON 格式不对、必填字段缺失,直接标记失败 - 如果 schema 通过,检查
confidence。LLM 自评置信度低于 0.6 的步骤,需要额外验证(用另一个模型跑一遍交叉检验,或触发 HITL) - 如果工具调用(数据库写入、API 调用),检查返回状态码。4xx 是工具参数问题→修正参数重试;5xx 是目标系统问题→等 5 秒重试 1 次
- 即使以上全过,还要检查语义一致性:生成的内容是否与前置步骤的输出矛盾?用一个小模型做 cross-check
关键设计:不要问 LLM 自己判断自己。"你觉得你这一步做对了吗?"这个 prompt 得到的永远是"是的,我做对了"——LLM 没有自我纠错能力。判断必须基于确定的规则(schema 校验)和交叉验证(另一个模型审查)。
Q6:任务失败后如何重试、回滚或重新规划?
三阶段递进:
graph TB
F[Task Failed] --> A{Error Type?}
A -->|tool_error| B[Retry: Fix Params]
A -->|schema_error| C[Retry: LLM Reprompt]
A -->|timeout| D[Retry: Extend Timeout]
A -->|llm_hallucination| E[Retry: Switch Model]
B --> G{Retry OK?}
C --> G
D --> G
E --> G
G -->|No, after 3x| H[Rollback to Checkpoint]
H --> I[Replan from Snapshot]
G -->|Yes| J[Continue]
style F fill:#FF6B6B,color:#000000
style A fill:#FFEAA7,color:#000000
style B fill:#4ECDC4,color:#000000
style C fill:#4ECDC4,color:#000000
style D fill:#4ECDC4,color:#000000
style E fill:#4ECDC4,color:#000000
style H fill:#45B7D1,color:#000000
style I fill:#96CEB4,color:#000000
style J fill:#98D8C8,color:#000000第一阶段:局部重试(retry)
- tool_error → 修正参数重试(3 次上限,指数退避:1s → 3s → 9s)
- schema_error → 给 LLM 明确错误信息,让它修正输出
- timeout → 延长时间 + 减小任务粒度
- hallucination → 切模型,或增加 RAG 注入纠正上下文
第二阶段:回滚到检查点(rollback)
3 次重试都失败,不回退到任务开始——只回退到最近一个成功的检查点。检查点是计划执行中的快照,包含完整的状态上下文。从这个点重新规划后续步骤。
第三阶段:全量重规划(replan)
如果回滚后还是失败,说明原始任务拆解就有问题。此时抛弃原计划,用"上一个成功的检查点 + 失败日志"作为输入,让 LLM 重新拆解剩余任务。关键是要把失败日志作为负反馈注入——"之前的方案在 XX 步骤失败了,因为 YY 原因,请避免"。
一个重要的工程约束:所有"外部写操作"必须在第一版计划中隔离为独立子任务。因为读操作可以无限重试,写操作重试的代价巨大。所以写操作子任务要等到所有依赖的读操作全部完成且验证通过后再执行。
Q7:如何设计完整的代码上下文理解系统?
代码上下文理解不是简单的"把代码扔进 RAG 向量库"。代码有结构(AST)、有逻辑(调用链)、有运行时(堆栈)、有历史(Git)。单靠向量检索只能做"这段代码和那段像不像",无法回答"这个改动了会影响哪些下游"。
四维一体的代码上下文理解系统:
Layer 1: 向量检索(语义层) → "这段代码做了什么事?"
Layer 2: 关键词搜索(符号层) → "哪些文件引用了 getUserById?"
Layer 3: AST 分析(结构层) → "这个类的继承链是什么?"
Layer 4: 调用链分析(运行时层) → "这个函数的下游依赖有哪些?"具体实现:
# 代码上下文的四层融合
class CodeContextEngine:
def build_context(self, query: str, repo_path: str):
# Layer 1: 向量检索 — 语义相似代码块
vector_results = self.vector_db.search(query, top_k=20)
# Layer 2: 关键词搜索 — grep + ripgrep 符号级定位
symbols = extract_symbols(query) # 从 query 中提取函数名、类名
grep_results = self.grep_client.search(symbols, repo_path)
# Layer 3: AST 分析 — 结构关系
ast_relations = self.ast_parser.parse(grep_results)
# → {callers: [...], callees: [...], imports: [...], class_hierarchy: [...]}
# Layer 4: 调用链分析 — 运行时依赖
call_chain = self.static_analyzer.trace(grep_results[0])
# → 下游依赖 + 上游调用者 + 相关联的 interface/type 定义
return merge_and_rank(
vector_results, grep_results, ast_relations, call_chain
)四层融合的权重策略:
- 如果 query 是"这个 bug 怎么修"→ AST + 调用链权重最高(需要理解影响面)
- 如果 query 是"怎么用这个库"→ 向量检索 + 关键词权重最高(需要找文档和示例)
- 如果 query 是"这个模块的整体设计"→ AST 结构层权重最高(需要看到整体架构)
关键性能优化:AST 和调用链不需要实时计算——在 CI/CD 中预计算,存入图数据库。Agent 查询时直接查图,而不是现场解析代码。把"冷启动"变成"热查询"。
Q8:Agent 工具调用系统应该怎么设计?
工具调用系统有三个层次,每个层次解决不同问题:
第一层:Tool Definition(工具定义)
# 工具注册的标准 schema
@tool_registry.register(
name="database_query",
description="Execute a read-only SQL query against the analytics database",
category="data_access",
permissions=["read_db_analytics"], # 权限标签
timeout=30, # 超时 30 秒
max_size_mb=10, # 单次返回上限 10MB
cost_estimate={"tokens": 500}, # 成本估算
version="2.1.0" # 版本号
)
def database_query(sql: str, params: dict = None) -> QueryResult:
pass第二层:Tool Discovery & Routing(工具发现与路由)
不把所有工具描述一次性塞进 prompt——工具多了 LLM 会选错。用两阶段检索:
- 粗筛选:基于任务意图的语义匹配,从工具池中召回 top-5 候选
- 精选择:把这 5 个工具的 schema 放入 prompt,LLM 精准选择
第三层:Tool Execution & Recovery(工具执行与恢复)
def execute_tool(tool_call: ToolCall) -> ToolResult:
result = None
for attempt in range(3):
try:
result = tool_registry.execute(
tool_call.name,
tool_call.arguments,
timeout=tool_call.timeout
)
break
except ToolError as e:
if attempt == 2:
result = ToolResult(
status="failed",
error=str(e),
suggestion="放弃此工具,切换到备选工具或人工介入"
)
else:
# 指数退避重试
time.sleep(2 ** attempt)
return result工具系统的三个关键约束:
- 权限隔离:数据库工具分"只读"和"读写",前者 Agent 可以自动调,后者必须经过 HITL 确认
- 频率限制:每个工具独立限流——防止 Agent 无限循环调用同一个 API,把下游打爆
- 版本管理:工具接口变更时,旧版本标记 deprecated 但不立即下线,给 Agent 一个迁移窗口
三、总裁面:方向判断与战略思维
Q1:为什么选择 Agent 方向,对 Agent 未来的判断是什么?
Agent 不是一个新的产品品类,它是一个新的交互范式。
过去二十年,人机交互经历了三次范式转移:CLI(命令行)→ GUI(图形界面)→ CUI(对话界面)。Agent 是 CUI 的下一阶段——从"人告诉机器每一步做什么"到"人告诉机器目标是什么,机器自己想办法"。
选择 Agent 方向不是因为它是热点,是因为它正在吃掉软件本身。传统的 SaaS 是"给你一把刀,教你怎么切菜"。Agent 是"告诉你做什么菜,连买菜带切菜带炒菜全干了"。这意味着整个软件的交付形式、计费模式、用户体验都在发生根本性的变化。
对未来的判断:三年内,企业内部 30% 以上的重复性工作流将由 Agent 替代。不是 ChatBot 换个皮,而是真正能自主完成端到端任务的 Agent 系统。五年内,"低代码平台"这个词会消失,被"Agent 平台"取代——因为"拖拽搭建表单"和"告诉 Agent 你需要一个审批系统"之间的用户体验差距,大到不可逆转。
Q2:追求短期热点还是长期看好?
长期看好。但"长期看好"不意味着"不关注短期"。
真正有价值的长期方向,往往在短期也有一波接一波的信号验证。2024 年的 Function Calling、2025 年的 MCP 协议标准化、2026 年的 Agent Infra 爆发——每一波都在证明一件事:Agent 从 Demo 走向生产是不可逆的趋势。
短期热点我会关注,比如某个框架突然火了、某个新范式被炒作。但我的判断框架是:
- 这个热点解决了 Agent 体系中的哪个关键问题?(记忆?工具?安全?可观测?)
- 解决的方式是"补丁"还是"范式升级"?
- 三年后回头看,这个方向还存在吗?
如果只满足第三条,我就投入。如果只满足前两条,我关注但不跟风。
Q3:你和其他候选人的差异是什么?
我不只是"会调 API 的 AI 工程师",我理解 Agent 系统从底层原理到生产落地的全链路。
具体来说三个差异:
第一,我拆过真实的生产环境问题。 不是跑 Demo,是真的踩过"Agent 无限循环调用 API 打爆下游服务""上下文窗口爆炸导致 LLM 输出质量断崖式下降""工具调用 3 次失败后没有合理的降级策略导致整个任务挂掉"这些坑。这些经验不是在 Demo 里能学到的。
第二,我关注"不可见"的工程问题。 大多数人讲 Agent 在讲"怎么让 LLM 更聪明",我在讲"怎么让 Agent 的故障半径可控""怎么把 HITL 做成可插拔中间件而不是硬编码""怎么设计观察系统让 Agent 的行为不被黑盒化"。这些问题是 Agent 从 80 分到 95 分的差距。
第三,我跨过技术到业务的鸿沟。 我能从"这个 API 应该怎么设计"一路讲到"这个方案能帮业务省多少钱"。技术和业务之间的翻译能力,在 Agent 这种"技术复杂度 × 业务复杂度"双高的领域,是稀缺的。
Q4:你能给公司带来什么价值?
三个层面的价值:
短期:把 Agent 系统从"能用"做到"好用"。 包括建立标准化的 Agent 架构、工具调用体系、上下文管理策略和可观测性。让团队不用每个人从零造轮子。
中期:降低 Agent 系统的运维成本。 Agent 系统最大的隐性成本不是 API 调用费,而是排障成本——Agent 做错了你不知道、知道了你找不到原因、找到原因了你修不好。一套好的可观测体系和容错设计,能让排障时间从"半天"降到"15 分钟"。
长期:建立公司在 Agent 方向的技术壁垒。 不是靠"比别人多知道一个 Prompt 技巧",而是靠"把 Agent 的可靠性/安全性/可观测性做成工程护城河"。让公司的 Agent 产品不只是"又一个套壳 GPT",而是真正能进企业生产环境的基础设施级产品。
Q5:愿不愿意带团队,能不能把业务带到行业头部?
愿意。带团队不是一个"升职加薪"的台阶,而是把一个方向从 0 做到 1 甚至从 1 到 10 的唯一方式。
关于带到行业头部,我有个清晰的判断:Agent 这个赛道的头部,不是靠"做得更多"赢的,是靠"做得更可靠"赢的。
现在市场上所有 Agent 产品都有一个共同的问题——可靠性不够。用户第一次用很惊艳,用了一周就放弃了,因为"它经常犯错而且你不会知道"。谁先解决"Agent 行为可预测、结果可验证、错误可追溯"这三个问题,谁就能从"好玩"跨越到"好用",谁就能定义这个品类的标准。
我的策略是:第一阶段聚焦在 2-3 个高频场景上,把可靠性做到 99% 以上(不是 Demo 成功率,是生产环境日活用户的真成功率)。第二阶段用这 2-3 个场景建立的口碑,把方法论横向复制到相邻场景。第三阶段把"可靠性保障"抽象为平台能力,让任何场景上的 Agent 都能继承这套体系。
我判断这条路能走到头部,不是因为"比别人聪明",而是因为"做了一个更难也更正确的事"。
参考文档与链接
- Google ADK Python — Workflow graph engine, Task API, ManagedAgent 架构参考
- Anthropic: Building Effective Agents — Agent 设计原则与 workflow 模式
- OpenAI: Structured Outputs — JSON schema 输出格式约束
- OpenAI: Prompt Caching — 提示词缓存降低 90% input 成本
- DeepSeek API Pricing — 国内模型定价基准
- 智谱开放平台定价 — GLM 系列模型定价
- 月之暗面 Kimi API 定价 — Kimi 系列定价
- OpenTelemetry — Agent 系统可观测性标准
- Ripgrep — 代码关键词搜索引擎
- AST Parser (tree-sitter) — 代码结构分析引擎
- ReAct Paper — Reasoning + Acting 范式
面试过 Agent 岗位吗?评论区聊聊你被问过的最难的问题是什么。觉得有用就点个在看,让更多准备面试的人看到。
作者: itech001 来源: 公众号:AI人工智能时代 网站: https://www.theaiera.cn/ 每日分享最前沿的AI新闻资讯和技术研究。
本文首发于 AI人工智能时代,转载请注明出处。