Track
Большие языковые модели становятся полезнее, когда им задают специализированные роли, выдают инструменты и доступ к актуальным данным. Вместо одного универсального решения можно собрать небольшую исследовательскую команду, где каждый агент отвечает за свой участок анализа.
Именно это мы и сделаем в этом практикуме: построим мульти-агентного аналитика акций на базе GLM-5.3-Flash и CrewAI. Три агента анализируют фундаментальные показатели, технические индикаторы и свежие новости, а портфельный менеджер объединяет их выводы в финальный исследовательский сигнал BUY, HOLD или SELL.
Сначала протестируем процесс в Jupyter Notebook, затем превратим его в простое терминальное приложение, которое анализирует акции и отвечает на уточняющие вопросы.
В проекте используются:
- GLM-5.3-Flash для рассуждений
- CrewAI для координации агентов
- Finnhub для рыночных и фундаментальных данных
- Yahoo Finance для исторических цен
- Tavily для свежих новостей
- Pandas и NumPy для технических индикаторов
Впервые работаете с фреймворком? Наш курс Building AI Agents with CrewAI разбирает агентов, команды и потоки с нуля.
Почему стоит выбрать GLM-5.3-Flash для мультиагентных приложений
GLM-5.3-Flash предлагает впечатляющий баланс производительности, эффективности и цены. Для полного обзора ознакомьтесь с нашим гайдом по GLM-5.3-Flash и сравнением с Qwen3.8-Flash-Next.
Конкурентные показатели и эффективность
В Artificial Analysis Intelligence Index модель набирает 57 баллов — это уровень лидеров и сопоставимость с рядом куда более дорогих флагманских моделей. Например:
-
GPT-5.6 Sol также имеет 57 (с усилием рассуждений
high), но стоит дороже более чем в 25 раз по входным и в 40 раз по выходным токенам. -
Claude Sonnet 5 показывает чуть ниже — 55 при
max— и при этом дороже в 20/30 раз по входу/выходу, чем GLM-5.3-Flash.
У модели 320B общих параметров, но активно около 18B параметров на токен, что обеспечивает высокую производительность при относительной экономичности вычислений.

Источник: AI Model & API Providers Analysis | Artificial Analysis
Привлекательная стоимость
Как уже отмечалось, такие характеристики доступны по сравнительно низкой цене API. На момент написания OpenRouter предлагает GLM-5.3-Flash со скидкой 50% — $0.075 за миллион входных и $0.25 за миллион выходных токенов.
Даже по обычной цене $0.15/$0.50 это дешевле, чем у моделей вроде GPT-5.6 Luna от OpenAI с $0.20/$1.20 (52 в индексе AA при рассуждениях max). Это делает модель привлекательной не только для экспериментов, но и для более крупных, продакшен-уровня агентных приложений.

Источник: GLM 5.3 Flash - API Pricing & Benchmarks | OpenRouter
Это особенно важно при разработке мультиагентных систем: один пользовательский запрос может вызвать множество внутренних обращений к LLM. Один LLM-агент может многократно звать модель для рассуждений, выбора инструмента, обработки результатов и генерации ответа. Если один агент делает около семи вызовов LLM, а ваш процесс использует пять агентов, один запрос легко превратится в 35 и более обращений.
Точное число зависит от архитектуры системы, но мысль проста: агентные пайплайны быстро дорожают. Выбор способной модели с низкой ценой за токен, такой как GLM-5.3-Flash, может серьёзно повлиять на переход от небольшого демо к реальному продакшен-приложению.
1. Подготовьте окружение для GLM-5.3-Flash
Перед сборкой мультиагентного процесса создайте API-ключи для Z.ai, Finnhub и Tavily.
Создайте API-ключи
Для Z.ai убедитесь, что используете обычный API, а не GLM Coding Plan. Coding Plan предназначён для поддерживаемых ИИ-инструментов программирования и не подходит как универсальный API для вашей мультиагентной системы.
Сгенерируйте обычный API-ключ Z.ai и пополните счёт на небольшую сумму. Поскольку GLM-5.3-Flash недорогая, для старта тестов хватит малого баланса.

