像LangChain、CrewAI和AutoGen这样的平台因其提供构建人工智能系统所需的高级抽象而受到广泛欢迎。然而,包括我在内的许多开发者发现,这些工具的缺点往往超过了优点,频繁导致开发过程中产生不必要的复杂性和沮丧感。
而Atomic Agents为我们提供了一种模块化的精简框架,旨在消除当前人工智能开发工具的种种困扰。Atomic Agents 基于坚固的编程范式,如输入-处理-输出(IPO)模型和原子性概念,提供了一种优先考虑简单性、灵活性以及开发者控制的全新方法。
(adsbygoogle=window.adsbygoogle||[]).push({});
在本文中,我们将深度探讨 Atomic Agents 的创建背景、所采用的编程范式,以及它在众多产品中脱颖而出的原因。结合代码示例与实际案例,一起深入了解 Atomic Agents。如果你认为 LangChain 过于复杂,那么不妨继续阅读~
当前人工智能框架的问题
我第一次尝试使用LangChain时,对它简化人工智能代理开发的能力感到非常兴奋,然而实际体验却远比想象复杂。
除了复杂的类和方法,LangChain 的开发者似乎没能真正理解人工智能开发人员面临的现实挑战,可能更关注的是理论上的精美设计,而非实际应用中的可用性。过度抽象不仅提高了开发的难度,也导致了透明度问题。
CrewAI 和 AutoGen 的幻觉
同样,CrewAI和AutoGen等框架也尝试通过自动化复杂任务来提供“神奇”的解决方案。虽然让大量人工智能代理自主处理事务的构想很吸引人,但在实际应用中,这些工具经常表现得不稳定,无法如承诺般正常工作。它们的夸大承诺与实际表现之间的差距,令开发者不断应对不可预测的行为及控制欠缺的困境。
这些框架模糊了底层流程,导致调试或定制功能变得困难。最终,这些工具更像是一个黑箱,而非一个实用的开发框架,这种状态对于需要可靠和可维护应用程序的开发者并不理想。
功能的过度承诺:常见问题
这些框架普遍存在一个问题,就是倾向于过度承诺功能。有些公司和工具声称能够接近AGI(人工智能通用智能),但如果你在人工智能领域工作了较长时间,就会意识到我们尚未达到这一水平。过度宣传往往导致不切实际的期望,而当这些工具不可避免地暴露出不足时,开发者只能面对随之而来的问题。
对更好方法的渴求
在与种种挫折斗争之后,我们清楚地认识到,我们亟需一个框架,它能消除不必要的复杂性和抽象层次:
- 消除不必要的复杂性和抽象层。
- 为开发者提供全面控制,避免将关键功能隐藏在不透明的接口后。
- 遵循可靠且经过检验的编程范式,提升可维护性和可扩展性。
- 由开发者构建,服务于开发者,理解人工智能开发中的真实挑战。
这种认识促成了Atomic Agents的诞生。
Atomic Agents简介

