Agent来了0x05:Self-Ask 回路验证

前言

之前学了 ReActPlan and Execute 两种 Agent 中的设计范式,那么除了这两种还有别的范式吗?

我们知道 LLM 最开始以 Chat 的形式风靡全世界,那么既然他可以和人类对话。可不可以让他就某个问题的答案进行自问自答来增强答案准确性呢?哈哈没错,答案是肯定的。他就是我们今天要看的 Self-Ask 回路验证

定义

自问自答(Self-Ask) 范式允许大模型对自己提出问题并回答,来增强对问题的理解以提高回答质量。

  • 本质:"思考-验证-再行动"

  • 核心流程-

    1. 自我提问(Self-Ask) :当Agent接到一个复杂问题(例如:"珠穆朗玛峰的高度和《三体》的作者有关联吗?"),它不会直接回答,而是先自主拆解。它会生成一个或多个子问题,例如:"1. 珠穆朗玛峰的精确高度是多少? 2. 《三体》的作者是谁?"
  • 执行与验证(Act & Verify) :Agent会通过调用工具 (如联网搜索)来寻找每个子问题的答案,同时评估答案的可信度 (来源是否权威?信息是否一致?是否与已知事实冲突?)。这一步是防御"幻觉"的核心。

  • 综合与迭代(Synthesize & Iterate) :基于已验证子答案,Agent尝试综合出最终答案。如果发现信息不足、矛盾或推导不出结论,它会生成新的、更精确的子问题,回到步骤1,形成回路。直到所有信息被验证且逻辑闭环,才输出最终答案。

哟,赶脚有点像之前 AdvancedRAG 提到的问题拆解,思路一致应用不同。

Coding

Prompt

我们还是尝试在 Langsmith-Hub 搜索 "Self-Ask",模板还有好几个呢,我们一般选择浏览和下载量最多的,如:hwchase17/self-ask-with-search。

vbnet 复制代码
template_template = '''
Answer the following question. When needed, you can ask follow-up questions and answer them to reach the final answer. Always use English format for follow-up questions and answers:

Examples:
Question: Who lived longer, Muhammad Ali or Alan Turing?
Are follow up questions needed here: Yes.
Follow up: How old was Muhammad Ali when he died?
Intermediate answer: Muhammad Ali was 74 years old when he died.
Follow up: How old was Alan Turing when he died?
Intermediate answer: Alan Turing was 41 years old when he died.
So the final answer is: Muhammad Ali

Question: When was the founder of craigslist born?
Are follow up questions needed here: Yes.
Follow up: Who founded craigslist?
Intermediate answer: Craigslist was founded by Craig Newmark.
Follow up: When was Craig Newmark born?
Intermediate answer: Craig Newmark was born on December 6, 1952.
So the final answer is: December 6, 1952

Question: Who was George Washington's paternal grandfather?
Are follow up questions needed here: Yes.
Follow up: Who was George Washington's father?
Intermediate answer: George Washington's father was Augustine Washington.
Follow up: Who was Augustine Washington's father?
Intermediate answer: Augustine Washington's father was Lawrence Washington.
So the final answer is: Lawrence Washington

IMPORTANT:
1. ONLY use the exact format shown above
2. DO NOT include any explanations or extra text
3. DO NOT use markdown formatting like **bold**
4. ONLY output in the specified format
5. End your response with "So the final answer is: [answer]"

Question: {input}
Are follow up questions needed here: {agent_scratchpad}
'''

PromptTemplate注意事项

缘起

上述的模版是英文,执行也没问题。但是对于英语不好的筒子可能想使用中文模板,那么可以吗?我们不妨一试,修改提示词模版为中文。

ini 复制代码
template_template = '''
在回答用户问题时,可以自己提出问题并回答,来增强对问题的理解以提高回答质量。
示例:
问题:谁活得更久,穆罕默德·阿里还是阿兰·图灵?
这里是否需要后续问题:是的。
追问:穆罕默德·阿里去世时几岁?
中间答案:穆罕默德·阿里去世时74岁。
追问:阿兰·图灵去世时几岁?
中间答案:阿兰·图灵去世时41岁。
最终答案:穆罕默德·阿里

用户问题: {input}
解决问题:{agent_scratchpad}
'''

开始看着好像也能正常问答。我去,怎么感觉进入死循环了,尽管得出了答案一直在死循环,直到最后程序被自动强制停止。还有点像我们传统开发里的递归死循环问题

直捣黄龙一探究竟

