快手 AI应用开发 二面
这个是5.11发的offer了,HR面和二面隔了10多天
1. 自我介绍
2. RAG 有没有解决大模型胡说八道的问题
答案:
RAG 只能缓解幻觉,不能彻底解决幻觉。RAG 的作用是把外部知识、业务文档、历史记录和实时数据作为上下文提供给模型,让模型减少依赖参数记忆。但如果召回错了、召回不全、chunk 切分不合理、rerank 排错、prompt 没约束好,模型仍然会基于错误证据生成错误答案。
所以线上 RAG 不能只做“检索 + 拼 prompt + 生成”。必须做证据约束。比如在园区运维场景里,模型说“冷却塔水泵异常导致能耗升高”,就必须引用对应的告警记录、传感器曲线或历史工单。如果没有证据,只能输出“证据不足,建议补充某项数据”,不能编一个看起来合理的原因。
{
"answer": "3 号楼能耗升高主要和夜间空调未按策略关闭有关",
"citations": [
{
"evidenceId": "ev_meter_1024",
"source": "energy_meter_hourly",
"content": "3 号楼 00:00-06:00 用电量较上周同期上涨 38%"
},
{
"evidenceId": "ev_bms_2091",
"source": "bms_control_log",
"content": "空调策略在 23:00 后仍保持运行"
}
]
}
后端还要校验引用是否真实存在:
public void verifyAnswer(Answer answer, Map<String, Evidence> evidenceMap) {
if (answer.getCitations() == null || answer.getCitations().isEmpty()) {
throw new BizException("ANSWER_WITHOUT_EVIDENCE");
}
for (Citation citation : answer.getCitations()) {
if (!evidenceMap.containsKey(citation.getEvidenceId())) {
throw new BizException("INVALID_EVIDENCE_CITATION");
}
}
}
3. 怎么评估 RAG 的效果,准确性用什么来对比
答案:
RAG 评估要分两层:检索评估和生成评估。检索评估看系统有没有把正确证据召回来,常用指标是 Recall@K、Precision@K、MRR、NDCG、HitRate。生成评估看最终答案是否正确、是否忠于证据、有没有幻觉、引用是否准确、用户是否采纳。
准确性不能只靠人工感觉,最好构建 golden set。比如拿历史能耗异常案例和已确认的运维结论作为标准集,每个问题标注标准答案、关键证据、可接受表达和不可接受结论。评估时先看正确证据是否进入 topK,再看模型答案是否覆盖标准结论。
CREATE TABLE rag_eval_case (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
question TEXT NOT NULL,
expected_answer TEXT NOT NULL,
expected_evidence_ids JSON NOT NULL,
category VARCHAR(64),
difficulty VARCHAR(32),
created_at DATETIME NOT NULL
);
检索评估可以这样算:
public double recallAtK(List<String> expected, List<String> retrieved, int k) {
Set<String> topK = new HashSet<>(retrieved.subList(0, Math.min(k, retrieved.size())));
long hit = expected.stream().filter(topK::contains).count();
return expected.isEmpty() ? 0.0 : (double) hit / expected.size();
}
生成侧还要看事实一致性,比如答案里提到的设备编号、时间、数值、故障原因,是否都能在证据里找到。
4. RAG 事实一致性指标怎么评估出来
答案:
事实一致性不是看答案流畅不流畅,而是看答案中的事实声明是否被证据支持。可以先把答案拆成 atomic claims,比如“3 号楼夜间能耗上涨 38%”“空调策略未关闭”“异常发生在 00:00 到 06:00”。然后逐条判断这些 claim 是否能在检索证据中找到支持。
评估方式可以分人工标注和模型辅助。高风险场景要人工抽检;大规模回归可以用 LLM-as-judge,但 judge 也要被约束,只能根据证据判断“支持 / 不支持 / 证据不足”。不能让评测模型凭常识判断。
{
"claim": "3 号楼 00:00-06:00 用电量上涨 38%",
"evidence": "3 号楼 00:00-06:00 用电量较上周同期上涨 38%",
"label": "SUPPORTED"
}
事实一致性可以定义为:
Fact Consistency = 被证据支持的事实数 / 答案中的事实总数
代码上可以保存评估明细:
CREATE TABLE fact_consistency_eval (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
request_id VARCHAR(64),
claim_text TEXT,
evidence_id VARCHAR(64),
label VARCHAR(32),
judge_reason TEXT,
created_at DATETIME
);
如果一个答案事实一致性低,即使用户觉得“写得很好”,也不能认为是合格答案。
5. 长期记忆怎么存储,具体存什么东西
答案:
长期记忆不能把所有对话原文都存进去。真正有价值的是稳定、可复用、经过确认的信息。比如在智慧园区场景里,可以存用户负责的楼宇范围、常看的能耗指标、偏好的报告格式、常用时间范围、历史确认过的设备别名、运维人员的处理偏好。
长期记忆一般会拆成结构化记忆和语义记忆。结构化记忆适合存明确字段,比如默认园区、默认楼宇、关注指标;语义记忆适合存用户偏好、历史总结和经验模式。敏感信息要脱敏,记忆要有来源、置信度、过期时间和删除能力。
{
"userId": "u_1024",
"memory": {
"defaultParkId": "park_A",
"focusBuildings": ["B1", "B3"],
"preferredMetrics": ["electricity_kwh", "hvac_runtime"],
"reportStyle": "brief_with_evidence"
},
"source": "user_confirmed",
"confidence": 0.95
}
存储表可以这样设计:
CREATE TABLE agent_memory (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
user_id VARCHAR(64) NOT NULL,
memory_key VARCHAR(128) NOT NULL,
memory_value JSON NOT NULL,
memory_type VARCHAR(32) NOT NULL,
source VARCHAR(64) NOT NULL,
confidence DECIMAL(5,4) NOT NULL,
expire_at DATETIME,
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL,
UNIQUE KEY uk_user_key(user_id, memory_key)
);
写入长期记忆必须有门槛,不能把模型推测当事实。
6. 有没有了解开源 Memory 框架,比如 Mem0
答案:
Mem0 这类 Memory 框架主要解决的是长期记忆的抽取、存储、检索和更新问题。它通常会从对话中提取用户偏好、事实信息和历史上下文,存到向量库或结构化存储里,在后续对话时按相关性召回。
但在业务系统里不能直接把 Mem0 当黑盒用。因为企业场景有权限、审计、过期、删除、冲突合并和敏感数据治理。比如用户曾经负责 B1 楼,后来权限变更了,长期记忆里仍然保留 B1 楼偏好,这就可能导致越权上下文注入。
我会把这类框架当作 memory pipeline 的一部分,而不是最终决策源。写入前要校验,读取时要过权限,使用时要带来源。
对话内容 -> 记忆候选抽取 -> 敏感信息过滤 -> 事实/偏好分类 -> 权限校验 -> 冲突合并 -> 写入 Memory Store -> 检索时按用户、租户、场景过滤
记忆读取接口需要带 auth context:
public List<MemoryItem> searchMemory(AuthContext auth, String query) {
List<MemoryItem> candidates = memoryVectorStore.search(auth.userId(), query);
return candidates.stream()
.filter(item -> permissionService.canRead(auth, item))
.toList();
}
7. Agent Runtime 是怎么设计的
答案:
Agent Runtime 我会设计成一个受控执行框架,而不是让模型自由调用工具。核心模块包括:请求接入、鉴权限流、意图识别、上下文构造、Memory 读取、RAG 检索、Planner、Tool Executor、Verifier、Trace Logger 和 Cost Controller。
请求进来后先判断用户身份和场景,再根据意图选择可用 skill 和工具。Planner 可以让模型生成计划,但计划必须经过校验,比如工具是否在白名单、参数是否完整、用户是否有权限、是否超过 token 预算。执行完工具后,结果会转成 evidence,最终答案必须引用 evidence。
Request -> Auth / RateLimit -> Intent Classifier -> Memory Retriever -> RAG Retriever -> Planner -> Plan Validator -> Skill Executor -> Evidence Builder -> LLM Generator -> Output Verifier -> Trace / Metrics
计划结构:
{
"intent": "energy_anomaly_diagnosis",
"steps": [
{
"id": "s1",
"skill": "query_energy_curve",
"input": {"buildingId": "B3", "range": "last_7_days"}
},
{
"id": "s2",
"skill": "query_bms_control_log",
"input": {"buildingId": "B3"}
},
{
"id": "s3",
"skill": "generate_diagnosis_report"
}
]
}
Runtime 的价值是稳定性和可回放。出问题时可以根据 traceId 看到模型看到了什么、调用了什么、为什么生成这个答案。
8. 既然是相对确定的工作流,为什么用 Skill 不用 Workflow
答案:
Workflow 适合描述完整业务流程,比如“提交巡检工单 -> 派单 -> 维修 -> 验收 -> 关闭”。它强调流程状态、审批、重试和节点顺序。Skill 更像可复用能力,比如“查询能耗曲线”“判断设备是否异常”“生成维修建议”“压缩上下文记忆”。
如果一个能力会被多个流程复用,就不应该写死在某个 workflow 里。比如“设备异常归因”既可以用于告警处理,也可以用于能耗诊断,还可以用于周报生成,这种能力更适合做成 skill。Agent 可以根据用户问题动态组合 skill,而不是每个场景都写一套 workflow。
Workflow:面向完整业务流程,状态驱动 Skill:面向可复用能力,输入输出稳定 Tool:面向底层动作,比如查库、调用接口
Skill 定义:
public interface Skill<I, O> {
String name();
O execute(I input, SkillContext context);
}
示例:
public class EnergyAnomalySkill implements Skill<EnergyInput, EnergyOutput> {
@Override
public String name() {
retu
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
本专栏聚焦 AI-Agent 面试高频考点,内容来自真实面试与项目实践。系统覆盖大模型基础、Prompt工程、RAG、Agent架构、工具调用、多Agent协作、记忆机制、评测、安全与部署优化等核心模块。以“原理+场景+实战”为主线,提供高频题解析、标准答题思路与工程落地方法,帮助你高效查漏补缺.
查看12道真题和解析