Источник: Z.ai API Platform — начните работу с GLM-5.3
Также можно создать бесплатные аккаунты на Finnhub и Tavily и сгенерировать API-ключи. Их бесплатных тарифов достаточно для тестирования этого проекта.
Настройте файлы проекта
Далее создайте файл .env в папке проекта и добавьте туда ключи API:
ZAI_API_KEY="your_zai_api_key"
FINNHUB_API_KEY="your_finnhub_api_key"
TAVILY_API_KEY="your_tavily_api_key"
Теперь создайте новый Jupyter Notebook. Сначала мы построим и протестируем здесь полный мультиагентный процесс, посмотрим вывод каждого агента и исправим недочёты, прежде чем превратить всё в полноценное приложение.
Установите необходимые библиотеки
Мы будем использовать CrewAI для создания и координации агентов, Finnhub для данных рынка акций и Tavily для веб-поиска в реальном времени. Установите требуемые пакеты Python:
!pip install -q crewai crewai-tools finnhub-python tavily-python pandas numpy requests python-dotenv openai
Импортируйте библиотеки и ключи API
Далее импортируйте требуемые библиотеки и загрузите ключи API:
import os
import re
import time
import finnhub
import numpy as np
import pandas as pd
import requests
from dotenv import load_dotenv
from openai import OpenAI
from tavily import TavilyClient
from crewai import Agent, Crew, LLM, Process, Task
from crewai.tools import tool
from crewai_tools import TavilySearchTool
# Load environment variables
load_dotenv()
# Disable CrewAI tracing
os.environ.setdefault("CREWAI_TRACING_ENABLED", "false")
os.environ.setdefault("OTEL_SDK_DISABLED", "true")
Наконец, выберите тикер акции для анализа агентами:
TICKER = "NVDA"
В тетрадке будет использоваться NVIDIA (NVDA), но вы можете заменить её на любой интересующий вас тикер, например AAPL, MSFT или TSLA.
2. Настройте GLM-5.3-Flash и API данных
Теперь, когда ключи готовы, подключим сервисы, которыми агенты будут пользоваться в проекте.
Начнём с инициализации Finnhub для рыночных данных и Tavily для веб-поиска:
finnhub_client = finnhub.Client(
api_key=os.environ["FINNHUB_API_KEY"]
)
tavily_client = TavilyClient(
api_key=os.environ["TAVILY_API_KEY"]
)
Если вы хотите создавать финансовых агентов и сомневаетесь, какой источник данных выбрать, рекомендуем наше руководство по выбору подходящего API рынка акций.
Далее настроим GLM-5.3-Flash как основной LLM для агентов CrewAI. Z.ai предоставляет API, совместимый с OpenAI, так что можно подключиться через класс CrewAI LLM напрямую:
llm = LLM(
model="openai/glm-5.3-flash",
api_key=os.environ["ZAI_API_KEY"],
base_url="https://api.z.ai/api/paas/v4/",
temperature=0.1,
)
Мы оставляем низкую температуру, потому что приложение посвящено финансовым исследованиям и анализу — нам важны устойчивые и сфокусированные ответы.
С моделью и API для рыночных данных и поиска всё подключено — можно переходить к инструментам, которыми будут пользоваться агенты.
3. Соберите исторические рыночные данные
Далее нужны исторические цены, чтобы агенты понимали динамику акций во времени.
Для этого используем публичный endpoint графиков Yahoo Finance, чтобы собрать дневные открытия, максимумы, минимумы, закрытия и объёмы.
Скачайте историю цен
HTTP = requests.Session()
HTTP.headers.update({"User-Agent": "glm-stock-swarm/1.0"})
def _yahoo_history(ticker: str, days: int) -> pd.DataFrame:
end = int(time.time())
start = end - days * 24 * 60 * 60
response = HTTP.get(
f"https://query1.finance.yahoo.com/v8/finance/chart/{ticker}",
params={
"period1": start,
"period2": end,
"interval": "1d",
"events": "history",
},
timeout=30,
)
response.raise_for_status()
result = response.json()["chart"]["result"][0]
values = result["indicators"]["quote"][0]
frame = pd.DataFrame({
"date": pd.to_datetime(
result["timestamp"], unit="s", utc=True
).tz_localize(None),
"open": values["open"],
"high": values["high"],
"low": values["low"],
"close": values["close"],
"volume": values["volume"],
})
frame = (
frame.dropna(subset=["close"])
.sort_values("date")
.reset_index(drop=True)
)
frame.attrs["source"] = "Yahoo public chart"
return frame
def get_price_history(ticker: str, days: int = 450) -> pd.DataFrame:
return _yahoo_history(ticker.strip().upper(), days)
Мы соберём около 450 дней истории — этого достаточно для расчёта долгосрочных индикаторов, например 200-дневной скользящей средней.
Рассчитайте технические индикаторы
Теперь рассчитаем несколько распространённых индикаторов:
- Скользящие средние: среднее за последние 20, 50 и 200 дней
- Индекс относительной силы (RSI): шкала 0–100, показывающая перекупленность (>70) и перепроданность (<30)
- MACD (конвергенция/дивергенция скользящих средних): разница между долгой и короткой EMA
def add_indicators(frame: pd.DataFrame) -> pd.DataFrame:
if frame.empty:
return frame.copy()
result = frame.copy()
result.attrs.update(frame.attrs)
# Moving averages
result["SMA20"] = result["close"].rolling(20).mean()
result["SMA50"] = result["close"].rolling(50).mean()
result["SMA200"] = result["close"].rolling(200).mean()
# RSI
delta = result["close"].diff()
gain = delta.clip(lower=0)
loss = -delta.clip(upper=0)
avg_gain = gain.ewm(
alpha=1 / 14, min_periods=14, adjust=False
).mean()
avg_loss = loss.ewm(
alpha=1 / 14, min_periods=14, adjust=False
).mean()
result["RSI14"] = 100 - (
100 / (1 + avg_gain / avg_loss.replace(0, np.nan))
)
# MACD
result["EMA12"] = result["close"].ewm(
span=12, adjust=False
).mean()
result["EMA26"] = result["close"].ewm(
span=26, adjust=False
).mean()
result["MACD"] = result["EMA12"] - result["EMA26"]
return result
Эти индикаторы помогут техническому агенту быстро увидеть тренды и импульс, не заставляя LLM всё рассчитывать самостоятельно.
Проверьте последние значения
Соберите данные, рассчитайте индикаторы и выведите последние строки:
history = add_indicators(
get_price_history(TICKER)
)
if len(history) < 200:
raise RuntimeError(
f"Need at least 200 daily observations; received {len(history)}."
)
print(
f"Loaded {len(history)} rows "
f"from {history.attrs['source']} ."
)
history.tail(3)[
[
"date",
"close",
"SMA20",
"SMA50",
"SMA200",
"RSI14",
"MACD",
]
]

