Запустите ai-hedge-fund на кастомном OpenAI-совместимом base URL.

Updated 2026-07-30

ai-hedge-fund строит свои модели OpenAI через LangChain ChatOpenAI и читает base URL из OPENAI_API_BASE. Установите его в https://api.apisrouter.com/v1, экспортируйте один ключ — и каждый агент-аналитик фонда маршрутизируется через единый эндпоинт.

Короткий ответ: OPENAI_API_BASE плюс один ключ.

Провайдер OpenAI в ai-hedge-fund инстанцируется как ChatOpenAI(model=model_name, api_key=api_key, base_url=base_url), и этот base_url берётся из os.getenv("OPENAI_API_BASE") в src/llm/models.py. Так что переопределение — это две строки в .env: направьте OPENAI_API_BASE на https://api.apisrouter.com/v1 и установите OPENAI_API_KEY в ваш ключ шлюза. Теперь каждая модель, работающая через провайдера OpenAI, отправляет запросы шлюзу. Внимательно проверьте имя переменной: это OPENAI_API_BASE, соглашение эпохи LangChain, а не OPENAI_BASE_URL. Экспорт не той переменной тихо игнорируется, и запросы продолжают идти на api.openai.com — это самая частая причина, по которой эта настройка выглядит нерабочей.

OPENAI_API_BASE=https://api.apisrouter.com/v1
OPENAI_API_KEY=sk-APIsRouter-...
FINANCIAL_DATASETS_API_KEY=...   # market data, unrelated to the LLM endpoint

Как ai-hedge-fund выбирает модель и провайдера.

ai-hedge-fund (virattt на GitHub, около 62K звёзд) симулирует фонд как комитет агентов: персоны аналитиков, смоделированные по известным инвесторам, плюс агенты оценки, настроений, фундаментальных показателей и технического анализа, питающие риск-менеджера и портфельного менеджера, которые формируют финальные сигналы. Все они разделяют один выбор модели на прогон, так что единственное решение по модели умножается на каждого агента и каждый тикер. Выбор модели идёт по двум путям. В интерактивном режиме запуск poetry run python src/main.py --ticker AAPL,MSFT,NVDA без флага модели открывает диалог выбора (questionary). В скриптовом режиме флаг --model принимает имя модели, но только те имена, что существуют в реестре моделей репозитория: find_model_by_name() ищет строку в src/llm/api_models.json, и каждая запись реестра несёт display_name, model_name и provider. Если поиск не удаётся, CLI не угадывает провайдера — он откатывается к интерактивному выбору, что критично для автоматизации: неизвестный id превращает скриптовый прогон в такой, что просто ждёт ввода с клавиатуры. Поле provider решает маршрутизацию. Записи с пометкой OpenAI идут через ChatOpenAI и учитывают OPENAI_API_BASE; записи с пометкой Anthropic идут через ChatAnthropic и ANTHROPIC_API_KEY, полностью минуя ваш base URL. Это ключевое понимание для маршрутизации через шлюз: столбец provider выбирает клиента и, следовательно, эндпоинт — независимо от того, кто на самом деле обучил модель.

Полная настройка: .env плюс запись в реестре на каждую модель шлюза.

Для моделей, уже перечисленных в реестре под провайдером OpenAI, достаточно только переопределения в .env; строка модели передаётся эндпоинту как есть. Чтобы прогнать id Claude, DeepSeek или Qwen через шлюз на том же ключе, добавьте запись в src/llm/api_models.json с id каталога в качестве model_name и, что критично, "OpenAI" в качестве provider. Provider выбирает клиента, так что запись с пометкой OpenAI маршрутизируется через ChatOpenAI и ваш OPENAI_API_BASE, даже если сама модель — не модель OpenAI. Запись тогда появляется в интерактивном выборе и резолвится через --model в скриптах. Это правка JSON в три строки в вашем клоне, а не изменение кода, и это уже задокументированная форма, которую использует реестр. Держите в уме нативные для провайдера записи как контраст: выбор модели реестра с пометкой Anthropic будет искать ANTHROPIC_API_KEY и идти прямиком на эндпоинт Anthropic. Если ваша цель — один ключ шлюза на всё, прогоняйте модели через записи с пометкой OpenAI, и тогда ключи по каждому вендору можно вообще не задавать.

