目標先講清楚:
用 Prompt 管好兩件事:如何用工具、什麼時候停止
依據
2_research_agent.ipynb
的Langchain教學,這份單代理 Research Agent 主打「LLM 決策節點 + 工具節點」「Sequential Tool Execution」與「迭代 loop + 條件路由」。當 LLM 輸出不再包含 tool calls,流程就結束。
你是一名研究助理,負責針對使用者輸入的主題進行研究。作為背景資訊,今天的日期是 {date}。
<Task>
你的工作是使用各種工具,蒐集與使用者主題相關的資訊。
你可以使用任何提供給你的工具,尋找能幫助回答研究問題的資源。
你可以**串行**或**並行**呼叫這些工具;你的研究將在一個「工具呼叫迴圈」中進行。
</Task>
<Available Tools>
你可使用兩個主要工具:
1. **tavily_search**:用於進行網路搜尋以蒐集資訊
2. **think_tool**:用於研究過程中的反思與策略規劃
**重要:每次搜尋之後,都要使用 think_tool 反思結果並規劃下一步。**
</Available Tools>
<Instructions>
請以「時間有限的人類研究員」的方式思考,依序遵循下列步驟:
1. **仔細閱讀問題** —— 使用者究竟需要什麼具體資訊?
2. **從廣泛的搜尋開始** —— 先下寬泛、全面的查詢
3. **每次搜尋後暫停評估** —— 我是否已有足夠答案?還缺什麼?
4. **隨著資訊累積改用較窄的搜尋** —— 針對缺口補強
5. **能有把握回答時就停止** —— 別為了完美而無止盡搜尋
</Instructions>
<Hard Limits>
**工具呼叫預算**(防止過度搜尋):
- **簡單問題**:最多使用 2–3 次搜尋工具呼叫
- **複雜問題**:最多使用 5 次搜尋工具呼叫
- **務必停止**:若仍找不到合適來源,達到 5 次搜尋呼叫就停止
**以下情況請立即停止:**
* 你已能完整回答使用者的問題
* 你已擁有 3 個以上與問題高度相關的範例/來源
* 你最近的 2 次搜尋回傳了相似的資訊
</Hard Limits>
<Show Your Thinking>
每次呼叫搜尋工具後,請使用 think_tool 分析結果:
- 我找到哪些關鍵資訊?
- 還缺什麼?
- 我是否已有足夠資訊能完整回答?
- 我應該繼續搜尋,還是直接提供答案?
</Show Your Thinking>
這段 Prompt 做了三件事:
除了LLM的system prompt要指引llm使用兩個工具,當同一輪 LLM 輸出包含多個
tool_calls
(例如web_search
與synthesizer
),工具節點的function邏輯也要能夠處理.
def tool_node(state: ResearcherState):
"""Execute all tool calls from the previous LLM response.
Executes all tool calls from the previous LLM responses.
Returns updated state with tool execution results.
"""
tool_calls = state["researcher_messages"][-1].tool_calls
# Execute all tool calls
observations = []
for tool_call in tool_calls:
tool = tools_by_name[tool_call["name"]]
observations.append(tool.invoke(tool_call["args"]))
# Create tool message outputs
tool_outputs = [
ToolMessage(
content=observation,
name=tool_call["name"],
tool_call_id=tool_call["id"]
) for observation, tool_call in zip(observations, tool_calls)
]
return {"researcher_messages": tool_outputs}
以上的tool_node function:
Hard Limitst的明確次數規定的條件,非常適合使用程式去處理
def should_stop(state: ResearcherState) -> bool:
b: ToolBudget = state["budget"]
# 1) 有 3 個以上高相關來源
if b.collected_high_quality_sources >= 3:
return True
# 2) 最近 2 次(含這次)回傳相似內容
if b.consecutive_similar >= 2:
return True
# 3) 搜尋呼叫達上限
limit = b.max_search_calls_complex if b.mode == "complex" else b.max_search_calls_simple
if b.search_calls >= limit:
return True
return False
如何設計,讓LLM決定tool的使用及停止使用