Agent轻松通-P3:分析我们的Agent

欢迎来到啾啾的博客🐱。

记录学习点滴。分享工作思考和实用技巧,偶尔也分享一些杂谈💬。

有很多很多不足的地方,欢迎评论交流,感谢您的阅读和评论😄。

目录

  • [1 引言](#1 引言)
  • [2 使用工具分析Agent:"日志"](#2 使用工具分析Agent:”日志“)
  • [3 Agent分析调优](#3 Agent分析调优)
    • [3.1 使用LLM自评LLM-as-a-Judge](#3.1 使用LLM自评LLM-as-a-Judge)
  • [4 TODO](#4 TODO)

1 引言

让我们结合前两篇的理论与实践,尝试系统性、结构化、全面地分析Agent。

因继续写下去单个文件太长了,本篇代码较上篇做了结构改动,代码放在https://github.com/tataCrayon/LLM-DEV-COOKBOOK仓库。

2 使用工具分析Agent:"日志"

我们之前通过verbose=True的日志,对Agent的行为进行了定性分析 (Qualitative Analysis)。

但verbose=True的日志结构还是不够清晰。

LangChain提供了组件(回调机制),让我们可以捕获Agent的完整思考链

python 复制代码
from langchain.callbacks.base import BaseCallbackHandler
from langchain.schema import AgentAction, LLMResult
from typing import Any, Dict, List

class IterationCounterCallback(BaseCallbackHandler):
    """一个在每次Agent行动前打印轮次的回调处理器"""
    def __init__(self):
        self.iteration_count = 0

    def on_agent_action(self, action: AgentAction, **kwargs: Any) -> Any:
        self.iteration_count += 1
        print(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调用中传入

python 复制代码
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"的评分标准
python 复制代码
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.  **工具使用:** ...

"""
  • "评委"代码
python 复制代码
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_TEMPLATE

def 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给出来的评估内容如下:

python 复制代码
--- 评委报告生成完毕 ---
**总体得分:** 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应用开发了,老熟人了。

相关推荐
用户298698530143 分钟前
.NET 文档自动化:Spire.Doc 设置奇偶页页眉/页脚的最佳实践
后端·c#·.net
智泊AI32 分钟前
一口气讲清:AI Agent 八大核心概念,建议收藏!
llm
序安InToo34 分钟前
第6课|注释与代码风格
后端·操作系统·嵌入式
xyy12335 分钟前
C#: Newtonsoft.Json 到 System.Text.Json 迁移避坑指南
后端
洋洋技术笔记37 分钟前
Spring Boot Web MVC配置详解
spring boot·后端
JxWang0538 分钟前
VS Code 配置 Markdown 环境
后端
navms41 分钟前
搞懂线程池,先把 Worker 机制啃明白
后端
JxWang0541 分钟前
离线数仓的优化及重构
后端
Sailing41 分钟前
LLM 调用从 60s 卡死降到 3s!彻底绕过 tiktoken 网络阻塞(LangChain.js 必看)
前端·langchain·llm
Nyarlathotep011342 分钟前
gin01:初探gin的启动
后端·go