Вы должны увидеть последнюю цену вместе со скользящими средними, RSI и MACD — примерно как на скриншоте выше.
Позднее мы передадим эти данные техническому агенту, чтобы он определил тренд, импульс и бычьи/медвежьи сигналы.
4. Превратите источники данных в инструменты CrewAI
Теперь, когда источники данных работают, оформим их как инструменты CrewAI. Это позволит агентам вызывать их напрямую, когда нужны фундаментальные, технические или новостные сведения.
Создайте инструменты для данных об акциях
Сначала создадим небольшую вспомогательную функцию для аккуратного и единообразного форматирования чисел:
def _number(value, decimals: int = 2) -> str:
if value is None or pd.isna(value):
return "N/A"
return f"{float(value):,.{decimals}f}"
Далее создадим инструмент для фундаментального анализа. Он использует Finnhub для получения последней цены, оценочных мультипликаторов, показателей роста, прибыльности и других метрик компании.
@tool("Get Stock Fundamentals")
def get_fundamentals(ticker: str) -> str:
"""Get current price and company fundamentals from Finnhub for one ticker."""
ticker = ticker.strip().upper()
quote = finnhub_client.quote(ticker)
metrics = finnhub_client.company_basic_financials(ticker, "all")
m = metrics.get("metric", {})
return f"""Ticker: {ticker}
Source: Finnhub
Current price: {_number(quote.get('c'))}
Previous close: {_number(quote.get('pc'))}
Daily change %: {_number(quote.get('dp'))}
Day high / low: {_number(quote.get('h'))} / {_number(quote.get('l'))}
Market cap (USD millions): {_number(m.get('marketCapitalization'))}
52-week high / low: {_number(m.get('52WeekHigh'))} / {_number(m.get('52WeekLow'))}
Normalized annual P/E: {_number(m.get('peNormalizedAnnual'))}
Annual P/B: {_number(m.get('pbAnnual'))}
Annual P/S: {_number(m.get('psAnnual'))}
ROE TTM: {_number(m.get('roeTTM'))}
Net margin TTM: {_number(m.get('netProfitMarginTTM'))}
Revenue growth TTM YoY: {_number(m.get('revenueGrowthTTMYoy'))}
EPS growth TTM YoY: {_number(m.get('epsGrowthTTMYoy'))}
Annual debt/equity: {_number(m.get('totalDebt/totalEquityAnnual'))}"""
Также создадим инструмент технического анализа на основе исторических данных и индикаторов из предыдущего раздела.
@tool("Analyze Stock Technicals")
def get_technicals(ticker: str) -> str:
"""Calculate price trends, returns, moving averages, RSI, and MACD."""
ticker = ticker.strip().upper()
frame = add_indicators(get_price_history(ticker))
if len(frame) < 200:
return (
f"Technical data unavailable for {ticker}: "
"fewer than 200 observations."
)
latest = frame.iloc[-1]
return f"""Ticker: {ticker}
Source: {frame.attrs.get('source', 'unknown')}
Last market date: {latest['date'].date()}
Close: {_number(latest['close'])}
SMA20 / SMA50 / SMA200: {_number(latest['SMA20'])} / {_number(latest['SMA50'])} / {_number(latest['SMA200'])}
RSI14: {_number(latest['RSI14'])}
MACD: {_number(latest['MACD'])}
20-day return: {_number((latest['close'] / frame['close'].iloc[-21] - 1) * 100)}%
50-day return: {_number((latest['close'] / frame['close'].iloc[-51] - 1) * 100)}%
Price vs SMA20: {_number((latest['close'] / latest['SMA20'] - 1) * 100)}%
Price vs SMA50: {_number((latest['close'] / latest['SMA50'] - 1) * 100)}%
Price vs SMA200: {_number((latest['close'] / latest['SMA200'] - 1) * 100)}%"""
Ключевой момент — декоратор @tool. Он превращает обычную функцию Python в инструмент, который агент CrewAI может вызывать во время выполнения задачи.
Добавьте инструмент веб-поиска
Для новостей и свежих событий используем инструмент поиска Tavily из CrewAI:
web_search = TavilySearchTool(
api_key=os.environ["TAVILY_API_KEY"],
topic="news",
search_depth="advanced",
days=30,
max_results=5,
)
Мы ограничиваем поиск последними 30 днями и возвращаем до пяти результатов — этого достаточно для свежей фактуры без лишнего шума.
Протестируйте инструменты
Перед созданием агентов запустите два пользовательских инструмента напрямую:
print(get_fundamentals.run(ticker=TICKER))
print()
print(get_technicals.run(ticker=TICKER))