Atomic Agents Logo
Atomic Agents是一个开源框架,旨在尽量保持轻量、模块化和可组合。它遵循输入-处理-输出(IPO)模型和原子性原则,确保每个组件都是单一用途、可重用且可互换的。
Atomic Agents为何诞生?
Atomic Agents的出现正是为了填补现有框架的空缺。它的目标在于:
- 通过提供清晰且易管理的组件,简化人工智能开发。
- 消除其他框架中的多余复杂性和不必要的抽象。
- 增强灵活性与一致性,使开发者更专注于构建有效的人工智能应用,而非陷入与框架的纠缠。
- 鼓励最佳实践,促进开发者采用模块化、可维护的代码结构。
通过坚持这些原则,Atomic Agents 让开发者能够构建既强大又易管理的人工智能代理和应用。
Atomic Agents背后的编程范式
输入-处理-输出(IPO)模型
Atomic Agents 的核心在于输入-处理-输出(IPO)模型,这是一种基本的编程范式,将程序结构划分为三个明确阶段:
- 输入:接收来自用户或其他系统的数据。
- 处理:对数据进行处理或转换。
- 输出:将处理后的数据作为结果呈现。
这一模型清晰简洁,更易于理解和管理应用程序中的数据流。
在 Atomic Agents 中,这能够转化为:
- 输入模式:使用 Pydantic 定义输入数据的结构和验证规则。
- 处理组件:执行数据操作的代理和工具。
- 输出模式:确保返回结果经过结构化和验证。
原子性:功能组件
原子性概念旨在将复杂系统分解为最小功能单元或“原子”。每个原子:
- 具有单一责任,便于理解和维护。
- 可重用,允许在不同项目或应用程序的多个部分使用。
- 可与其他原子组件结合,构建更复杂的功能。
通过聚焦原子组件,Atomic Agents 促进了模块化架构,提升了灵活性和可扩展性。
Atomic Agents如何运作
组成部分
在 Atomic Agents 中,人工智能代理由几个关键部分组成:
- 系统提示:定义代理的行为和目的。
- 输入模式:规定输入数据的预期结构。
- 输出模式:定义输出数据的结构。
- 内存:存储对话历史或状态信息。
- 上下文提供程序:在运行时向系统提示注入动态上下文。
- 工具:代理可使用的外部功能或应用程序接口。
每个组件的设计都是模块化和可互换的,并遵循关注点分离和单一责任原则。
模块化与可组合性
模块化是 Atomic Agents 的核心。通过将组件设计为独立且专注于单一任务,开发者可以:
- 更换工具或代理而不影响系统的其他部分。
- 微调单个组件,如系统提示或模式,而不会带来意想不到的副作用。
- 通过调整输入与输出模式,将代理与工具无缝串联。
这种模块化方法不仅使开发变得更易管理,也提升了人工智能应用程序的可维护性和可扩展性。
提供上下文:增强灵活性
上下文提供程序使代理能在系统提示中包含动态数据,并根据最新信息影响响应。
示例:
from atomic_agents.lib.components.system_prompt_generator import SystemPromptContextProviderBase class SearchResultsProvider(SystemPromptContextProviderBase): def __init__(self, title: str, search_results: List[str]): super().__init__(title=title) self.search_results = search_results def get_info(self) -> str: return "\n".join(self.search_results) # 向代理注册上下文提供程序 agent.register_context_provider("search_results", search_results_provider)
通过将实时数据注入代理的上下文,您可以创建更动态、反应更灵敏的人工智能应用。
模式与代理的链式连接
Atomic Agents 通过调整输入和输出模式简化了代理与工具的链式连接过程。
示例:假设您有一个查询生成代理和一个网络搜索工具。通过设置查询代理的输出模式,使其与搜索工具的输入模式相匹配,您就可以直接将它们串联起来。
from web_search_agent.tools.searxng_search import SearxNGSearchTool # 初始化查询代理 query_agent = BaseAgent( BaseAgentConfig( # ... 其他配置 ... output_schema=SearxNGSearchTool.input_schema, # 对齐输出模式 ) )
这种设计提升了可重用性与灵活性,实现了组件的轻松更换或功能扩展。
Atomic Agents优于其他产品的原因
消除不必要的复杂性
与引入多层抽象的框架不同,Atomic Agents 保持简单明了。每个组件的目的都非常明确,没有隐藏的复杂机制需要破解。
- 透明架构:您完全可以理解数据在应用程序中的流动方式。
- 更易调试:由于复杂性降低,识别和修复问题变得更为简单。
- 减轻学习曲线:开发者不需要了解繁复的抽象概念,就能迅速上手。
由开发者打造,服务于开发者
Atomic Agents 的设计着眼于现实开发挑战。它采用了可靠的编程范式,并优先考虑开发者体验。
- 坚实的编程基础:遵循 IPO 模型和原子性,框架鼓励最佳实践。
- 灵活性与控制:开发者可以根据需求自由定制和扩展组件。
- 社区驱动:作为一个开源项目,它邀请开发者社区的贡献与协作。
独立与可重复使用的组件
Atomic Agents 的每个部分均可独立运行,促进了组件的重用和模块化。
- 可隔离测试:每个组件可单独测试,确保集成前的可靠性。
- 可跨项目重用:原子组件可以用于不同应用程序,从而节省开发时间。
- 更易维护:隔离功能减少变更的影响,简化更新过程。
构建一个简单的人工智能代理
接下来我们将构建一个能够响应用户询问并提出后续问题的人工智能代理。
第 1 步:定义自定义输入和输出模式
from pydantic import BaseModel, Field from typing import List from atomic_agents.agents.base_agent import BaseIOSchema class CustomInputSchema(BaseIOSchema): chat_message: str = Field(..., description="The user's input message.") class CustomOutputSchema(BaseIOSchema): chat_message: str = Field(..., description="The agent's response message.") suggested_questions: List[str] = Field(..., description="Suggested follow-up questions.")
第 2 步:设置系统提示
from atomic_agents.lib.components.system_prompt_generator import SystemPromptGenerator system_prompt_generator = SystemPromptGenerator( background=[ "You are a knowledgeable assistant that provides helpful information and suggests follow-up questions." ], steps=[ "Analyze the user's input to understand the context and intent.", "Provide a relevant and informative response.", "Generate 3 suggested follow-up questions." ], output_instructions=[ "Ensure clarity and conciseness in your response.", "Conclude with 3 relevant suggested questions." ] )
第 3 步:初始化代理
from atomic_agents.agents.base_agent import BaseAgent, BaseAgentConfig import instructor import openai # 初始化代理 agent = BaseAgent( config=BaseAgentConfig( client=instructor.from_openai(openai.OpenAI(api_key='YOUR_OPENAI_API_KEY')), model="gpt-4", system_prompt_generator=system_prompt_generator, input_schema=CustomInputSchema, output_schema=CustomOutputSchema ) )
第 4 步:使用代理
user_input = "Can you explain the benefits of using Atomic Agents?" input_data = CustomInputSchema(chat_message=user_input) response = agent.run(input_data) print(f"Agent: {response.chat_message}") print("Suggested questions:") for question in response.suggested_questions: print(f"- {question}")
预期输出:
Agent: Atomic Agents simplifies AI development by providing modular, reusable components based on solid programming paradigms like the IPO model and atomicity.
Suggested questions:
- How does Atomic Agents compare to other AI frameworks?
- Can you provide an example of building an agent with Atomic Agents?
- What are the key features of Atomic Agents that enhance productivity?
整合工具与上下文提供程序
假设我们希望让代理根据用户查询执行网络搜索。
第 1 步:下载并设置 SearxNGSearchTool
使用Atomic Assembler CLI,我们可以下载搜索工具:
atomic
从菜单中选择 SearxNGSearchTool,然后按照说明安装依赖项。
第 2 步:集成搜索工具
from web_search_agent.tools.searxng_search import SearxNGSearchTool, SearxNGSearchToolConfig # 初始化搜索工具 search_tool = SearxNGSearchTool(config=SearxNGSearchToolConfig(base_url="http://localhost:8080"))
第 3 步:更新代理以使用工具
我们可以修改代理,以便根据用户输入决定何时使用搜索工具。
from typing import Union class OrchestratorOutputSchema(BaseModel): tool: str = Field(..., description="The tool to use: 'search' or 'chat'") parameters: Union[SearxNGSearchTool.input_schema, CustomInputSchema] = Field(..., description="Parameters for the selected tool.") # 修改代理逻辑以输出 OrchestratorOutputSchema # ... # 执行选定的工具 if response.tool == "search": search_results = search_tool.run(response.parameters) # 处理检索结果 else: # 使用之前的聊天代理 pass
第 4 步:使用包含搜索结果的上下文提供程序
class SearchResultsProvider(SystemPromptContextProviderBase): def __init__(self, search_results): super().__init__(title="Search Results") self.search_results = search_results def get_info(self) -> str: return "\n".join(self.search_results) # 获取搜索结果后 context_provider = SearchResultsProvider(search_results) agent.register_context_provider("search_results", context_provider)
通过这种集成,代理能够根据实时网络搜索数据提供响应。
Atomic Assembler CLI:轻松管理工具
Atomic Agents的一个突出特点是Atomic Assembler CLI,这是一种简化工具和代理管理的命令行工具。
受一些现代库(如shadcn)启发,在这些库中,您不需要将组件作为依赖项安装,而是对其源代码拥有完整控制。
这意味着我们不会使用 pip 将工具作为依赖项安装,而是将其直接复制到项目中。实现这一目标有两种方法:
- 手动下载工具,或从 Atomic Agents GitHub 代码库中复制/粘贴源代码,并将其放入
atomic-forge
文件夹中。 - 使用 Atomic Assembler CLI 下载工具。

Atomic Agents
主要功能
- 下载和管理工具:轻松将新工具添加到项目中,无需手动复制或解决依赖问题。
- 避免依赖性杂乱:只安装必要的工具,让项目保持精简。
- 轻松修改工具:每个工具都是独立的,具有自己的测试和文档。
- 直接访问工具:如有需要,可以手动管理工具文件夹。
总结
Atomic Agents 将简约、模块化和开发者控制放在首位,为人工智能开发领域带来了急需的转变。通过采用诸如输入-处理-输出模型与原子性等可靠的编程范式,它解决了许多开发者在使用 LangChain、CrewAI 和 AutoGen 等现有框架时所面临的问题。
借助 Atomic Agents,您可以:
- 消除不必要的复杂性,专注于构建高效的人工智能应用。
- 完全掌控系统的每个组件。
- 轻松更换或修改组件,而无需中断整个应用程序。
- 利用模块化和可重用性提高工作效率和可维护性。
如果您已经厌倦了与复杂框架周旋,且发现它们常常承诺过多,交付不足,那么现在是尝试 Atomic Agents 的最佳时机。
暂无评论