趋近智
随着您为LLM代理构建工具库,确保每个工具可靠并按预期工作变得必不可少。有缺陷的工具可能导致代理行为不可预测、输出错误以及用户体验不佳。建立测试实践,特别是单元测试和集成测试,专为LLM代理工具的独特环境而设计。通过彻底测试您的工具,您为构建可靠高效的代理系统打下根基。
测试为LLM代理设计的工具,与传统软件组件相比,带来了一套略有不同的挑战。虽然单元测试和集成测试的基本原则保持不变,但与LLM的互动增加了需要考虑的层面:
代理工具的单元测试和集成测试的主要目标是验证每个工具在隔离状态下能正确运行,并能与代理的操作环境集成。
单元测试侧重于工具中最小的可测试部分,通常是类中的单个函数或方法。目标是验证工具逻辑的每个部分都能正确工作,且独立于系统的其他部分或外部依赖。
单元测试主要涵盖的方面:
主要功能:
计算抵押贷款支付工具应为给定贷款参数返回正确的支付金额。输入验证与处理:
输出格式与结构:
错误处理与报告:
状态管理(对于有状态工具):
模拟外部依赖:
unittest.mock库(与MagicMock、patch一起)通常用于此目的。示例:单元测试一个简单的Python工具
考虑一个Python工具,它获取股票价格:
# stock_tool.py
import requests
class StockPriceTool:
def __init__(self, api_key: str):
self.api_key = api_key
self.base_url = "https://api.examplefinance.com/v1/stock"
def get_price(self, ticker_symbol: str) -> dict:
if not isinstance(ticker_symbol, str) or not ticker_symbol.isalpha():
return {"error": "无效的股票代码格式。"}
try:
response = requests.get(
f"{self.base_url}/{ticker_symbol}/price",
params={"apikey": self.api_key}
)
response.raise_for_status() # 对于不良响应(4XX或5XX)抛出HTTPError
data = response.json()
if "price" not in data:
return {"error": f"未找到 {ticker_symbol} 的价格数据。"}
return {"ticker": ticker_symbol, "price": data["price"]}
except requests.exceptions.RequestException as e:
return {"error": f"API请求失败:{str(e)}"}
except ValueError: # JSONDecodeError 继承自 ValueError
return {"error": "无法解析API响应。"}
使用pytest和unittest.mock的单元测试可能如下所示:
# test_stock_tool.py
import pytest
from unittest.mock import patch, MagicMock
from stock_tool import StockPriceTool
@pytest.fixture
def tool():
return StockPriceTool(api_key="test_api_key")
def test_get_price_success(tool, monkeypatch):
mock_response = MagicMock()
mock_response.json.return_value = {"price": 150.75}
mock_response.raise_for_status.return_value = None # 模拟没有HTTP错误
# 使用 pytest 的 monkeypatch 来模拟 requests.get,类似于 unittest.mock.patch
monkeypatch.setattr("requests.get", MagicMock(return_value=mock_response))
result = tool.get_price("AAPL")
assert result == {"ticker": "AAPL", "price": 150.75}
requests.get.assert_called_once_with(
"https://api.examplefinance.com/v1/stock/AAPL/price",
params={"apikey": "test_api_key"}
)
def test_get_price_invalid_ticker_format(tool):
result = tool.get_price("AAPL123")
assert result == {"error": "无效的股票代码格式。"}
def test_get_price_api_failure(tool, monkeypatch):
mock_response = MagicMock()
mock_response.raise_for_status.side_effect = requests.exceptions.HTTPError("API 不可用")
monkeypatch.setattr("requests.get", MagicMock(return_value=mock_response))
result = tool.get_price("MSFT")
assert "API请求失败" in result["error"]
def test_get_price_data_not_found(tool, monkeypatch):
mock_response = MagicMock()
mock_response.json.return_value = {"message": "未找到股票代码"} # API未返回价格字段
mock_response.raise_for_status.return_value = None
monkeypatch.setattr("requests.get", MagicMock(return_value=mock_response))
result = tool.get_price("GOOG")
assert result == {"error": "未找到 GOOG 的价格数据。"}
单元测试的最佳实践:
test_tool_handles_invalid_input_gracefully)。单元测试验证单个代理工具的方法或函数在隔离状态下是否正常运行,通常使用模拟来处理API调用等外部依赖。
单元测试确认单个组件正确工作,而集成测试则验证您的工具是否与更大的代理框架或编排器正确交互。它们侧重于将您的工具连接到最终将根据LLM决策调用它的系统的“连接机制”。
集成测试应涵盖的方面:
工具注册与发现:
框架对工具的调用:
参数映射与转换:
框架对响应的处理:
与真实外部服务的交互(预生产/测试环境):
模拟LLM交互:
集成测试的方法:
示例:集成代码片段
假设您有一个代理框架,其中包含一个方法run_agent_query(query: str)。集成测试可能如下所示:
# test_agent_integration.py
from my_agent_framework import AgentFramework
from stock_tool import StockPriceTool # 假设它已注册
def test_stock_tool_integration_with_agent(monkeypatch):
# 模拟 StockPriceTool 的外部API调用,即使在集成测试中,
# 如果您只想关注框架与工具的交互并避免外部不稳定因素。
# 或者,让它命中测试/预生产API端点。
mock_api_response = MagicMock()
mock_api_response.json.return_value = {"price": 200.00}
mock_api_response.raise_for_status.return_value = None
monkeypatch.setattr("requests.get", MagicMock(return_value=mock_api_response))
agent = AgentFramework()
# 假设 StockPriceTool 以 "getStockPrice" 的名称注册到代理
# 并且代理框架可以解析查询以调用此工具。
# 这部分高度依赖于您具体的代理框架。
# 此查询旨在确定性地触发股票工具
# (通过特定关键词或测试设置中的简化NLU)
agent_response = agent.run_agent_query("TSLA 股票的价格是多少?")
# 断言将检查工具是否被调用及其结果是否被处理
# 如果直接输出不足以判断,这通常涉及检查日志或代理/框架的内部状态。
# 为简单起见,假设 agent_response 包含结构化结果:
assert "TSLA" in agent_response["tool_result"]["ticker"]
assert agent_response["tool_result"]["price"] == 200.00
# 潜在地断言 requests.get 被调用时使用了 "TSLA"
requests.get.assert_called_with(
"https://api.examplefinance.com/v1/stock/TSLA/price", # 或者您实际的股票代码
params={"apikey": "test_api_key"} # 或者API密钥是如何管理的
)
这个示例是简化的。与代理框架进行的实际集成测试通常需要更多设置来配置代理、其工具,并可能模拟LLM的决策过程,以可靠地触发特定工具。
集成测试检查工具如何与代理框架或模拟代理环境交互。这可能涉及真实的外部服务测试实例或进一步模拟,具体取决于测试的侧重点。
需重申,此处讨论的单元测试和集成测试主要关注工具本身的正确性和可靠性及其与代理连接机制的集成。它们确保,如果LLM(或代理框架)决定用特定参数调用工具,该工具的行为可预测并返回格式良好的响应。
这些测试通常不评估:
评估这些LLM特有方面属于LLM评估和代理性能评估的更广泛范畴,这些是独立但相关的学科。经过充分测试的工具是进行有意义的LLM代理评估的先决条件。如果工具本身不可靠,就无法确定故障是由于工具还是LLM的推理。
通过实施全面的单元测试和集成测试,您奠定了可靠工具的根基。这不仅提高了LLM代理的可靠性,还简化了调试和维护,因为您可以更有信心单个工具组件按预期运行。这种严格的测试方法是先进LLM代理系统开发中良好工程实践的标志。
这部分内容有帮助吗?
© 2026 ApX Machine Learning用心打造