Теперь вы должны увидеть свежие фундаментальные метрики, а затем технические индикаторы для выбранной акции.
5. Соберите мультиагентную исследовательскую команду
Когда инструменты готовы, можно создать мультиагентную команду.
Мы используем трёх специалистов: по фундаменталу, по технике и по новостям, а также портфельного менеджера, который объединяет их выводы в итоговую оценку.
Создайте агентов-специалистов
Сначала — фундаментальный аналитик:
fundamental_agent = Agent(
role="Fundamental Analyst",
goal=(
"Evaluate financial health, growth, profitability, "
"valuation, and balance-sheet risk."
),
backstory=(
"You are a careful long-term equity analyst. "
"Use the fundamentals tool and never invent a figure. "
"Treat N/A as missing, not as zero."
),
tools=[get_fundamentals],
llm=llm,
allow_delegation=False,
max_iter=4,
verbose=False,
)
Далее — технический аналитик:
technical_agent = Agent(
role="Technical Analyst",
goal=(
"Determine whether the current price setup is "
"bullish, bearish, or neutral."
),
backstory=(
"You interpret indicators calculated by Python. "
"Never guess market prices or indicator values."
),
tools=[get_technicals],
llm=llm,
allow_delegation=False,
max_iter=4,
verbose=False,
)
Затем — аналитик новостей:
news_agent = Agent(
role="Financial News Analyst",
goal=(
"Find material recent developments and distinguish "
"confirmed reporting from speculation."
),
backstory=(
"You are a skeptical financial-news researcher. "
"Prioritize primary and reputable sources, dates, and links."
),
tools=[web_search],
llm=llm,
allow_delegation=False,
max_iter=5,
verbose=False,
)
Каждому специалисту выдаётся только нужный инструмент. Это делает процесс сфокусированным и предотвращает обращения к нерелевантным источникам.
Создайте портфельного менеджера
Наконец, создадим менеджера, который просматривает три отчёта специалистов:
manager_agent = Agent(
role="Portfolio Manager",
goal=(
"Combine the specialist reports into a balanced, "
"evidence-based research signal."
),
backstory=(
"You lead an equity research team. "
"Weigh bullish and bearish evidence, use HOLD when evidence "
"is mixed, and never add unsupported facts."
),
llm=llm,
allow_delegation=False,
max_iter=4,
verbose=False,
)
Портфельному менеджеру не нужен прямой доступ к нашим инструментам. Он работает с отчётами трёх специалистов.
Параметр allow_delegation=False делает процесс предсказуемым, а max_iter ограничивает число циклов рассуждений и использования инструментов каждым агентом.
6. Поставьте специализированные исследовательские задачи
Создание агентов определяет, кто они. Теперь нужно точно задать, что им делать и каким должен быть итоговый вывод.
Определите исследовательские задачи
Начнём с задачи по фундаменталу:
fundamental_task = Task(
description=(
f"Analyze {TICKER}'s growth, profitability, valuation, "
"balance sheet, and business quality. "
"Use Get Stock Fundamentals. "
"Return a Fundamental Score from 0-100, strongest positive, "
"biggest risk, and note all material missing data."
),
expected_output=(
"A concise fundamental assessment with a 0-100 score, "
"evidence, strongest positive, biggest risk, "
"and missing-data note."
),
agent=fundamental_agent,
)
Теперь задача по технике:
technical_task = Task(
description=(
f"Analyze {TICKER}'s technical setup. "
"Use Analyze Stock Technicals. "
"Consider SMA20/50/200, RSI14, MACD, recent returns, and trend. "
"Return Technical Score 0-100, Bullish/Neutral/Bearish signal, "
"trend, momentum, and main technical risk."
),
expected_output=(
"A concise technical assessment with score, signal, trend, "
"momentum, data source, and main risk."
),
agent=technical_agent,
)
Для свежих событий создадим новостную задачу:
news_task = Task(
description=(
f"Research the most important recent news for {TICKER}, "
"focusing on the last 30 days: earnings, guidance, analyst "
"revisions, products, partnerships, M&A, regulation, lawsuits, "
"management, and industry developments. "
"Use Tavily Search. "
"Return News Score 0-100, sentiment, positive and negative "
"catalysts, publication dates, and source URLs. "
"Ignore low-quality speculation."
),
expected_output=(
"A sourced recent-news assessment with score, sentiment, "
"catalysts, dates, and clickable URLs."
),
agent=news_agent,
)
Чёткая формулировка задач и формата вывода важна: так портфельному менеджеру проще сравнивать отчёты, а не разнородные ответы от каждого агента.
Создайте задачу финального решения
Финальная задача объединяет все три отчёта:
decision_task = Task(
description=(
f"Review all three specialist reports and make the final "
f"educational research assessment for {TICKER}. "
"Return exactly one signal: BUY, HOLD, or SELL. "
"Use HOLD when evidence is mixed or confidence is insufficient. "
"Base every claim only on the supplied reports."
),
expected_output=(
"Ticker; Signal; Overall Score /100; Confidence %; "
"Fundamental, Technical, and News scores; Bull Case; "
"Bear Case; Main Catalyst; Main Risk; Final Explanation; "
"Sources; and an educational-not-financial-advice disclaimer."
),
agent=manager_agent,
context=[
fundamental_task,
technical_task,
news_task,
],
)
Ключ — параметр context. Он даёт портфельному менеджеру доступ к результатам трёх задач специалистов, чтобы тот сопоставил фундаментал, технику и новости перед вынесением итоговой оценки BUY, HOLD или SELL.
На этом этапе агенты, инструменты и задачи готовы. Теперь объединим всё в процесс CrewAI и запустим полную исследовательскую команду.
7. Запустите мультиагентную команду
Теперь можно собрать всё вместе и запустить полный процесс исследования акций.
Создайте команду
Создайте команду CrewAI из трёх специалистов и портфельного менеджера:
crew = Crew(
agents=[
fundamental_agent,
technical_agent,
news_agent,
manager_agent,
],
tasks=[
fundamental_task,
technical_task,
news_task,
decision_task,
],
process=Process.sequential,
verbose=False,
tracing=False,
)
Мы используем Process.sequential, поэтому задачи выполняются по порядку: сначала фундаментал, техника и новости, затем портфельный менеджер формирует финальную оценку.
Запустите исследовательскую команду
Стартуем процесс асинхронно:
result = await crew.kickoff_async()
Этот шаг может занять время: агенты делают несколько обращений к LLM и инструментам. В нашем тесте полный цикл занял около 4–5 минут.
По завершении выведите финальный отчёт портфельного менеджера:
print(result.raw)

