生成一个AI面试复盘标题,只需要一个标题,不需要其他的任何文本。

13 阅读5分钟

AI 面试复盘:查漏补缺,迭代优化

一、为什么“复盘”要做成技术系统

面试结束后凭记忆回顾,得到的往往是模糊感受而非事实数据:你记得自己卡住了一道题,却记不清卡在哪一步;你觉得自己答得不错,却不知道回答里有几处逻辑跳跃。把复盘做成一条流水线后,输入是原始问答记录,输出是可执行的迭代任务,每一步都可追溯、可量化、可对比。

二、四层架构

层职责关键产出
采集层录音转写、按题目边界切分问答对QA 记录
结构化层对每条回答做能力维度的打分与标注结构化评估
归因层汇总缺口,按频次和严重度排序缺口清单
迭代层生成复习任务,并在下一轮验证是否改善迭代计划与对比报告

核心原则:一次面试只提供样本,不提供结论。任何单场结论都要落到“待验证假设”,由下一场面试证伪或确认。

三、代码演示

1. 数据模型与问答对切分

from dataclasses import dataclass, field, asdict
import json, hashlib

@dataclass
class QA:
    q: str            # 面试官问题
    a: str            # 候选人回答(转写文本)
    tag: str = ""     # 题目类型:算法/系统设计/项目/行为
    rounds: int = 0   # 追问轮次

def split_qa(transcript: list[dict]) -> list[QA]:
    """transcript: [{"role": "interviewer"|"candidate", "text": str}]"""
    out, cur = [], None
    for turn in transcript:
        if turn["role"] == "interviewer":
            if cur:
                out.append(cur)
            cur = QA(q=turn["text"], a="", tag=classify(turn["text"]))
        elif cur:
            cur.a += turn["text"]
            cur.rounds += 1
    if cur:
        out.append(cur)
    return out

def classify(text: str) -> str:
    rules = {"算法": ("复杂度", "数组", "链表", "树", "动态规划"),
             "系统设计": ("架构", "并发", "扩容", "缓存", "存储"),
             "项目": ("项目", "你做过", "背景", "指标")}
    for tag, kws in rules.items():
        if any(k in text for k in kws):
            return tag
    return "行为"

2. 结构化评估:强制 JSON,拒绝自由发挥

评估这一步最容易失控:直接让模型“点评一下”,得到的会是通顺但无用的话术。解决办法是固定维度、固定档位、要求给出原文证据。

EVAL_PROMPT = """你是资深面试官。基于给定问答对评估候选人,只输出 JSON。
维度与档位(1-5 分):clarity 表达清晰度、depth 技术深度、structure 结构化、
evidence 结论是否有事实支撑、handling 追问与抗压。
要求:
1) 每个维度给出 score 与 evidence(必须是回答原文片段,不得改写);
2) gap 列出答得不完整的知识点,最多 3 条;
3) 若信息不足以评分,score 记 null 并在 evidence 写 "insufficient"。
输出格式:{"clarity":{"score":3,"evidence":"..."}, ..., "gap":[...]}"""

def evaluate(qa: QA) -> dict:
    raw = llm_call(EVAL_PROMPT, f"问题:{qa.q}\n回答:{qa.a}")
    return json.loads(raw)          # 生产环境加 schema 校验与重试

校验必做:任何 evidence 字段都要在实际回答文本中出现。对不上的,直接判定这条评估无效。这一步能挡掉大部分“看起来合理但其实是编的”评价。

3. 归因:从单条评价到缺口清单

from collections import Counter, defaultdict

def aggregate(evals: list[dict]) -> list[dict]:
    gap_counter, dim_scores = Counter(), defaultdict(list)
    for ev in evals:
        for g in ev.get("gap", []):
            gap_counter[g.strip()] += 1
        for dim, v in ev.items():
            if isinstance(v, dict) and v.get("score"):
                dim_scores[dim].append(v["score"])

    dims = {d: round(sum(s) / len(s), 2) for d, s in dim_scores.items()}
    ranking = gap_counter.most_common()
    return [{"dimension_avg": dims,
             "gaps": [{"gap": g, "hits": n} for g, n in ranking],
             "priority": [g for g, n in ranking if n >= 2]}]

用 hits >= 2 作为优先级门槛很关键:同一个缺口要出现两次以上,才值得占用复习时间。

4. 迭代任务与下轮验证

def plan(agg: dict) -> list[dict]:
    tasks = []
    for dim, score in agg["dimension_avg"].items():
        if score < 3.5:
            tasks.append({"type": "drill", "target": dim,
                          "action": f"针对 {dim} 做 3 次限时模拟,录音自评"})
    for g in agg["priority"]:
        tasks.append({"type": "knowledge", "target": g,
                      "action": "补一个最小可讲透的知识单元,写成 200 字提纲"})
    return tasks

def compare(before: dict, after: dict) -> dict:
    """比较两次面试的同维度均分,判断迭代是否真的有效"""
    delta = {d: round(after["dimension_avg"][d] - before["dimension_avg"].get(d, 0), 2)
             for d in after["dimension_avg"]}
    fixed = set(g["gap"] for g in before["priority"]) - \
            set(g["gap"] for g in after["priority"])
    return {"delta": delta, "closed_gaps": sorted(fixed)}

若某维度分数未升,且对应缺口仍在清单里,说明这一轮复习方式无效,需要更换练习形态(例如从“看资料”改成“限时口头复述”),而不是继续堆时间。

5. 组合成一条命令

def review(transcript, store="review.jsonl"):
    qas = split_qa(transcript)
    evals = [evaluate(qa) for qa in qas]
    agg = aggregate(evals)
    tasks = plan(agg)
    rec = {"id": hashlib.md5(json.dumps(transcript, ensure_ascii=False).encode()).hexdigest()[:8],
           "qa_count": len(qas), "aggregate": agg, "tasks": tasks}
    with open(store, "a", encoding="utf-8") as f:
        f.write(json.dumps(rec, ensure_ascii=False) + "\n")
    return rec

id 用内容哈希,保证同一份转写重复跑不会在库里灌入两条记录,方便后续跨场次对比。

四、四个容易踩的坑

评估漂移:同一个人不同场次的评分标准会慢慢变化。做法是把历史评估和人工抽检结果存下来,每次换模型或改提示词后先跑一遍回归集,确认分数分布没有整体偏移。

过拟合单场:一场面试被拒,可能是岗位不匹配、面试官偏好、当天状态。缺口必须跨场次聚合,单场只允许进“待验证假设”。

隐私与成本:转写文本含个人信息,落库前应做脱敏(人名、公司、联系方式),并按场次设置保留期。评估环节每条问答一次调用,可先做廉价预处理——过滤复述型回答、合并重复追问——再送模型,通常能砍掉三成调用量。

只优化表达不补深度:清晰度分数容易提升,深度很难。如果 clarity 上涨而 depth 停滞,说明练习偏向“讲得顺”,需要补的是知识密度与追问耐力。

五、结语

复盘的价值不在于给上一场打分,而在于把“我好像不太行”转换成“第 3 类追问下我的方案缺少容量估算”——后者才是能改变的。系统的作用,是让这个转换每次都发生,并且在下一次面试时告诉你它到底有没有发生。

海量精选技术文档和实战案例持续更新,敬请关注【风骏时光少年】