Draai Stanford STORM op een aangepast OpenAI-compatibel endpoint.
Updated 2026-07-29
STORM bouwt elk taalmodel als een LitellmModel, en litellm accepteert api_base. Zet https://api.apisrouter.com/v1 in je gedeelde openai_kwargs, geef model-ID's het voorvoegsel openai/, en alle vijf LM-slots van de artikelpipeline routeren via één endpoint en één sleutel.
Snel antwoord: api_base in openai_kwargs, voorvoegsel openai/ op ID's.
De LitellmModel van STORM bewaart welke kwargs je ook meegeeft bij constructie en voegt ze samen in elke litellm.completion()-aanroep. De parameter api_base van litellm is hoe je de openai-provider naar een andere host wijst, dus api_base toevoegen aan de openai_kwargs-dict die de eigen voorbeelden van STORM al gebruiken, is de hele override. Geef elk model-ID het voorvoegsel openai/ zodat litellm het chat-completions-protocol spreekt tegen die base, en de string na de schuine streep wordt doorgegeven aan de gateway. Omdat de voorbeelden één openai_kwargs-dict bouwen en die hergebruiken voor elk model, herroutet één toegevoegde sleutel de hele pipeline. Geen STORM-codewijzigingen, geen fork; dit is standaard knowledge_storm-gedrag gelaagd op het gedocumenteerde routeringsgedrag van litellm.
openai_kwargs = {
"api_key": os.getenv("APISROUTER_API_KEY"),
"api_base": "https://api.apisrouter.com/v1",
"temperature": 1.0,
"top_p": 0.9,
}
fast = LitellmModel(model="openai/deepseek-v4-flash", max_tokens=500, **openai_kwargs)
strong = LitellmModel(model="openai/claude-sonnet-4-6", max_tokens=3000, **openai_kwargs)Hoe STORM een artikel over vijf LM-slots verdeelt.
STORM (stanford-oval op GitHub, ruim 30K sterren) schrijft Wikipedia-achtige rapporten vanaf nul: het onderzoekt een onderwerp via gesimuleerde multi-perspectiefgesprekken, bouwt een overzicht uit wat het leerde, genereert het volledige artikel sectie voor sectie, en polijst het daarna. STORMWikiLMConfigs stelt die pipeline bloot als vijf onafhankelijk instelbare modellen: conv_simulator_lm en question_asker_lm drijven de onderzoeksgesprekken aan, outline_gen_lm structureert het artikel, article_gen_lm schrijft het, en article_polish_lm doet de laatste pas. De upstream README is expliciet over de economie: de gespreksimulator draait het hoogste aanroepvolume, dus wordt daar een sneller model aanbevolen en een krachtiger model voor artikelgeneratie. Die richtlijn ging uit van kiezen tussen OpenAI-modellen; achter een multi-vendor endpoint generaliseert het naar iets nuttigers. Elke slot is zijn eigen LitellmModel met zijn eigen model-string, dus het onderzoeksgebabbel kan op een snel DeepSeek-ID draaien terwijl overzicht- en artikelgeneratie op Claude draaien, en polijsten op welk model je ook vertrouwt voor toon, allemaal geauthenticeerd met dezelfde sleutel tegen dezelfde api_base. De retrievalkant is aparte machinerie: de runner van STORM neemt een RM-module (You.com, Bing, en verschillende andere zoekbackends) met zijn eigen API-sleutel. Waar de taalmodellen naartoe wijzen veranderen, raakt niet aan hoe bronnen worden opgehaald.
Volledige instelling: vijf slots, één kwargs-dict.
Het werkende patroon spiegelt de eigen run-scripts van de repo: bouw de gedeelde kwargs eenmalig, construeer één LitellmModel per rol, en wijs ze toe via de setters van STORMWikiLMConfigs. De api_key mag elke naam hebben die je wilt aangezien je hem expliciet doorgeeft; het voorbeeld gebruikt zijn eigen variabele om duidelijk te maken dat dit geen OpenAI-accountcredential is. litellm eerbiedigt ook omgevingsvariabelen op providerniveau, en de openai-provider leest OPENAI_API_BASE, dus een omgevingsonly-override is mogelijk. Het expliciete kwargs-pad blijft de voorkeur: het is zichtbaar in de code die een bepaald artikel produceerde, het overleeft draaien op een machine met andere omgevingsstatus, en het maakt uitzonderingen per slot mogelijk als je ooit één fase naar een ander endpoint wilt sturen.
import os
from knowledge_storm import STORMWikiRunnerArguments, STORMWikiRunner, STORMWikiLMConfigs
from knowledge_storm.lm import LitellmModel
from knowledge_storm.rm import YouRM
openai_kwargs = {
"api_key": os.getenv("APISROUTER_API_KEY"),
"api_base": "https://api.apisrouter.com/v1",
"temperature": 1.0,
"top_p": 0.9,
}
fast = LitellmModel(model="openai/deepseek-v4-flash", max_tokens=500, **openai_kwargs)
strong = LitellmModel(model="openai/claude-sonnet-4-6", max_tokens=3000, **openai_kwargs)
lm_configs = STORMWikiLMConfigs()
lm_configs.set_conv_simulator_lm(fast)
lm_configs.set_question_asker_lm(fast)
lm_configs.set_outline_gen_lm(strong)
lm_configs.set_article_gen_lm(strong)
lm_configs.set_article_polish_lm(strong)
engine_args = STORMWikiRunnerArguments(output_dir="./results")
rm = YouRM(ydc_api_key=os.getenv("YDC_API_KEY"), k=engine_args.search_top_k)
runner = STORMWikiRunner(engine_args, lm_configs, rm)
runner.run(topic="Small modular reactors")Modellen kiezen per pipelinefase.
Behandel de vijf setters als een budgetknop, geen boilerplate. Upstream-richtlijnen zeggen al om snelle en sterke modellen te splitsen over fasen; een multi-vendor endpoint verbreedt gewoon het menu per fase. Verander één slot per keer tussen runs op hetzelfde onderwerp en diff de outputs, met het gebruikslogboek per sleutel dat elke configuratie prijst.
- conv_simulator_lm en question_asker_lm zijn de volumefasen: multi-turn gesimuleerde interviews over verschillende perspectieven per onderwerp. deepseek-v4-flash of een ander snel ID houdt de onderzoeksfase ervan af de uitgaven te domineren, en imperfect gebabbel is acceptabel omdat het notities voedt, geen proza.
- article_gen_lm is de vlaggenschipslot. Het schrijft lange, gestructureerde, geciteerde secties uit opgebouwd onderzoek, wat volgehouden generatiewerk is waar claude-sonnet-4-6 of gpt-5.5 zichtbaar beter presteert dan kleinere ID's.
- outline_gen_lm is weinig aanroepen met buitensporige hefboomwerking, dezelfde vorm als een planningsslot: een zwak overzicht begrenst het artikel ongeacht hoe goed de schrijver is. Het is de natuurlijke plek om claude-opus-4-7 te testen.
- article_polish_lm herschrijft voor vloeiendheid en verwijdert duplicatie over het samengestelde artikel, wat baat heeft bij een langecontext-ID; gemini-3.1-pro-preview is het waard om hier te benchmarken.
Betaal naar gebruik · onder officiële prijzen
Selected models are priced below official list prices. Exact input, output, cache, and per-request prices are shown for each model.
| Model | Officiële prijs | Onze prijs |
|---|---|---|
| DeepSeek V4 Flash | $0.14 / $0.28 per M | $0.10 / $0.30 per M |
| Claude Sonnet 4.6 | $3.00 / $15.00 per M | $2.40 / $12.00 per M |
| Claude Opus 4.7 | $5.00 / $25.00 per M | $4.00 / $20.00 per M |
| GPT-5.5 | $5.00 / $30.00 per M | $4.00 / $24.00 per M |
| Gemini 3.1 Pro Preview | $2.00 / $12.00 per M | $1.60 / $9.60 per M |
De faalmodi specifiek voor STORM.
Een kaal model-ID routeert door inferentie, niet via je api_base. litellm leest het voorvoegsel om een provider te kiezen, en een Claude-ID zonder voorvoegsel wordt afgeleid als een native Anthropic-aanroep, die dan om ANTHROPIC_API_KEY vraagt en je gateway volledig negeert. Elk ID op weg naar de gateway moet het voorvoegsel openai/ dragen; het voorvoegsel noemt het protocol, niet de leverancier. Eén achtergebleven slot. Elke LitellmModel legt zijn kwargs vast bij constructie. Als vier slots openai_kwargs delen en een vijfde ad hoc is gebouwd zonder api_base, post die slot stilletjes naar de standaard van de leverancier en faalt op auth, en de traceback noemt een pipelinefase in plaats van een configregel. Bouw elke slot uit dezelfde dict en deze bugklasse verdwijnt. Retriever-fouten die het endpoint de schuld krijgen. De onderzoeksfase heeft een werkende zoekbackend nodig; een ongeldige of uitgeputte retriever-sleutel (YDC_API_KEY, BING_SEARCH_API_KEY, of welke RM je ook koos) faalt runs tijdens informatievergaring. Die fase interleaved met LM-aanroepen, dus lees de traceback voor welke client een fout gooide voordat je de LM-config aanraakt. De secrets.toml van de demo is niet de config van je script. De Streamlit-demo leest secrets.toml; programmatische runs lezen wat je script ook doorgeeft. De ene bewerken terwijl de andere draait is een klassieke mismatch. max_tokens is ook per slot. De voorbeelden van STORM zetten kleine limieten op de snelle slots (500) en grotere op generatie (3000). Een slot naar een langvormig model wijzen zonder zijn max_tokens te verhogen, knipt secties stilletjes af, wat aanvoelt als een modelkwaliteitsprobleem maar een configgetal is.
Wie routeert STORM via een gateway.
- Teams die kennisrapporten genereren op volume (briefings, wiki-stijl interne docs, onderwerpprimers), waar de vijf-slot-splitsing kostenafstemming per fase echt geld waard maakt.
- Onderzoekers die pipelinecompositie bestuderen: welke fase baat heeft bij een sterker model is een empirische vraag, en één endpoint maakt het rooster van slot-modelcombinaties triviaal om op te sommen.
- Bouwers die Claude of Gemini draaien in de schrijfslots van een OpenAI-gevormde stack, zonder een leveranciers-SDK per modelfamilie toe te voegen.
- Iedereen die batches onderwerplijsten draait, waar het volume van de onderzoeksfase zich vermenigvuldigt over onderwerpen en het gebruikslogboek het kostenoverzicht per onderwerp wordt.
- Developers zonder toegang tot de facturering van een bepaalde leverancier. Toegang op basis van opwaarderen zonder kaartvereiste verwijdert de aanmeldingsafhankelijkheid per provider.
Verifieer het endpoint en debug het eerste artikel.
Lijst eerst de modellen van de gateway op: de string na openai/ in elke slot moet exact overeenkomen met een bediend ID. Fouten bij de eerste run volgen de pipelinevolgorde. Een authenticatiefout die Anthropic of Google noemt, betekent dat een ID zonder voorvoegsel naar een native provider routeerde; voeg openai/ toe. Een 401 van de gateway betekent dat de api_key in je kwargs niet de gatewaysleutel is. Een model-not-found-fout noemt de slot wiens ID een tikfout heeft. Fouten tijdens de onderzoeksfase die je zoekbackend noemen zijn retriever-credentials, geen LM-routering. En afgeknotte of vreemd korte artikelsecties zijn meestal een karig max_tokens op de generatieslot in plaats van iets stroomopwaarts. Een volledige STORM-run is een grote burst: gesimuleerde gesprekken over perspectieven, dan overzicht, generatie, en polijsten. Zodra er een is voltooid, toont de APIsRouter-console model per verzoek, tokenaantallen, en uitgaven, wat netjes mapt op de vijf slots en je precies vertelt welke fase je moet bijstellen voor de volgende batch onderwerpen.
curl -s https://api.apisrouter.com/v1/models \
-H "Authorization: Bearer $APISROUTER_API_KEY" | head -50Veelgestelde vragen
Hoe ondersteunt STORM een aangepast OpenAI-compatibel endpoint?
Via litellm. STORM bouwt elk LM als een LitellmModel, dat zijn constructor-kwargs samenvoegt in elke litellm.completion()-aanroep, en litellm accepteert api_base voor de openai-provider. Voeg api_base toe aan de openai_kwargs-dict en elke slot die eruit is gebouwd routeert naar de gateway.
Waarom hebben model-ID's het voorvoegsel openai/ nodig?
litellm kiest de provider op basis van het voorvoegsel. openai/claude-sonnet-4-6 betekent "spreek het OpenAI-chat-completions-protocol tegen mijn api_base met model claude-sonnet-4-6". Zonder het voorvoegsel leidt litellm de leverancier af uit de naam en routeert native, waarbij je endpoint wordt omzeild.
Kunnen verschillende STORM-fasen modellen van verschillende leveranciers gebruiken?
Ja. Elk van de vijf slots is een onafhankelijke LitellmModel, dus de gespreksimulator kan een DeepSeek-ID draaien terwijl artikelgeneratie Claude draait en polijsten GPT, allemaal via dezelfde api_base en sleutel. Upstream beveelt al aan om snelle en sterke modellen te splitsen over fasen.
Verandert de zoekretriever wanneer ik api_base wijzig?
Nee. Retrieval loopt via de RM-module die je doorgeeft aan STORMWikiRunner (You.com, Bing, en andere ondersteunde backends) met zijn eigen sleutel. LM-routering en bronretrieval zijn onafhankelijke systemen die in verschillende fasen van een run falen.
Is er een omgevingsvariabelenpad in plaats van kwargs?
litellm eerbiedigt variabelen op providerniveau, en de openai-provider leest OPENAI_API_BASE. Het werkt, maar het expliciete api_base-kwarg is reproduceerbaarder: het reist mee met het script, overleeft machines met andere omgevingsstatus, en staat uitzonderingen per slot toe.
Hoeveel tokens verbruikt één STORM-artikel?
De onderzoeksfase domineert: multi-perspectief gesimuleerde gesprekken vermenigvuldigen aanroepen voordat er een woord van het artikel bestaat, waarna generatie en polijsten lange output erbovenop toevoegen. Volledige runs komen vaak uit op honderdduizenden tokens, en de gebruiksweergave per sleutel toont de exacte splitsing per fase.