Вы получите подробный отчёт, похожий на показанный выше, включая:
- сигнал BUY, HOLD или SELL
- общий балл
- уровень уверенности
- оценки специалистов
- бычий сценарий
- медвежий сценарий
- катализаторы
- риски
- ссылки на источники
В этом примере агенты независимо проанализировали NVIDIA, а затем объединили выводы в единый отчёт, основанный на доказательствах. Здесь видна ценность мультиагентного подхода: вместо того чтобы просить одну модель сделать всё сразу, каждый агент фокусируется на своей области, а портфельный менеджер собирает исследования воедино.
Если у вас возникнут сложности с запуском кода выше, мы добавили полную Jupyter-ноутбук с кодом и выводами — можно изучить или запустить самостоятельно: glm-stock-swarm/stock_analyst_crew.ipynb
8. Соберите и запустите терминальный интерфейс
После тестирования в Jupyter Notebook мы превратили весь процесс в терминальный интерфейс (TUI). Теперь вместо поочерёдного запуска ячеек можно стартовать мультиагентного аналитика одной командой.
Весь проект с кодом и инструкциями доступен на GitHub: репозиторий glm-stock-swarm.
Установка и запуск
Начните с клонирования репозитория:
git clone https://github.com/kingabzpro/glm-stock-swarm.git
cd glm-stock-swarm
Добавьте ключи API Z.ai, Finnhub и Tavily в файл .env, затем установите зависимости с помощью uv:
uv sync
Запустите TUI:
uv run glm-stock-swarm
Проанализируйте акцию
Интерфейс предоставляет простое поле ввода, куда можно ввести любой поддерживаемый тикер для запуска анализа.