{
  "display_name": "Claude Sonnet 4.6 (gateway)",
  "model_name": "claude-sonnet-4-6",
  "provider": "OpenAI"
},
{
  "display_name": "DeepSeek V4 Pro (gateway)",
  "model_name": "deepseek-v4-pro",
  "provider": "OpenAI"
}

Выбор модели для комитета агентов.

Поскольку реестр делает каждого кандидата адресуемым за одним флагом, честная оценка эмпирична: прогоните одни и те же тикеры и даты через две-три модели и сравните сигналы и расходы. Вид использования по ключу оценивает каждый прогон за вас, что превращает выбор модели из спора в измерение.

  • Один прогон — это множество вердиктов. Каждая персона-аналитик рассуждает над теми же отчётами и ценовыми данными по каждому тикеру, так что выбор модели умножается на число агентов, умноженное на число тикеров. Флагманский id рассуждений (claude-opus-4-7, gpt-5.5) поднимает качество каждого вердикта при соответственно умноженном счёте за токены.
  • claude-sonnet-4-6 — разумный выбор по умолчанию: достаточно силён, чтобы рассуждение персон оставалось связным на длинном фундаментальном контексте, и оценён по цене для прогонов, разворачивающихся на дюжину агентов и корзину тикеров.
  • deepseek-v4-pro и qwen3.7-max стоит бенчмаркнуть для широких прогонов, где разница в цене за прогон накапливается по каждой дате бэктеста.
  • Что бы вы ни выбрали — зафиксируйте это. Сигналы от разных снимков движущейся модели несопоставимы в рамках окна бэктеста; используйте точные id и записывайте строку модели рядом с результатами, как случайное зерно (seed).

Оплата по факту · дешевле официальных цен

Selected models are priced below official list prices. Exact input, output, cache, and per-request prices are shown for each model.

МодельОфициальная ценаНаша цена
Claude Opus 4.7$5.00 / $25.00 per M$4.00 / $20.00 per M
Claude Sonnet 4.6$3.00 / $15.00 per M$2.40 / $12.00 per M
GPT-5.5$5.00 / $30.00 per M$4.00 / $24.00 per M
DeepSeek V4 Pro$0.43 / $0.87 per M$0.40 / $0.90 per M
Qwen 3.7 Max$2.50 / $7.50 per M$2.50 / $7.50 per M

Сбои, специфичные именно для ai-hedge-fund.

Неверная переменная окружения. Этот репозиторий читает OPENAI_API_BASE. OPENAI_BASE_URL, переменная, которую используют другие инструменты, здесь не учитывается, и её установка не делает ничего, кроме как убеждает вас, что переопределение сломано. Если запросы всё ещё идут на api.openai.com, сначала проверьте имя переменной. --model с незарегистрированным id. find_model_by_name() знает только записи в api_models.json. Передайте id каталога, который не зарегистрирован, и CLI выведет сообщение об отсутствии и упадёт в интерактивный выбор, что в cron-задаче или прогоне CI означает тихое зависание, а не ошибку выхода. Сначала зарегистрируйте id — тогда скриптовые прогоны резолвят его детерминированно. Записи с пометкой провайдера, минующие шлюз. Выбор модели реестра с provider Anthropic, Google или DeepSeek маршрутизируется через нативный клиент и ключ этого вендора. Если вы ожидали, что прогон появится в логе использования шлюза, а он не появился, — объяснение в столбце provider выбранной модели. Ошибки данных, маскирующиеся под ошибки LLM. Ценовые и фундаментальные данные приходят из API финансовых данных, настроенного через FINANCIAL_DATASETS_API_KEY — совершенно отдельного сервиса. Отсутствующий или исчерпанный ключ данных роняет прогон до или между вызовами LLM, и трассировка может читаться как проблема модели. Эти два набора учётных данных падают независимо друг от друга — отлаживайте их по отдельности. Интерактивные подсказки в автоматизации. Даже при полностью настроенном окружении забытый флаг --model открывает диалог выбора. Для непривязанных к вниманию прогонов всегда передавайте --model с зарегистрированным id.

