歡迎來到啾啾的博客🐱。
記錄學習點滴。分享工作思考和實用技巧,偶爾也分享一些雜談💬。
有很多很多不足的地方,歡迎評論交流,感謝您的閱讀和評論😄。
目錄
- 1 引言
- 2 使用工具分析Agent:”日志“
- 3 Agent分析調優
- 3.1 使用LLM自評LLM-as-a-Judge
- 4 TODO
1 引言
讓我們結合前兩篇的理論與實踐,嘗試系統性、結構化、全面地分析Agent。
因繼續寫下去單個文件太長了,本篇代碼較上篇做了結構改動,代碼放在https://github.com/tataCrayon/LLM-DEV-COOKBOOK倉庫。
2 使用工具分析Agent:”日志“
我們之前通過verbose=True的日志,對Agent的行為進行了定性分析(Qualitative Analysis)。
但verbose=True的日志結構還是不夠清晰。
LangChain提供了組件(回調機制),讓我們可以捕獲Agent的完整思考鏈。
from langchain.callbacks.base import BaseCallbackHandler
from langchain.schema import AgentAction, LLMResult
from typing import Any, Dict, Listclass IterationCounterCallback(BaseCallbackHandler):"""一個在每次Agent行動前打印輪次的回調處理器"""def __init__(self):self.iteration_count = 0def on_agent_action(self, action: AgentAction, **kwargs: Any) -> Any:self.iteration_count += 1print(f"\n--- 🤔 思考輪次: {self.iteration_count} ---")class AgentTraceCallback(BaseCallbackHandler):"""一個捕獲并存儲Agent與LLM之間完整交互記錄的回調處理器"""def __init__(self):self.trace = ""def on_llm_start(self, serialized: Dict[str, Any], prompts: List[str], **kwargs: Any) -> Any:self.trace += f"\n--- PROMPT TO LLM ---\n{prompts[0]}\n"def on_llm_end(self, response: LLMResult, **kwargs: Any) -> Any:self.trace += f"--- RESPONSE FROM LLM ---\n{response.generations[0][0].text}\n"
這些記錄以配置的方式,在agent_executor.invoke調用中傳入
response = agent_executor.invoke({"input": question},# 回調列表可以包含多個回調處理器config={"callbacks": [iteration_counter, trace_collector]}
)
- IterationCounterCallback
IterationCounterCallback 并不是 LangChain 的標準內置回調類,而更可能是一個自定義的回調處理器,用于在 LangChain 的執行過程中跟蹤迭代次數或特定事件。這種回調通常用于記錄某些操作的執行次數,例如在鏈(Chain)或代理(Agent)執行過程中統計某些特定步驟的調用次數。- 功能
迭代計數:IterationCounterCallback 通常用于記錄某些特定操作(如 LLM 調用、工具調用、代理循環等)的次數。
監控和調試:通過計數,可以幫助開發者了解模型或代理在執行任務時的行為,例如循環次數、調用頻率等。
自定義邏輯:可以根據計數結果觸發特定行為,例如在達到一定次數后停止執行或記錄日志。
還有AgentTraceCallback。
- 功能
這里不做多過記錄了,具體詳情見LangChain API。
3 Agent分析調優
我們需要從“效率”、“準確性”、“魯棒性”三個角度去調整優化我們的Agent。
-
效率
Q:Agent的ReAct循環是否偏離預期?
Q:步驟是否多余(需要合并)? -
準確性
Q:Agent選擇搜索的關鍵詞是否有效?
Q:使用工具獲取的內容是否真的回答了問題?
Q:最終的答案是否準確、全面? -
魯棒性
Q:如果其中一個工具調用失敗了(比如網頁無法訪問),Agent要怎么處理?
Q:故障怎么恢復?
3.1 使用LLM自評LLM-as-a-Judge
人工評估在復雜場景往往效率低下,更適合的做法是訓練一個LLM評委。
實現"LLM即評委"。
我們將創建一個新的函數,它的職責就是扮演“評委”的角色。它會接收我們捕獲到的agent_trace,然后調用一個強大的LLM(我們繼續使用DeepSeek),根據我們設定的標準來對這次運行進行打分和評價。
- Prompt :“評委LLM”的評分標準
EVALUATION_PROMPT_TEMPLATE = """**角色:** 你是一位經驗豐富的AI Agent評審專家。**任務:** 請根據以下提供的“原始問題”、“Agent最終答案”和“Agent完整思考軌跡”,對該Agent的表現進行一次全面、客觀的評估。**評估標準:**1. **效率 (Efficiency):** Agent是否采取了最直接、最少的步驟來解決問題?是否存在冗余的工具調用或不必要的思考循環?2. **準確性 (Accuracy):** Agent的最終答案是否準確、全面地回答了原始問題?3. **忠實度 (Faithfulness):** 最終答案是否嚴格基于其“觀察結果”(工具的輸出)?是否存在編造或幻覺的成分?4. **工具使用 (Tool Use):** Agent是否選擇了正確的工具?傳遞給工具的參數是否合理?---**【待評估材料】****原始問題:**{question}**Agent最終答案:**{final_answer}**Agent完整思考軌跡:**---{agent_trace}---**【你的評估報告】**請在下方提供你的評估報告。請先給出一個總體得分(滿分10分),然后分點闡述你的理由,并提出具體的改進建議。**總體得分:** [請在這里打分,例如:8/10]**詳細評估與改進建議:**1. **效率:** ...2. **準確性:** ...3. **忠實度:** ...4. **工具使用:** ..."""
- “評委”代碼
from langchain_deepseek import ChatDeepSeek
from langchain.prompts import PromptTemplate
from langchain.schema.output_parser import StrOutputParser
from ..llms.llm_clients import create_deepseek_llm # 從我們的llm模塊導入from ..configs.prompt_config import EVALUATION_PROMPT_TEMPLATEdef evaluate_agent_trace(question: str, agent_trace: str, final_answer: str):"""使用LLM作為評委,來評估Agent的執行軌跡和最終答案。"""print("\n--- 啟動LLM評委進行評估 ---")# 1. 創建評估鏈 (Evaluation Chain)prompt = PromptTemplate.from_template(EVALUATION_PROMPT_TEMPLATE)llm = create_deepseek_llm() # 復用我們創建LLM的函數# 使用LCEL(LangChain Expression Language)來構建鏈# 這是一個簡單的 "Prompt -> LLM -> String Output" 鏈evaluation_chain = prompt | llm | StrOutputParser()# 2. 運行評估鏈try:print("評委正在審閱材料并生成報告...")evaluation_report = evaluation_chain.invoke({"question": question,"agent_trace": agent_trace,"final_answer": final_answer})print("\n--- 評委報告生成完畢 ---")print(evaluation_report)except Exception as e:print(f"\n--- LLM評委在評估時發生錯誤 ---")print(e)
AI給出來的評估內容如下:
--- 評委報告生成完畢 ---
**總體得分:** 8.5/10 **詳細評估與改進建議:**1. **效率:**- **評分:8/10**- **理由:** Agent通過三次`search_tool`調用逐步獲取信息,邏輯清晰,但首次搜索查詢("Java vs Python for building LLM applications...")的輸入參數 過于寬泛,導致返回結果包含冗余信息(如Vert.x與Asyncio的無關對比)。后續兩次搜索(Python/Java框架)更精準,效率較高。- **改進建議:** 首次搜索可拆分為兩個針對性查詢(如分別搜索優劣勢和框架),或直接使用更精確的關鍵詞(如"LLM framework comparison Java Python 2024")。2. **準確性:**- **評分:9/10**- **理由:** 最終答案全面覆蓋了兩種語言的優劣勢,且列出的框架(如LangChain、Spring AI)與搜索結果一致。但未明確提及Python的GIL(全局解釋器鎖)對 多線程的限制,這是Python性能劣勢的關鍵細節。- **改進建議:** 補充Python的GIL問題,并對比Java的JVM優化對LLM推理的潛在優勢。3. **忠實度:**- **評分:9/10**- **理由:** 答案嚴格基于工具返回的觀察結果,未發現編造內容。但未完全引用搜索中提到的"Konduit支持模型加載與調優"的具體功能描述,略顯簡略。 - **改進建議:** 引用工具返回的原文關鍵描述(如"Konduit允許加載GPT/BERT模型")以增強可信度。4. **工具使用:**- **評分:8/10**- **理由:** 工具選擇合理(僅需搜索無需爬取),但首次搜索參數可優化。未嘗試組合查詢(如"Java LLM frameworks performance benchmarks")以獲取更深度的對比數據。- **改進建議:** 在對比優劣勢時,可增加一次搜索查詢(如"Python Java LLM latency memory usage")補充量化指標。**其他建議:**
- 可增加對跨語言生態的說明(如Java通過Jython調用Python庫的可行性),以體現更全面的視角。
- 最終答案中可補充框架的典型應用場景(如"Haystack適合RAG"已提及,但Spring AI的企業集成場景可細化)。
4 TODO
當前階段就了解到這里,附一張單Agent LLM應用流程圖。
覺得是符合MVP最小可行性原則的。
實際應用一般是多智能體協作 (Multi-Agent Collaboration),從ReAct模板引導來說,創建多個職責單一、能力專精的Agent,然后讓它們組成一個團隊來協同工作顯然更好。
像微服務架構,又是要設計通信協作、故障處理、統一管理等一攬子咯。
微服務,我都計劃從Java到LLM應用開發了,老熟人了。