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应用开发了,老熟人了。

相关推荐
mldong1 小时前
mldong 快速开发框架登录模块设计与实现
java·后端·架构
我爱Jack1 小时前
@annotation:Spring AOP 的“精准定位器“
java·后端·spring
我崽不熬夜2 小时前
为什么你该立即学习 Java 的 Lambda 表达式?
java·后端·java ee
爱捣鼓的XiaoPu3 小时前
基于Spring Boot的计算机考研交流系统的设计与实现
spring boot·后端·考研·毕业设计
是紫焅呢4 小时前
I排序算法.go
开发语言·后端·算法·golang·排序算法·学习方法·visual studio code
lovebugs4 小时前
Java线上死锁问题实战:从定位到解决的全链路指南
java·后端·面试
飞飞帅傅4 小时前
go语言位运算
开发语言·后端·golang
kong@react5 小时前
使用springboot实现过滤敏感词功能
java·spring boot·后端·spring