После отправки тикера вы увидите последовательную работу агентов. Сначала — фундаментальный аналитик, затем технический, затем новостной, и, наконец, портфельный менеджер, который формирует итоговое решение.

В конце TUI формирует полный отчёт прямо в терминале: фундаментальный, технический и новостной баллы, общий балл, уверенность, бычий и медвежий сценарии, риски, катализаторы и финальный сигнал BUY, HOLD или SELL.
Задавайте уточняющие вопросы
Мы также добавили чат для уточняющих вопросов, чтобы не запускать весь мультиагентный конвейер заново каждый раз.

Например, получив рекомендацию SELL, мы спросили, стоит ли продавать всю позицию или только часть.

Вместо повторного запуска четырёх агентов приложение использует контекст готового отчёта и выдаёт гораздо более быстрый ответ на уточнение.
Это делает приложение практичнее: дорогой мультиагентный анализ выполняется один раз, а последующие вопросы используют уже проведённое исследование.
Заключение
Главное наблюдение по итогам тестов — надёжность вызова инструментов. Все три специалиста выбирали правильный инструмент, соблюдали правило N/A вместо подстановки нулей и возвращали формат «оценка + доказательства», который требовался портфельному менеджеру. Обычно на этом и спотыкаются недорогие модели.
Цена — скорость. Artificial Analysis измеряет скорость вывода GLM-5.3-Flash примерно в 45 токенов в секунду через API Z.ai — это нижняя граница для открытых моделей такого размера, и это ощущается в 4–5 минутах полного прогона команды. В их индексе интеллекта модель набирает 57 против 60 у GLM-5.3 — то есть чуть меньшая глубина рассуждений, но это оправданный обмен, учитывая, что стоимость примерно в десять раз ниже.
Никакой жёсткой привязки тут нет. Переход на OpenRouter, Hugging Face Inference или локальную модель через Ollama обычно сводится к трём изменениям: ключ API, имя модели и базовый URL. То же и с инструментами: yfinance может заменить связку Finnhub + Yahoo.
Следующим шагом можно подключить API бумажной торговли и запланировать утренний прогон. Но держите это на демо-счёте: система создана для обучения проектированию агентов, а не для торговли.
Если хотите изучить агентный ИИ с нуля, рекомендуем наш трек AI Agent Fundamentals как отличную отправную точку.