云计算百科
云计算领域专业知识百科平台

大模型实战:让 Agent 学会反思

前面已经搭好了:

  • 能用 RAG 检索文档的问答链路;
  • 多 Agent 的“家族分工”和调度器;
  • 调用监控、Trace、A/B 实验等工程能力。

但在真实使用中,你一定已经遇到过这种情况:

  • 明明文档里没有写,Agent 却一本正经地“编”出一段内容;
  • 数学题、逻辑题偶尔给错,还写得非常自信;
  • 问“为什么”时,它会凭感觉胡乱推断一个理由。

根本原因是:

我们现在的大部分 Agent,只有“正向生成”的本事,
没有“反向检查”和“自我怀疑”的机制。

专门做一件事:

在现有的 Agent 体系之上,加一层自我反思(Self-Reflection)能力,
让 Agent 在给用户答案之前,先审查一下自己有没有胡说。


一、先澄清:我们要的“自我反思”到底是什么?

这里的“自我反思”,不是哲学上的那一套,而是很工程化的东西,可以理解为:

在输出之前,强制再跑一遍**“慢思考(审稿人模式)”**,
对刚才的答案做一次结构化的检查和修订。

它至少包括三类检查:

  • 事实检查

    • 这句话在文档里有没有依据?
    • 数字/日期/名称是否和上下文一致?
  • 逻辑检查

    • 前后有没有自相矛盾?
    • 推理链条有没有断档?
  • 语气与置信度检查

    • 是不是用了“肯定”“必须”“一定”等绝对化表述?
    • 明明没证据,却表现得很自信?
  • 大致流程可以想象成:

    用户问题 →(快思考)生成初稿 →(慢思考)自我审查 → 修订版 → 返回用户


    二、两种实用架构:选一个就能落地

    根据你现在的系统形态和预算,可以考虑两种主要模式:

    2.1 单 Agent 双阶段模式(轻量版)

    一个 Agent 内部包含两个阶段:

  • 阶段1:像现在一样,直接生成答案;
  • 阶段2:用另一个 Prompt,让它“切换人格”,当成审稿人来挑自己毛病;
  • 如果发现问题,再让它自己按反馈改一版答案。
  • 特点:

    • 改造量小,不需要新建 Agent 类;
    • 成本增加有限(Prompt 长一点,多一轮生成)。

    2.2 双 Agent 模式(推荐)

    把角色拆开:

    • 生成 Agent:只管“怎么答”,不负责严格审查,保持自然流畅;
    • 审核 Agent:只管“答得对不对”,完全以审稿人心态工作。

    特点:

    • 职责清晰,代码结构更干净;
    • 审核 Agent 可以用不同模型/不同 Prompt,做更严苛的检查。

    下面我用双 Agent 模式作为主线来讲解,最后再给一个单 Agent 版本的轻量实现。


    三、核心接口设计:一个“自我反思 Agent”

    我们先抽象一个“带自我反思能力的 Agent”:

    from typing import Dict, Any, List
    import json

    class SelfReflectingAgent:
    """
    双Agent架构:
    – generator_llm: 负责生成答案
    – reviewer_llm: 负责审查答案
    """
    def __init__(self, generator_llm, reviewer_llm, max_reflection: int = 2):
    self.generator = generator_llm
    self.reviewer = reviewer_llm
    self.max_reflection = max_reflection

    # — 快思考:生成初稿 —
    def generate_answer(self, question: str) -> str:
    prompt = f"请直接、简明地回答这个问题:\\n{question}"
    return self.generator(prompt)

    # — 慢思考:结构化审查 —
    def review_answer(self, question: str, answer: str, docs: List[str]) -> Dict[str, Any]:
    review_prompt = self._build_review_prompt(question, answer, docs)
    resp = self.reviewer(review_prompt)
    try:
    data = json.loads(resp)
    except json.JSONDecodeError:
    data = {
    "valid": False,
    "issues": [{"type": "格式错误", "description": "审核输出非JSON", "location": ""}],
    "corrections": [],
    "confidence": 0.0
    }
    return data

    # — 应用审稿建议:简单版本用替换 —
    def apply_corrections(self, answer: str, corrections: List[Dict[str, str]]) -> str:
    for c in corrections:
    answer = answer.replace(c.get("original", ""), c.get("corrected", ""))
    return answer

    # — 整体入口 —
    def run(self, question: str, docs: List[str]) -> Dict[str, Any]:
    """
    返回结构:
    {
    "final_answer": str,
    "review": {…},
    "iterations": int,
    "status": "success|failure"
    }
    """
    answer = self.generate_answer(question)

    review = {}
    for i in range(self.max_reflection):
    review = self.review_answer(question, answer, docs)

    # 满足“审核通过”的条件直接返回
    if review.get("valid") and review.get("confidence", 0.0) >= 0.9:
    return {
    "final_answer": answer,
    "review": review,
    "iterations": i + 1,
    "status": "success"
    }

    # 有明确的 corrections,尝试自动修正
    if review.get("corrections"):
    answer = self.apply_corrections(answer, review["corrections"])
    else:
    # 没法修,说明问题比较大
    return {
    "final_answer": "当前无法生成可靠答案,请稍后再试,或交由人工处理。",
    "review": review,
    "iterations": i + 1,
    "status": "failure"
    }

    # 达到最大反思轮数仍然不过审
    return {
    "final_answer": "经过多轮检查仍无法确认答案可靠,建议人工复核。",
    "review": review,
    "iterations": self.max_reflection,
    "status": "failure"
    }


    四、关键点:审核 Prompt 一定要“结构化”

    自我反思能不能落地,很大程度上取决于审核 Prompt 写得好不好。

    4.1 审核 Prompt 的思路

    对审核 Agent 来说,你要告诉它:

  • 上下文有哪些(文档/检索结果);
  • 问题是什么;
  • 待审核答案是什么;
  • 你要它检查什么;
  • 用什么格式输出。
  • 一个实用的实现:

    class ReviewPromptBuilder:
    def __init__(self, max_docs: int = 5):
    self.max_docs = max_docs

    def build(self, question: str, answer: str, docs: List[str]) -> str:
    doc_block = "\\n".join(
    [f"[文档{i+1}]\\n{d[:300]}…" for i, d in enumerate(docs[:self.max_docs])]
    )

    return f"""
    你是一个严格的审稿人,需要根据给定的文档审查一个答案是否可靠。

    # 问题
    {question}

    # 参考文档(截断显示)
    {doc_block}

    # 待审核答案
    {answer}

    # 审查任务(请逐条检查)
    1. 文档引用是否准确?
    – 每条事实性陈述是否能在上述文档中找到支持?
    – 是否引用了文档中不存在的内容?

    2. 是否存在事实性错误?
    – 数字、日期、名称是否与文档一致?
    – 推论是否与文档描述矛盾?

    3. 逻辑是否自洽?
    – 同一答案内部有无矛盾?
    – 是否有明显的逻辑漏洞?

    4. 语气是否合理?
    – 是否有“肯定/必须/绝对”等过度自信的表达,在没有文档支持的情况下使用?

    # 输出要求
    仅输出一段 JSON 文本,格式如下:
    {{
    "valid": true/false,
    "issues": [
    {{
    "type": "引用错误|事实错误|逻辑错误|过度自信",
    "description": "问题描述",
    "location": "相关句子或片段"
    }}
    ],
    "corrections": [
    {{
    "type": "引用修正|事实修正|逻辑修正|语气修正",
    "original": "原句子",
    "corrected": "修正后的句子"
    }}
    ],
    "confidence": 0.0-1.0,
    "reasoning": "简要说明你做出上述判断的原因"
    }}

    不要输出任何多余解释。
    """

    然后在 SelfReflectingAgent 中用它:

    class SelfReflectingAgent:
    def __init__(…, …):

    self.prompt_builder = ReviewPromptBuilder()

    def _build_review_prompt(self, question, answer, docs):
    return self.prompt_builder.build(question, answer, docs)


    五、轻量版:在一个 Agent 里加“自问自答”反思

    如果你暂时不想上“双 Agent 模式”,或者只想在部分场景里做个试点,可以用单 Agent + 双阶段 Prompt的做法。

    5.1 逻辑流程

  • Prompt1:正常回答问题;
  • Prompt2:以“审稿人角色”检查 Prompt1 的回答;
  • 如果发现问题,Prompt3:根据审稿结果修正自己的回答。
  • 5.2 极简代码示例

    def self_reflecting_answer(llm, question: str, docs: List[str]) -> str:
    # 第一轮:正常回答
    context = "\\n\\n".join(docs[:3])
    answer_prompt = f"""
    你是一个问答助手,请基于以下上下文回答问题:

    上下文:
    {context}

    问题:
    {question}

    请直接给出答案,不要解释推理过程。
    """
    answer = llm(answer_prompt)

    # 第二轮:自我检查
    review_prompt = f"""
    你现在切换成一个严格的审稿人。

    问题:{question}
    你的回答:{answer}
    参考上下文:{context}

    请检查你的回答是否存在以下问题:
    1. 引用了上下文中不存在的内容?
    2. 数字/名称/日期等事实性内容是否有错误?
    3. 是否存在明显的逻辑矛盾?
    4. 是否有无依据的绝对化表述?

    如果有问题,请用自然语言说明问题,并给出一个“修正建议”;如果没有问题,请只回答“没有问题”。
    """
    review = llm(review_prompt)

    # 第三轮:如果有问题,根据反馈修正
    if "没有问题" in review:
    return answer
    else:
    revise_prompt = f"""
    你刚才的回答存在问题,具体反馈如下:
    {review}

    请根据这些反馈,重新给出一个更准确、更谨慎的答案。
    问题:{question}
    上下文:{context}
    """
    final_answer = llm(revise_prompt)
    return final_answer

    这个版本实现成本很低,而且对你现有代码改动最小,完全可以先在一个关键场景试点:
    比如「重要的制度问答、合同条款解释」等,再根据效果决定是否升级到“双 Agent 模式」。


    六、怎么验证“自我反思”有没有用?

    既然你前面已经有:

    • 调用级日志(LLMCallLog);
    • 工作流 Trace;
    • 简单 A/B 框架。

    那验证这套“自我反思”能力是不是值得保留,可以直接做一个小实验:

  • 选一批有标准答案的问答样本(比如 50~200 条);
  • 对比两种模式:
    • 模式 A:普通 Agent;
    • 模式 B:启用自我反思的 Agent;
  • 对每条样本打标签:
    • 是否回答正确;
    • 是否引用了不存在的内容;
    • 是否过度自信。
  • 你要重点关注的是:

    • 事实性错误减少了多少;
    • “编造内容”的频率下降了多少;
    • 增加的延迟和成本(多调用一次模型)你是否可以接受。

    在监控系统里可以加两类指标:

    • self_reflection_trigger_rate:每 100 次调用里有多少次触发了反思;
    • self_reflection_fix_rate:在触发反思的调用中,有多少次最终答案发生了实质性变化。

    如果你在实验里看到:

    • 错误率明显下降(例如从 10% 降到 3–5%);
    • 延迟从 1s 增加到 1.3–1.5s,还在可接受范围内;

    那这套“自我反思能力”就非常值得在关键业务场景里推广。


    七、如何接到你现有的多 Agent / 工作流体系里?

    推荐一个尽量“无痛”的接法:

  • 只替换关键节点

    • 不要改整个系统;
    • 只把原来的 RAG_QA_Agent 替换成 SelfReflectingAgent 封装的节点。
  • 保持外部接口不变

    • 对上层 Coordinator 来说,handle(question, state) -> answer 签名不变;
    • 只是在节点内部多跑了一轮“快思考 + 慢思考”。
  • 先灰度部分流量

    • 比如仅对 10% 用户请求启用自我反思;
    • 或者仅对“命中特定意图/领域”的请求启用。
  • 把反思过程的关键信息写进 Trace

    • 审核是否通过;
    • 反思轮数;
    • 是否发生了修正;
    • 审稿 Agent 的置信度。
  • 这四点完成后,你的 Agent 系统就从:

    “会回答问题,但自己不检查”

    升级成:

    “既会回答问题,又会先检查自己说的靠不靠谱”。


    八、小结

    这一篇做的事情是:在你已经有的 Agent 家族 + 工作流 + 监控 基础之上,再往前迈一步——让 Agent 拥有一个简单但非常实用的能力:

    在张口之前,先问问自己:
    “我说的有依据吗?有没有可能在瞎编?”

    落地上,你可以:

    • 先用单 Agent 双阶段的轻量方案,在一个场景试水;
    • 再升级到双 Agent 模式,专门用一个“审稿 Agent”盯事实、逻辑和语气;
    • 用你现有的评估与监控体系,量化“错误率下降”和“延迟增加”的 tradeoff。
    赞(0)
    未经允许不得转载:网硕互联帮助中心 » 大模型实战:让 Agent 学会反思
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!