使用 Anthropic 的最佳实践和 smolagents 构建高效智能体 ❤️
社区文章 发布于 2025 年 1 月 4 日
在快速发展的 AI 世界中,构建高效智能体已成为解决复杂问题的基石。然而,挑战在于平衡简单性、效率和可扩展性。最近,我读了Anthropic 关于“构建高效智能体”的文章,这与我在 Hawky.ai 的经验产生了深刻共鸣,我们在那里构建了多个营销和创意智能体。结合这些见解和 smolagents 的简洁性,我实现了一些工作流,想与您分享。
为什么智能体很重要
智能体是大型语言模型(LLM)动态引导自身流程和工具使用的系统。与预定义的工作流不同,智能体提供灵活性和适应性,使其成为需要模型驱动决策的任务的理想选择。然而,构建智能体通常感觉像组装宜家家具一样——令人不知所措且不必要地复杂。这就是 smolagents 的闪光点。
smolagents 的优势
smolagents 是一个轻量级库,旨在让开发人员亲身体验构建智能体,而不会陷入层层抽象之中。以下是其颠覆性的原因:
- 极简设计:整个库只有约 1,000 行代码。
- 基于代码的智能体:智能体将操作编写为 Python 代码,减少了 30% 的步骤并提高了性能。
- 安全执行:在沙盒环境中运行代码或使用安全的 Python 解释器。
- 灵活性:适用于任何 LLM——Hugging Face、OpenAI、Anthropic 等。
使用 smolagents 实现 Anthropic 的最佳实践
Anthropic 的文章强调简单性、透明度和完善的工具。以下是我如何使用 smolagents 实现这些原则:
1. 提示链工作流
提示链将任务分解为连续的子任务,并在步骤之间设置验证门。以下是我如何实现它的:
class ChainedPromptAgent(MultiStepAgent):
"""
Agent that implements prompt chaining workflow by breaking tasks into sequential subtasks
with validation gates between steps.
"""
def __init__(
self,
tools: List[Tool],
model: Callable,
subtask_definitions: List[Dict[str, Any]],
system_prompt: Optional[str] = None,
validation_functions: Optional[Dict[str, Callable]] = None,
**kwargs
):
super().__init__(tools=tools, model=model, system_prompt=system_prompt, **kwargs)
self.subtask_definitions = subtask_definitions
self.validation_functions = validation_functions or {}
self.current_subtask_index = 0
self.subtask_outputs = {}
def validate_subtask_output(self, subtask_name: str, output: Any) -> Tuple[bool, str]:
"""
Validate the output of a subtask using its validation function.
"""
if subtask_name not in self.validation_functions:
return True, ""
validation_fn = self.validation_functions[subtask_name]
try:
is_valid = validation_fn(output)
return is_valid, "" if is_valid else f"Validation failed for {subtask_name}"
except Exception as e:
return False, f"Validation error for {subtask_name}: {str(e)}"
def format_subtask_prompt(self, subtask_def: Dict[str, Any]) -> str:
"""
Format the prompt template for a subtask using previous outputs.
"""
prompt_template = subtask_def["prompt_template"]
return prompt_template.format(
**self.subtask_outputs,
task=self.task
)
def step(self, log_entry: ActionStep) -> Union[None, Any]:
"""
Execute one step in the prompt chain.
"""
if self.current_subtask_index >= len(self.subtask_definitions):
return self.subtask_outputs[self.subtask_definitions[-1]["name"]]
current_subtask = self.subtask_definitions[self.current_subtask_index]
subtask_name = current_subtask["name"]
formatted_prompt = self.format_subtask_prompt(current_subtask)
agent_memory = self.write_inner_memory_from_logs()
agent_memory.append({
"role": MessageRole.USER,
"content": formatted_prompt
})
try:
subtask_output = self.model(agent_memory)
log_entry.llm_output = subtask_output
except Exception as e:
raise AgentGenerationError(f"Error in subtask {subtask_name}: {str(e)}")
if current_subtask.get("requires_validation", False):
is_valid, error_msg = self.validate_subtask_output(subtask_name, subtask_output)
if not is_valid:
raise AgentExecutionError(error_msg)
self.subtask_outputs[subtask_name] = subtask_output
self.current_subtask_index += 1
log_entry.observations = f"Completed subtask: {subtask_name}"
return None
主要特点
- 任务分类:使用 LLM 或基于规则的分类来路由任务。
- 专业处理程序:将任务定向到最合适的处理程序。
- 回退机制:确保即使分类失败也能处理任务。
为什么 smolagents + Anthropic 的方法行之有效
将 smolagents 与 Anthropic 的最佳实践相结合,提供了一种强大而简单的构建智能体的方式。原因如下:
- 简单性:smolagents 保持代码库最小化且易于理解。
- 透明度:Anthropic 强调完善的工具,确保了清晰度。
- 可扩展性:模块化设计便于扩展和定制。
最终思考
构建智能体不必复杂。通过利用 smolagents 并遵循 Anthropic 的最佳实践,您可以创建强大、高效且易于维护的智能体。无论您是初创公司还是企业,这种方法都可以帮助您专注于解决实际问题,而不是与框架的复杂性作斗争。
立即试用 smolagents,并告诉我它的使用体验!您可以在此处找到 GitHub 存储库:smolagents-approach。动态提示:使用先前的输出为后续步骤格式化提示。