那么这是为什么呢?好在 Langchain 都是开源代码,我们不妨直接查看源代码看看。经过一番追踪,最终我定位在了 self_ask.py 文件:

  • 模块:langchain_classic.agents.output_parsers.self_ask.py
  • SelfAskOutputParser:self-ask范式定义的输出解析器

我勒个去,这是发现了什么?

  1. 这个解析强依赖 Prompt 硬编码中的 "Follow up:" 等字符,注意有冒号!
  2. 针对部分字符,如 "So the final answer is: ",末尾还有一个空格!!

注意事项

所以,我们编写中文提示词模板的时候就有的放矢了。英文模板中的关键引导词 必须保留不变:Question、Follow up、Intermediate answer、So the final answer is 等。

  • "Follow up:":作为 SelfAskOutputParser 中 followups 来源
  • "So the final answer is: ": SelfAskOutputParser 中 finish_string 来源;⚠️⚠️⚠️:这里末尾还有个**【空格】**一定不能丢
  • "Intermediate Answer": SelfAskOutputParser 中 作为 action 的调用源

那么问题来了:我们看源代码中并未依赖 Question ,为什么建议 Question 也保留呢?

  • 跟其他字段对齐
  • 养成良好代码习惯,后续遇到其他情况一开始我们可能并不知道哪些字段硬编码依赖,这样可以防止再出现类似问题
ini 复制代码
# ✅✅✅【正确示例】✅✅✅
template_template = '''
在回答用户问题时,可以自己提出问题并回答,来增强对问题的理解以提高回答质量。
示例:
Question: 谁活得更久,穆罕默德·阿里还是阿兰·图灵?
这里是否需要后续问题:是的。
Follow up: 穆罕默德·阿里去世时几岁?
Intermediate answer: 穆罕默德·阿里去世时74岁。 
Follow up: 阿兰·图灵去世时几岁?
Intermediate answer: 阿兰·图灵去世时41岁。
So the final answer is: 穆罕默德·阿里。

用户问题: {input}
解决问题:{agent_scratchpad}
'''

思考🤔

我们发现 create_self_ask_with_search_agent 又是 Langchain 0.x 时代遗留的接口。再一次印证 Langcchain 1.0 时代鼓励使用新范式是正确的。

  • Langchain 0.x 早期为了快速实现和保证基础功能的确定性,牺牲了国际化和灵活性
  • Langchain 1.0 框架升级后吸取之前的经验,将一些前沿激进的技术、API还未稳定成熟的接口放在了 langchain_experimental
    • 分层治理和迭代 的设计思想得到进一步体现。

核心代码

ini 复制代码
tools = [TavilyAnswer(
    max_results=1,
    include_raw_content=True,
    name="Intermediate Answer",
    tavily_api_key=os.getenv("TAVILY_API_KEY"))]

agent = create_self_ask_with_search_agent(llm, tools, prompt)
agent_executor = AgentExecutor(
    agent=agent,
    tools=tools,
    verbose=True,
    handle_parsing_errors=True)

Runing

arduino 复制代码
print(agent_executor.invoke({"input": "《大白鲨》和《皇家赌场》的导演都来自同一个国家吗?"}))

源码

github

相关推荐
鲲志2 小时前
别等 Sora 了!一代神话陨落?OpenAI 这一手“弃车保帅”我看懂了...
aigc·agent·sora
倾心琴心2 小时前
【agent辅助pcb routing coding学习】实践9 CU GR 代码 算法学习
算法·agent·pcb·eda·routing
百慕大三角2 小时前
pi-mono sdk中文文档
人工智能·ai编程
gujunge2 小时前
Spring with AI (5): 搜索扩展——向量数据库与RAG(下)
ai·大模型·llm·openai·qwen·rag·spring ai·deepseek
MicrosoftReactor2 小时前
技术速递|底层机制:GitHub Agentic Workflows 的安全架构
安全·ai·github·agent·安全架构
程序员老刘3 小时前
2026春招Flutter岗位为何变少?我看到的3个招聘逻辑变化
flutter·ai编程·客户端
刀法如飞3 小时前
AI时代,重温10大经典排序算法的思维
算法·排序算法·ai编程
刀法如飞3 小时前
AI时代,重温10大经典排序算法
算法·排序算法·ai编程
Java后端的Ai之路3 小时前
【AI应用开发】-怎么解决Lost in the Middle(中间迷失)现象?
人工智能·agent·rag·中间迷失·lost