Кто направляет ai-hedge-fund через шлюз.

  • Бэктестеры, прогоняющие тикеры и диапазоны дат, где комитет агентов на тикер на дату делает расход токенов доминирующей статьёй, а использование по ключу — естественной бухгалтерией.
  • Исследователи, сравнивающие вердикты моделей. Тот же прогон под двумя id моделей — это смена флага, и расхождение сигналов между моделями само по себе интересные данные.
  • Разработчики, расширяющие репозиторий новыми агентами, которым нужен один эндпоинт и один ключ под любым числом добавленных персон.
  • Разработчики, которым нужны рассуждения Claude или DeepSeek внутри репозитория, чей самый чистый путь маршрутизации имеет форму OpenAI, без поддержки ключа вендора на каждую запись провайдера.
  • Разработчики без доступа к биллингу конкретного вендора. Доступ на основе пополнения без требования карты убирает зависимость от регистрации у каждого провайдера.

Проверьте эндпоинт и отладьте первый прогон.

Прежде чем запускать прогон, убедитесь, что шлюз обслуживает зарегистрированные вами id; строки model_name реестра должны точно совпадать с обслуживаемыми id. Лестница сбоев первого прогона: 401 означает, что OPENAI_API_KEY в окружении, с которым реально запущен poetry, — не ключ шлюза. Ошибка model-not-found от шлюза означает, что model_name записи реестра содержит опечатку относительно /v1/models. Прогон, который останавливается и просит ввод, означает, что строка --model не попала в реестр. Ошибка ключа вендора (Anthropic, Google) означает, что provider выбранной записи — не OpenAI. А трассировка в форме данных до какого-либо вывода модели указывает на FINANCIAL_DATASETS_API_KEY, а не на путь LLM. Как только прогон завершается, консоль APIsRouter показывает модель на запрос, счётчики токенов и расходы. Прогон комитета — это десятки вызовов через этапы аналитиков, риска и портфеля, и вид использования — это то, как вы видите, сколько реально стоит одно решение, прежде чем масштабировать его в широкий прогон.

curl -s https://api.apisrouter.com/v1/models \
  -H "Authorization: Bearer $OPENAI_API_KEY" | head -50

Частые вопросы

Какая переменная окружения задаёт кастомный base URL для ai-hedge-fund?

OPENAI_API_BASE. Провайдер OpenAI в src/llm/models.py строит ChatOpenAI с base_url=os.getenv("OPENAI_API_BASE"). OPENAI_BASE_URL этим репозиторием не читается, так что используйте именно написание API_BASE.

Может ли ai-hedge-fund прогонять модели Claude или DeepSeek через один ключ?

Да, зарегистрировав id в src/llm/api_models.json с provider, установленным в "OpenAI". Provider выбирает клиента, так что запись с пометкой OpenAI маршрутизируется через ChatOpenAI и ваш OPENAI_API_BASE, а id каталога передаётся шлюзу как простая строка.

Почему --model бросает меня в интерактивный выбор?

Значение --model ищется через find_model_by_name() в api_models.json. Неизвестные id не угадываются: CLI выводит сообщение об отсутствии и открывает диалог выбора. Добавьте запись реестра для этого id, и скриптовые прогоны резолвят его без запроса.

Всё ещё нужен ли мне ANTHROPIC_API_KEY или другие ключи вендоров?

Не для моделей, маршрутизируемых через шлюз. Ключи вендоров учитываются только записями реестра, помеченными provider этого вендора. Если каждая ваша модель зарегистрирована под провайдером OpenAI, ключ шлюза — единственные учётные данные LLM, нужные прогону.

Меняется ли настройка рыночных данных при смене эндпоинта LLM?

Нет. Ценовые и фундаментальные данные идут через API финансовых данных, настроенный через FINANCIAL_DATASETS_API_KEY, независимый от base URL LLM. Эти два набора учётных данных падают на разных фазах прогона, так что отлаживайте их раздельно.

Насколько дорог один прогон ai-hedge-fund?

Он масштабируется как агенты умножить на тикеры: каждая персона-аналитик, плюс риск- и портфельный менеджмент, рассуждает по каждому тикеру. Прогоны с одной корзиной обычно приземляются в десятках-сотнях тысяч токенов, а бэктест-прогоны умножают это на сетку дат. Вид использования по ключу даёт точную цифру на прогон.