第 9 章 · 03 外部 CryptoAgent 封装 本节摘要:本节精读 (约 51 行)——三段实验代码里最短的一段。它演示如何用适配器模式(Adapter Pattern)把一个外部库( )接入 AutoHedge 的 swarms Agent 体系:先建一个 swarms (用 cryptoagent 提供的 system prompt),再把它作为参数喂给 ,从而让外部库复用 swarms 的 Agent 能力。但这段代码有个致命问题:它依赖的 库既不在 ,也不在 ——直接 import 会 。这是一段「写好了但跑不起来」的代码,教学价值在两点:一是适配器模式怎么写(包一层让外部库融入自家框架);二是未声明依赖是开源项目常见的坑(代码引用了却不告诉安装者要装什么)。
本节摘要:本节精读
experimental/crypto_agent_wrapper.py(约 51 行)——三段实验代码里最短的一段。它演示如何用适配器模式(Adapter Pattern)把一个外部库(cryptoagent)接入 AutoHedge 的 swarms Agent 体系:先建一个 swarmsAgent(用 cryptoagent 提供的 system prompt),再把它作为参数喂给CryptoAgent(agent=..., autosave=True),从而让外部库复用 swarms 的 Agent 能力。但这段代码有个致命问题:它依赖的cryptoagent库既不在requirements.txt,也不在pyproject.toml——直接 import 会ModuleNotFoundError。这是一段「写好了但跑不起来」的代码,教学价值在两点:一是适配器模式怎么写(包一层让外部库融入自家框架);二是未声明依赖是开源项目常见的坑(代码引用了却不告诉安装者要装什么)。读完本节,你理解适配器模式的意图,也学会识别「隐性依赖」。
内容来源:原项目源码
experimental/crypto_agent_wrapper.py,逐行精读并套用体系化模板。
⚠️ 现实澄清:这段代码当前无法运行——
from cryptoagent.main import CryptoAgent会因cryptoagent未安装而失败,且项目没声明这个依赖。它是「代码正确但环境不全」的样本。
阅读完本节,你应当能够:
CryptoAgentWrapper(全 51 行)。cryptoagent 是未声明依赖(不在 requirements/pyproject)。文件很短(约 51 行),完整呈现:
import os from swarm_models import OpenAIChat from swarms import Agent from cryptoagent.main import CryptoAgent from cryptoagent.prompts import CRYPTO_AGENT_SYS_PROMPT class CryptoAgentWrapper: def __init__(self): self.api_key = os.getenv("OPENAI_API_KEY") self.model = OpenAIChat( openai_api_key=self.api_key, model_name="gpt-4o-mini", temperature=0.1, ) self.input_agent = Agent( agent_name="Crypto-Analysis-Agent", system_prompt=CRYPTO_AGENT_SYS_PROMPT, llm=self.model, max_loops=1, autosave=True, dashboard=False, verbose=True, dynamic_temperature_enabled=True, saved_state_path="crypto_agent.json", user_name="swarms_corp", retry_attempts=1, context_length=10000, ) self.crypto_analyzer = CryptoAgent( agent=self.input_agent, autosave=True ) def run(self, coin_id: str, analysis_prompt: str) -> str: summaries = self.crypto_analyzer.run( [coin_id], analysis_prompt, # real_time=True, ) return summaries # # Example usage # if __name__ == "__main__": # crypto_agent_wrapper = CryptoAgentWrapper() # coin_ids = ["bitcoin", "ethereum"] # analysis_prompt = "Conduct a thorough analysis of the following coins:" # summaries = crypto_agent_wrapper.summarize_crypto_data(coin_ids, analysis_prompt) # print(summaries)
逻辑链:__init__ 建模型 → 建 swarms Agent → 把 Agent 喂给外部 CryptoAgent;run 调外部 CryptoAgent.run。注意末尾的 __main__ 是注释掉的——作者写了个示例又把它注释了,说明这段代码可能从没跑通过。
文件第 6-7 行:
from cryptoagent.main import CryptoAgent from cryptoagent.prompts import CRYPTO_AGENT_SYS_PROMPT
这两行 import 引入了 cryptoagent 这个外部库。但检查项目依赖声明:
| 文件 | 是否声明 cryptoagent |
|---|---|
requirements.txt |
❌(只有 swarms/pydantic/loguru/swarm-models/fastapi/uvicorn/requests/httpx/solders) |
pyproject.toml |
❌ |
.env.example |
❌ |
所以 pip install -U autohedge 的用户不会自动装上 cryptoagent,运行这段代码会立刻 ModuleNotFoundError: No module named 'cryptoagent'。
⚠️ 现实澄清:这是开源项目最常见的「坑」之一——代码引用了外部库,却没在依赖清单里声明。原因通常是:作者在自己环境里
pip install cryptoagent装了能跑,但忘了写进 requirements;或者这段是「实验性」代码(它在experimental/下,且.gitignore第 17 行把整个experimental/都忽略了——本就被排除在正式发布外)。无论哪种,结论是:这段代码在标准安装的环境里跑不起来。
抛开依赖问题,这段代码的设计思路是经典的适配器模式。意图是:
cryptoagent 有自己的 CryptoAgent 类,但它可能不认识 swarms 的 Agent。cryptoagent 复用 swarms Agent 的能力(日志、autosave、重试、动态温度等)。CryptoAgentWrapper 当中间层——内部用 swarms 建好 Agent,再把 Agent 作为参数喂给 CryptoAgent(agent=...)。[你的代码] ──► CryptoAgentWrapper(适配器) ──► CryptoAgent(外部库) │ └─ 内部建 swarms Agent ──► 作为 agent= 参数注入
这种「外部库接受一个 agent 参数」的设计,是依赖注入的一种——外部库不强制你用它的 Agent,你可以传自己的进来。CryptoAgentWrapper 就是利用这个口子,把 swarms Agent 注入进去。
💡 适配器 vs 直接用:直接用
cryptoagent的话,你要学它自己的 Agent API;包一层适配器后,调用方只用熟悉的 swarms 风格,外部库的差异被藏在 Wrapper 里。代价是多一层间接性、多一层维护负担。当外部库稳定、接口清晰时,直接用更简单;当想统一多个外部库到一套接口时,适配器更划算。
逐行看构造函数:
def __init__(self): self.api_key = os.getenv("OPENAI_API_KEY") self.model = OpenAIChat( openai_api_key=self.api_key, model_name="gpt-4o-mini", temperature=0.1, ) self.input_agent = Agent( agent_name="Crypto-Analysis-Agent", system_prompt=CRYPTO_AGENT_SYS_PROMPT, # ← 外部库提供的 prompt llm=self.model, max_loops=1, autosave=True, dashboard=False, verbose=True, dynamic_temperature_enabled=True, saved_state_path="crypto_agent.json", user_name="swarms_corp", retry_attempts=1, context_length=10000, ) self.crypto_analyzer = CryptoAgent( agent=self.input_agent, autosave=True # ← swarms Agent 注入外部库 )
三步:
OpenAIChat 用 gpt-4o-mini、温度 0.1(低温偏确定性,适合分析)。CRYPTO_AGENT_SYS_PROMPT(巧妙——让 swarms Agent 说外部库的「行话」);配 autosave/retry/动态温度等 swarms 特性。CryptoAgent(agent=self.input_agent)——把刚建的 swarms Agent 作为参数传给外部库的 CryptoAgent。关键点是第 3 步:外部库的构造函数接受一个 agent 参数,这正是适配器能成立的口子。如果外部库不接受外部 agent,适配器就只能用继承或猴子补丁(更脏)。
def run(self, coin_id: str, analysis_prompt: str) -> str: summaries = self.crypto_analyzer.run( [coin_id], analysis_prompt, # real_time=True, ) return summaries
coin_id(如 "bitcoin"、"ethereum",是 CoinGecko 风格的 id)+ 分析提示。self.crypto_analyzer.run(外部库的方法)。real_time=True 被注释了——作者考虑过实时模式但注释掉,可能因为不稳或没调通。run 自己几乎不做事,只做转发。这正是适配器的典型形态:对外暴露统一接口,对内转给被适配的对象。
# # Example usage # if __name__ == "__main__": # crypto_agent_wrapper = CryptoAgentWrapper() # coin_ids = ["bitcoin", "ethereum"] # analysis_prompt = "Conduct a thorough analysis of the following coins:" # summaries = crypto_agent_wrapper.summarize_crypto_data(coin_ids, analysis_prompt) # print(summaries)
注意几个问题:
crypto_agent_wrapper.summarize_crypto_data(...),但类里定义的方法是 run——根本没有 summarize_crypto_data 这个方法。这段示例即便取消注释也会 AttributeError。这是「代码未经测试就提交」的典型痕迹。结合前面的依赖缺失,可以判断:这段代码大概率从没成功跑过,是「写一半、试一下、跑不通、先放着」的状态。
进一步看 .gitignore(第 17 行):
experimental/
整个 experimental/ 目录被 git 忽略——意味着这三段实验代码(做市、BTC 监控、CryptoAgent 封装)根本不会进入 git 仓库,也不在 PyPI 发布的包里。它们只存在于作者本地和这份「教程素材」里。
这解释了为什么:
cryptoagent 依赖没声明(实验代码,不发布,作者本地装了就行)。💡 实验代码的定位:
experimental/是「沙盒」——放那些「想法有意思但没打磨」的代码。它的价值是展示思路(做市怎么建模、事件如何驱动 Agent、外部库怎么接),不是「能用的产品功能」。读者应以「学范式」而非「抄代码」的心态对待它。
抛开跑不通,这段代码展示了外部库集成的几个好思路:
但也要警惕:
extras(如 autohedge[experimental])。summarize_crypto_data 不存在这种错误很低级)。cryptoagent)API 易变,应锁定版本,否则升级即坏。CryptoAgentWrapper.__init__ 建 OpenAIChat → 建 swarms Agent → 注入 CryptoAgent(agent=...);run 转发调用。from cryptoagent.main import ... 但 cryptoagent 不在 requirements/pyproject——标准环境直接 ModuleNotFoundError。CryptoAgentWrapper,让外部库 cryptoagent 复用 swarms Agent 的能力;关键是外部库接受 agent= 参数(依赖注入口子)。CRYPTO_AGENT_SYS_PROMPT 作 swarms Agent 的 system prompt,让两者「说同一种话」。__main__ 被注释,且调用了不存在的 summarize_crypto_data 方法——从没跑过的迹象。.gitignore 第 17 行排除整个 experimental/,所以这些代码不进 git/PyPI,只是本地沙盒——解释了依赖不声明、bug 不修的原因。至此第 9 章结束——你看完了三段实验代码:做市(逻辑骨架有价值)、BTC 监控(事件驱动+LLM 范式)、外部封装(适配器思路+依赖缺失)。下一章是全教程收束章,我们批判性盘点 README 营销与代码现实的落差,讲如何扩展到 Coinbase,并给出生产化建议。