各位同仁,大家好。
今天,我们将深入探讨一个在构建智能体(Agent)时至关重要的设计模式——“Self-Reflection”(自我反思)模式。尤其,我们会聚焦于一个特定的实现策略:在智能体将最终结果呈现给用户之前,插入一个专门的节点,让智能体对自己的输出进行“找Bug”和“修复Bug”的工作。这不仅仅是一个技术细节,它代表了我们如何从根本上提升AI智能体的可靠性、准确性和用户体验。
第一章:智能体设计与“首轮误差”的挑战
在人工智能领域,特别是基于大型语言模型(LLM)的智能体,正在快速演进,从简单的问答系统发展到能够规划、执行复杂任务的自主实体。一个典型的智能体工作流程大致如下:
- 接收用户输入 (User Input):理解用户提出的问题、指令或目标。
- 规划 (Planning):根据输入,智能体制定一个实现目标的策略或步骤。这可能涉及分解复杂任务、选择合适的工具等。
- 执行 (Execution):智能体根据规划,调用内部函数、外部工具(如搜索引擎、API、代码解释器等),或直接生成文本来完成任务。
- 结果输出 (Output Generation):将执行过程中获得的信息或生成的文本组织成最终答案,呈现给用户。
这个流程看起来直接而高效。然而,LLM智能体在实际运行中面临诸多挑战,尤其是在“首轮生成”中。这些挑战常常导致各种形式的“误差”:
- 幻觉 (Hallucination):智能体生成听起来合理但实际上是虚构或不准确的信息。
- 逻辑错误 (Logical Errors):在规划或执行步骤中出现推理缺陷,导致结果不符合逻辑。
- 信息不完整 (Incomplete Information):未能充分利用所有可用信息,或遗漏了用户需求中的关键部分。
- 对提示词的误解 (Prompt Misinterpretation):未能准确把握用户意图,导致偏离主题或回答不符合预期。
- 工具使用不当 (Improper Tool Usage):选择错误的工具,或以不正确的方式使用工具,导致获取错误数据或无法完成任务。
- 输出格式不符 (Incorrect Output Format):未能按照用户或系统要求的特定格式生成结果。
- 安全与伦理问题 (Safety & Ethical Issues):生成有害、偏见或不当内容。
当这些误差直接传递给用户时,会带来一系列负面后果:用户感到困惑和沮丧,需要投入额外的时间进行澄清和修正,从而侵蚀了用户对智能体的信任,并增加了系统整体的运行成本。
我们如何降低这些“首轮误差”的影响,甚至在它们到达用户之前就加以纠正呢? 这正是“Self-Reflection”模式的核心价值所在。
第二章:’Self-Reflection’ 模式的定义与工作原理
“Self-Reflection”模式,顾名思义,是智能体对自己内部状态、生成内容或执行结果进行批判性审查和评估的过程。它模仿了人类在完成一项任务后,主动进行“回溯思考”和“自我校对”的行为。
在我们的特定讨论中,’Self-Reflection’ 模式的核心在于:在智能体即将把结果输出给用户之前,增加一个强制性的、独立的评估节点。在这个节点中,智能体扮演“内部批评者”的角色,检查自己即将发布的成果是否存在潜在的错误、遗漏或不符合要求的地方。
我们可以将其想象成一个质量控制(QC)环节,但这个QC环节是由智能体自己完成的。
工作原理:
- 初步生成 (Initial Generation):智能体按照常规流程,基于用户输入和内部规划,生成一个初步的响应、代码、计划或任何形式的输出。
- 进入反思节点 (Enter Reflection Node):这个初步生成的结果不是直接给到用户,而是被送入一个专门设计的“反思模块”。
- 反思机制 (Reflection Mechanism):反思模块通常是一个独立的LLM调用(或一系列调用),它接收:
- 原始用户查询。
- 智能体此前的思考过程(例如,规划步骤、使用的工具、工具的输出等)。
- 智能体初步生成的待输出结果。
- 一套明确的反思准则或检查清单(Prompt中给出)。
反思模块的任务是根据这些准则,对初步结果进行严格审查,找出潜在的“Bug”。
- 生成反思报告 (Generate Reflection Report):反思模块输出一份报告,其中包含:
- 是否存在问题?
- 如果存在,具体问题是什么(例如,事实错误、逻辑不一致、格式不符、遗漏信息等)?
- 如何改进或纠正这些问题?(这可以是具体的修改建议,也可以是重新执行某个步骤的指令)。
- 如果不存在问题,则明确声明“未发现问题”。
- 决策与修正 (Decision & Correction):
- 如果反思报告指出问题,智能体将利用这份报告作为新的输入,回到之前的某个步骤(例如,重新规划、重新执行工具、重新生成文本),尝试修正错误。这个修正过程可能是一个迭代循环。
- 如果反思报告未发现问题,或者经过多次修正后仍未发现问题,则智能体认为结果已达到要求。
- 最终输出 (Final Output):经过反思和可能的多轮修正后,智能体将最终的、高质量的结果呈现给用户。
概念架构图示(非图形):
[用户输入]
|
V
[智能体核心规划与执行模块]
| (初步结果,包括中间思考过程和工具输出)
V
[自我反思节点]
|
+--- [反思LLM调用] --- (反思报告:发现问题及改进建议 / 未发现问题)
|
V
[决策模块]
|
+--- (如果发现问题) --> [返回智能体核心规划与执行模块进行修正]
| ^
| | (修正后的结果)
+--- (如果未发现问题) --> [最终结果输出给用户]
通过这种方式,我们为智能体构建了一个内部的质量保障循环,显著提升了其输出的可靠性。
第三章:自我反思模式的关键优势
引入自我反思模式并非没有成本(例如额外的LLM调用带来延迟和费用),但其带来的收益往往远超这些成本,尤其是在对准确性和可靠性要求较高的应用场景中。
-
显著提升输出的准确性和可靠性:
- 直接对抗LLM的固有弱点,如幻觉和逻辑跳跃。通过强制智能体审视自己的输出,可以捕捉并纠正许多在首次尝试时可能出现的错误。
- 确保事实的精确性,通过与外部工具(如搜索引擎)返回的结果进行比对。
-
优化用户体验,减少交互摩擦:
- 用户接收到的是经过智能体内部“校对”的高质量信息,减少了用户因错误信息而进行的反复提问和澄清。
- 提升了用户对智能体能力的信任感和满意度。
-
缩短迭代周期,提高效率:
- 智能体在内部自行修正错误,减少了需要人工介入纠正或用户重新引导的次数。
- 对于复杂的任务,内部迭代比外部反馈循环更为高效。
-
增强对复杂指令和约束的适应性:
- 反思机制可以被设计来检查输出是否严格遵守了用户在提示中提出的所有约束条件(例如,字数限制、特定格式、包含或排除某些信息等)。
- 即使智能体在初步生成时忽略了某些微妙的指令,反思阶段也有机会发现并纠正。
-
提升安全性和伦理合规性:
- 反思阶段可以包含专门的检查,以确保生成的内容不包含有害、偏见、歧视性或不适当的语言。
- 这对于面向公众的AI应用尤为重要,有助于维护品牌形象和社会责任。
-
提高智能体的鲁棒性 (Robustness):
- 即使在面对模糊、矛盾或具有挑战性的输入时,反思机制也能帮助智能体更好地处理不确定性,并通过自我修正来提供更稳健的答案。
通过将自我反思嵌入到智能体的工作流程中,我们不仅仅是在修复错误,更是在从根本上提升智能体的“智能”水平,使其行为更接近人类专家在完成任务时的严谨性。
第四章:实施自我反思:架构考量与设计
将自我反思节点集成到智能体架构中,需要仔细的规划和设计。以下是一些关键的架构考量:
4.1 集成点选择
自我反思节点可以放置在智能体流程的不同阶段,但最常见且效果显著的位置是:
- 在最终输出给用户之前:这是我们今天主要讨论的场景,确保发送给用户的最终响应是经过审查的。
- 在工具执行结果被采纳之前:智能体在调用外部工具后,可以反思工具返回的结果是否符合预期,是否需要进一步查询或修正。
- 在生成复杂计划之后:在执行任何步骤之前,反思计划本身的合理性、完整性和可行性。
4.2 独立的反射代理/提示
为了确保反思的客观性和有效性,通常建议使用一个独立的“思考模式”来执行反思。这可以通过以下方式实现:
- 独立的Prompt:为反思阶段设计一个与生成阶段截然不同的Prompt。生成Prompt鼓励创造性和完成任务,而反思Prompt则鼓励批判性思维、挑剔和错误检测。
- (可选)独立的LLM实例或模型:在某些高性能或高安全要求的场景下,甚至可以使用不同的LLM模型实例或针对批判性评估进行过微调的模型来执行反思。这可以进一步隔离思维模式,避免生成模型在反思时出现“自我维护”的倾向。
4.3 上下文管理
反思机制的有效性高度依赖于其可访问的上下文信息。为了做出明智的判断,反思模块需要:
- 原始用户查询:理解用户最初的需求和目标。
- 智能体的内部思考过程:例如,智能体是如何规划的,它做了哪些假设,它尝试了哪些步骤。这通常以“思考链”(Chain-of-Thought)的形式提供。
- 初步生成的待输出结果:这是反思的主要目标。
- (如果适用)工具执行的详细结果:如果智能体使用了工具,反思模块需要查看工具的原始输出,而不仅仅是智能体对输出的解释。
这些上下文信息需要以结构化且易于LLM理解的方式提供给反思Prompt。
4.4 迭代限制与终止条件
自我反思和修正可能是一个迭代过程。为了防止无限循环或效率低下,必须设定明确的迭代限制和终止条件:
- 最大迭代次数 (Max Iterations):例如,允许最多进行3次反思-修正循环。
- 收敛条件 (Convergence Condition):如果连续几轮反思都未能发现新的问题,或者发现的问题与之前相同,则可以认为已经收敛,停止迭代。
- 时间限制 (Time Limit):为整个反思-修正过程设置一个总时间限制。
- 成本限制 (Cost Limit):对API调用成本进行限制。
4.5 监控与日志
如同任何复杂的系统,对自我反思机制的监控和日志记录至关重要。这有助于:
- 调试:理解反思机制何时有效,何时失效,以及为什么。
- 优化:分析反思报告和修正结果,以改进反思Prompt和准则。
- 评估:量化反思机制对最终输出质量的影响。
表格:反思模块输入与输出
| 输入 (Input) | 输出 (Output) |
|---|---|
| 原始用户指令 | 反思状态:"No Issues Found" 或 "Issues Detected" |
| 智能体内部思考过程 (CoT/Plan) | 问题列表 (如果存在):清晰列出发现的所有问题,例如: 1. 事实错误: "[具体错误描述]",应为 "[正确信息]"2. 逻辑不一致: "[具体不一致描述]"3. 格式错误: "[具体格式要求]",但实际为 "[实际格式]"4. 遗漏信息: "[遗漏的关键点]"5. 安全/伦理问题: "[具体不当内容]" |
| 智能体初步生成的待输出结果 | 改进建议 (如果存在):针对每个问题,提供具体的修正方案或重新执行的指令,例如: 1. “请重新查询[关键词]以获取准确数据。”2. “请修改[文本片段]使其符合逻辑。”3. “请将输出格式调整为JSON数组。”4. “请补充关于[主题]的细节。”5. “请重写[句子]以避免潜在的偏见。” |
| (可选)工具调用记录及原始输出 | (内部状态更新):智能体根据反思报告更新其内部状态,例如,将 needs_replan 或 needs_re_execute 标记为 True,并存储改进建议,以便下一个生成步骤使用。 |
| (可选)预设的反思准则或检查清单 | (迭代计数器):记录当前是第几次反思循环。 |
第五章:实践实现:代码示例与模式
接下来,我们将通过具体的代码示例来演示如何实现自我反思模式。我们将使用Python,并结合LangChain等库的概念(即使不直接使用,其思想也普遍适用)。
5.1 核心反思提示词设计
一个高质量的反思提示词是成功的关键。它需要清晰地指示LLM扮演的角色、需要检查的内容、以及期望的输出格式。
REFLECTION_PROMPT_TEMPLATE = """
你现在是一个极其严格且专业的AI输出质量审核员。你的任务是审查另一个AI智能体为用户生成的初步响应。
请仔细阅读以下信息:
1. **原始用户指令**:用户最初的要求是什么?
2. **智能体的思考过程**:智能体为了生成响应所经历的内部步骤、决策、使用的工具以及工具的原始输出。这可以帮助你理解智能体的意图。
3. **智能体初步生成的响应**:这是需要你审查的最终输出草稿。
你的审查必须基于以下准则:
- **事实准确性**:响应中是否存在任何事实错误或幻觉?是否与你所知的真实世界信息(或工具输出)相符?
- **逻辑一致性**:响应的推理过程是否严密?是否存在逻辑漏洞或矛盾?
- **完整性**:是否充分回答了用户指令的所有方面?是否遗漏了关键信息?
- **相关性**:响应是否紧密围绕用户指令,没有离题?
- **格式符合性**:如果用户指令有特定的格式要求(例如,列表、JSON、代码块),响应是否符合?
- **安全性与伦理**:响应是否包含任何有害、偏见、歧视性或不适当的内容?
- **清晰度与简洁性**:响应是否易于理解,没有不必要的冗余?
请按照以下格式输出你的审查结果:
如果发现问题:
```json
{{
"status": "issues_detected",
"issues": [
{{
"type": "事实错误",
"description": "响应中关于[某主题]的描述与[工具输出/已知事实]不符。",
"suggestion": "请重新检查[信息来源]并修正该事实。"
}},
{{
"type": "逻辑不一致",
"description": "智能体声称[A],但其推理过程或后续结论却依赖[非A]。",
"suggestion": "请重新审视推理链条,确保逻辑自洽。"
}}
// ... 其他问题
],
"action": "revise", // 指示智能体需要进行修正
"revised_prompt_for_agent": "基于上述问题,请智能体重新生成或修改其响应,重点解决以下问题:[总结所有问题的核心点,作为给智能体的重新生成指令]"
}}
如果未发现任何问题:
{{
"status": "no_issues_found",
"issues": [],
"action": "proceed", // 指示智能体可以直接输出
"revised_prompt_for_agent": null
}}
请确保你的输出严格遵守JSON格式,并且你的判断是客观、严谨的。
原始用户指令:
{user_query}
智能体的思考过程:
{agent_thought_process}
智能体初步生成的响应:
{agent_initial_response}
"""
#### 5.2 示例1:简单文本生成与反思
假设智能体需要回答一个关于历史事件的问题。
```python
import json
from typing import Dict, Any, Optional
# 模拟LLM调用
def mock_llm_call(prompt: str) -> str:
"""
这是一个模拟LLM调用的函数。
在真实场景中,这里会集成OpenAI, Anthropic或其他LLM API。
为了演示,我们使用简单的条件逻辑来模拟不同响应。
"""
print(f"n--- LLM Call (Prompt Snippet: {prompt[:100]}...) ---")
if "事实错误" in prompt and "巴拿马运河" in prompt:
return json.dumps({
"status": "issues_detected",
"issues": [
{
"type": "事实错误",
"description": "巴拿马运河的开通时间有误,实际开通时间是1914年。",
"suggestion": "请修正巴拿马运河的开通时间。"
}
],
"action": "revise",
"revised_prompt_for_agent": "请修正关于巴拿马运河开通时间的错误,确保其为1914年。"
})
elif "不完整" in prompt and "哥伦布" in prompt:
return json.dumps({
"status": "issues_detected",
"issues": [
{
"type": "完整性",
"description": "响应中只提到了哥伦布的首次航行,但没有提及他总共进行了几次航行。",
"suggestion": "请补充哥伦布总共进行了几次航行以及大致时间。"
}
],
"action": "revise",
"revised_prompt_for_agent": "请补充哥伦布总共进行了几次航行以及大致时间。"
})
else:
return json.dumps({
"status": "no_issues_found",
"issues": [],
"action": "proceed",
"revised_prompt_for_agent": None
})
class Agent:
def __init__(self, llm_caller):
self.llm_caller = llm_caller
self.max_reflections = 2
def _generate_initial_response(self, user_query: str, current_context: str = "") -> Dict[str, str]:
"""模拟智能体根据用户查询和当前上下文生成初步响应。"""
print(f"n--- Agent Initial Generation ---")
prompt = f"请回答以下问题:'{user_query}'。n{current_context}"
# 这里模拟一个LLM的生成行为
if "巴拿马运河开通时间" in user_query and "1914年" not in current_context:
response_text = "巴拿马运河于1920年正式开通,是连接大西洋和太平洋的重要航道。"
thought_process = "分析用户问题,尝试回忆巴拿马运河开通时间。初步判断为20世纪初。但可能记忆有误。"
elif "哥伦布航行次数" in user_query and "四次" not in current_context:
response_text = "克里斯托弗·哥伦布于1492年首次横渡大西洋,发现了美洲新大陆。"
thought_process = "聚焦哥伦布的首次航行,未考虑其他航行。"
else:
response_text = f"这是关于'{user_query}'的修正后的准确信息:巴拿马运河于1914年正式开通。克里斯托弗·哥伦布总共进行了四次跨大西洋航行,分别在1492年、1493年、1498年和1502年。"
thought_process = "根据反思建议,补充了哥伦布的航行次数和时间,并修正了巴拿马运河的开通时间。"
return {"response": response_text, "thought_process": thought_process}
def _reflect_on_response(self, user_query: str, agent_thought: str, agent_response: str) -> Dict[str, Any]:
"""
使用自我反思提示词来评估智能体的响应。
"""
prompt = REFLECTION_PROMPT_TEMPLATE.format(
user_query=user_query,
agent_thought_process=agent_thought,
agent_initial_response=agent_response
)
reflection_raw = self.llm_caller(prompt)
try:
reflection_result = json.loads(reflection_raw)
return reflection_result
except json.JSONDecodeError:
print(f"Warning: Reflection LLM returned invalid JSON: {reflection_raw}")
return {"status": "error", "issues": [], "action": "error", "revised_prompt_for_agent": None}
def process_query(self, user_query: str) -> str:
current_response_info = self._generate_initial_response(user_query)
initial_response = current_response_info["response"]
agent_thought = current_response_info["thought_process"]
final_response = initial_response
print(f"nInitial Response:n{initial_response}")
for i in range(self.max_reflections):
print(f"n--- Reflection Cycle {i+1} ---")
reflection_result = self._reflect_on_response(user_query, agent_thought, final_response)
if reflection_result["status"] == "no_issues_found":
print("Reflection: No issues found. Proceeding with current response.")
break
elif reflection_result["status"] == "issues_detected":
print(f"Reflection: Issues detected. Proposed action: {reflection_result['action']}")
for issue in reflection_result["issues"]:
print(f" - Type: {issue['type']}, Desc: {issue['description']}, Suggestion: {issue['suggestion']}")
# 更新上下文,尝试重新生成
correction_prompt = reflection_result["revised_prompt_for_agent"]
print(f"Agent will attempt to revise based on: {correction_prompt}")
# 模拟智能体根据修正建议进行重新生成
# 在真实Agent中,这里会触发重新规划或重新调用LLM来修改响应
# 这里我们简化为传递一个修正上下文
current_response_info = self._generate_initial_response(user_query, current_context=correction_prompt)
final_response = current_response_info["response"]
agent_thought = current_response_info["thought_process"] # 思考过程也可能更新
print(f"nRevised Response after Reflection {i+1}:n{final_response}")
else:
print(f"Reflection: Error or unknown status: {reflection_result['status']}. Stopping reflection.")
break
else:
print(f"nMax reflections reached ({self.max_reflections}). Outputting the last revised response.")
return final_response
# 运行示例
my_agent = Agent(mock_llm_call)
print("n--- Test Case 1: Factual Error ---")
query1 = "请告诉我巴拿马运河的开通时间。"
result1 = my_agent.process_query(query1)
print(f"nFinal Result for '{query1}':n{result1}")
print("n--- Test Case 2: Incomplete Information ---")
query2 = "克里斯托弗·哥伦布共进行了几次航行?"
result2 = my_agent.process_query(query2)
print(f"nFinal Result for '{query2}':n{result2}")
print("n--- Test Case 3: Already Correct ---")
query3 = "请说明地球是圆的还是扁的。" # 假设智能体直接能正确回答
# 为了模拟,我们让_generate_initial_response对这个查询直接返回正确答案,
# 这样_reflect_on_response就不会检测到问题。
result3 = my_agent.process_query(query3)
print(f"nFinal Result for '{query3}':n{result3}")
代码解释:
mock_llm_call: 这是一个模拟真实LLM API调用的函数。在实际项目中,你会替换为像openai.ChatCompletion.create或langchain.LLMChain这样的调用。为了演示,它根据Prompt内容模拟不同的反思结果。Agent类:_generate_initial_response: 模拟智能体的“首次尝试”生成响应。它有意地在某些查询中制造错误(例如,巴拿马运河开通时间错误,哥伦布航行次数不完整),以便反思机制可以捕捉到。_reflect_on_response: 负责调用LLM(通过mock_llm_call),使用REFLECTION_PROMPT_TEMPLATE来评估智能体的初步响应。它解析LLM返回的JSON,并返回反思结果。process_query: 这是核心逻辑。它首先生成初步响应,然后进入一个循环,反复进行反思。如果反思发现问题,它会利用反思报告中revised_prompt_for_agent的建议,再次调用_generate_initial_response尝试修正。这个循环会持续到没有发现问题,或者达到最大反思次数为止。
这个示例清晰地展示了“生成 -> 反思 -> 修正(如果需要)”的迭代过程。
5.3 示例2:代码生成与反思(概念性)
对于代码生成场景,反思可以更加复杂,涉及静态分析、动态执行测试甚至测试用例生成。
# ... (mock_llm_call 和 Agent 类定义与之前类似,但需要修改其内部逻辑以适应代码生成)
class CodeGeneratingAgent(Agent):
def _generate_initial_code(self, user_request: str, current_context: str = "") -> Dict[str, str]:
"""模拟智能体生成Python代码。"""
print(f"n--- Code Agent Initial Generation ---")
prompt = f"请生成Python代码来完成以下任务:'{user_request}'。n{current_context}"
if "计算斐波那契数列" in user_request and "递归" not in current_context:
code = """
def fibonacci(n):
if n <= 0:
return 0
elif n == 1:
return 1
else:
return fibonacci(n-1) + fibonacci(n-2) # 效率低下的递归实现
"""
thought = "生成了一个简单的递归斐波那契函数。"
elif "文件操作" in user_request and "try-except" not in current_context:
code = """
def read_file(filepath):
f = open(filepath, 'r')
content = f.read()
f.close()
return content
"""
thought = "生成了基本的读取文件代码,但可能缺少错误处理。"
else:
# 假设经过修正后,生成了更优化的或带错误处理的代码
code = """
def fibonacci_optimized(n):
a, b = 0, 1
for _ in range(n):
yield a
a, b = b, a + b
def read_file_safe(filepath):
try:
with open(filepath, 'r') as f:
content = f.read()
return content
except FileNotFoundError:
return f"Error: File not found at {filepath}"
except Exception as e:
return f"An error occurred: {e}"
"""
thought = "根据反思建议,改进了斐波那契函数为迭代器,并为文件读取添加了异常处理。"
return {"code": code, "thought_process": thought}
def _reflect_on_code(self, user_request: str, agent_thought: str, agent_code: str) -> Dict[str, Any]:
"""
专门为代码生成设计反思逻辑。
反思准则将包括:语法错误、逻辑错误、效率、安全性、可读性等。
"""
reflection_prompt_code = f"""
你现在是一个专业的代码评审员。你的任务是审查另一个AI智能体为用户生成的Python代码。
请仔细阅读以下信息:
1. **原始用户请求**:用户最初要求编写什么代码?
2. **智能体的思考过程**:智能体在生成代码时的思路。
3. **智能体初步生成的代码**:这是需要你审查的Python代码。
你的审查必须基于以下准则:
- **语法正确性**:代码是否符合Python语法?
- **逻辑正确性**:代码是否正确实现了用户请求的功能?是否存在逻辑错误或边界条件处理不当?
- **效率**:代码的性能如何?是否存在更高效的实现方式(例如,递归深度限制,循环优化)?
- **健壮性/错误处理**:代码是否考虑了潜在的错误(例如,文件不存在,输入无效),并进行了适当的错误处理?
- **安全性**:代码是否存在安全漏洞(例如,注入风险,不安全的eval)?
- **可读性与规范**:代码是否清晰易懂,符合PEP8等编码规范?
请按照以下JSON格式输出你的审查结果:
如果发现问题:
```json
{{
"status": "issues_detected",
"issues": [
{{
"type": "效率低下",
"line_number": "10",
"description": "斐波那契函数使用了低效的递归实现,对于大N值会栈溢出或计算缓慢。",
"suggestion": "建议改为迭代实现或记忆化递归。"
}},
{{
"type": "健壮性不足",
"line_number": "5",
"description": "文件读取未包含try-except块,如果文件不存在会直接报错。",
"suggestion": "请添加try-except块处理FileNotFoundError和其他IOError,并使用with语句确保文件关闭。"
}}
],
"action": "revise",
"revised_prompt_for_agent": "基于上述问题,请智能体重新生成或修改代码,重点解决:优化斐波那契函数的效率,并为文件操作添加健壮的错误处理。"
}}
如果未发现任何问题:
{{
"status": "no_issues_found",
"issues": [],
"action": "proceed",
"revised_prompt_for_agent": null
}}
原始用户请求:
{user_request}
智能体的思考过程:
{agent_thought}
智能体初步生成的代码:
{agent_code}
"""
reflection_raw = self.llm_caller(reflection_prompt_code)
try:
return json.loads(reflection_raw)
except json.JSONDecodeError:
print(f"Warning: Code Reflection LLM returned invalid JSON: {reflection_raw}")
return {"status": "error", "issues": [], "action": "error", "revised_prompt_for_agent": None}
def process_code_request(self, user_request: str) -> str:
current_code_info = self._generate_initial_code(user_request)
initial_code = current_code_info["code"]
agent_thought = current_code_info["thought_process"]
final_code = initial_code
print(f"nInitial Code:n{initial_code}")
for i in range(self.max_reflections):
print(f"n--- Code Reflection Cycle {i+1} ---")
reflection_result = self._reflect_on_code(user_request, agent_thought, final_code)
if reflection_result["status"] == "no_issues_found":
print("Code Reflection: No issues found. Proceeding with current code.")
break
elif reflection_result["status"] == "issues_detected":
print(f"Code Reflection: Issues detected. Proposed action: {reflection_result['action']}")
for issue in reflection_result["issues"]:
print(f" - Type: {issue['type']}, Desc: {issue['description']}, Suggestion: {issue['suggestion']}")
correction_prompt = reflection_result["revised_prompt_for_agent"]
print(f"Agent will attempt to revise code based on: {correction_prompt}")
# 模拟根据修正建议重新生成代码
current_code_info = self._generate_initial_code(user_request, current_context=correction_prompt)
final_code = current_code_info["code"]
agent_thought = current_code_info["thought_process"]
print(f"nRevised Code after Reflection {i+1}:n{final_code}")
else:
print(f"Code Reflection: Error or unknown status: {reflection_result['status']}. Stopping reflection.")
break
else:
print(f"nMax code reflections reached ({self.max_reflections}). Outputting the last revised code.")
return final_code
运行代码生成示例
code_agent = CodeGeneratingAgent(mock_llm_call)
print("n— Test Case 4: Inefficient Fibonacci Code —")
code_request1 = "请编写一个Python函数来计算斐波那契数列的第N项。"
code_result1 = code_agent.process_code_request(code_request1)
print(f"nFinal Code for ‘{code_request1}’:n{code_result1}")
print("n— Test Case 5: File Operation without Error Handling —")
code_request2 = "请编写一个Python函数来读取指定路径的文本文件内容。"
code_result2 = code_agent.process_code_request(code_request2)
print(f"nFinal Code for ‘{code_request2}’:n{code_result2}")
**代码生成反思的特点:**
* **更专业的检查项**:针对代码的特点,检查项会包括语法、逻辑、效率、健壮性、安全性等。
* **行号和具体建议**:反思报告中可以包含代码中的具体行号,以及更详细、可操作的修正建议。
* **潜在的外部工具集成**:在真实场景中,反思模块可以:
* 调用Python的`ast`模块进行静态代码分析。
* 执行代码(在一个沙箱环境中),捕获运行时错误,并检查输出。
* 生成单元测试并运行,以验证代码的逻辑正确性。
* 使用`mypy`等工具进行类型检查。
#### 5.4 关键反思准则(General Table)
下表总结了不同类型输出可能需要的反思准则:
| 输出类型 | 常见反思准则
| **文本回答** | 事实准确性、逻辑一致性、完整性、相关性、语气/风格、语法/拼写、避免有害/偏见内容、简洁性、遵循指令中的所有约束。