Asking a language model to write you an article usually gets you a confident essay with invented facts and no receipts. STORM, from Stanford’s Open Virtual Assistant Lab, attacks that problem head on: it is an LLM system that writes Wikipedia-like articles from scratch, grounded in Internet search, with inline citations you can click. The acronym spells out the method — Synthesis of Topic Outlines through Retrieval and Multi-perspective Question Asking — and the two papers behind it (NAACL 2024 for STORM, EMNLP 2024 for the collaborative Co-STORM variant) are linked from the README, alongside a research preview that more than 70,000 people have tried. The code is MIT licensed Python, built on dspy, and organized so that every stage of the writing process is a swappable module rather than a tangled script.
The idea that makes STORM special is deceptively simple: the hard part of automated research is not retrieving documents, it is knowing which questions to ask. Directly prompting a model to ask questions produces shallow, generic ones. STORM instead discovers the perspectives experienced writers bring to a topic and simulates conversations between them and grounded experts, mining facts turn by turn before a single outline is drafted. As always in this series, what follows is an educational tour of published source code.
STORM at a glance: abstract contracts and shared data types on the left, pluggable models and search engines below, the original article-writing engine in the middle, and the collaborative discourse engine beside it.
Reading the overview from left to right:
- The STORM Wiki Runner — the four-stage orchestrator: research, outline, article, polish, each toggleable with a flag.
- The perspective finder — scrapes tables of contents from related Wikipedia pages to discover the viewpoints an article must cover.
- The conversation simulator — pits persona-driven writers against search-grounded topic experts in simulated interviews.
- The outline generator — turns mined conversations into a hierarchical table of contents with references.
- The article generator — writes section by section with inline citations, fanning out per subsection.
- The Co-STORM runner — a turn-managed discourse where experts, a moderator, and you debate a topic into a shared mind map.
- The language model adapters — litellm, OpenAI, Google, Ollama, and friends, so any provider can power any component.
- The retrieval modules — ten search backends from You.com and Bing to SearXNG and your own vector store.
Why You Need This
The first reason is that citations change everything about trust. Every claim in a STORM article carries a URL because the conversation simulator never lets the topic expert answer from memory alone: each turn generates concrete search queries, retrieves snippets, and asks the model to produce a grounded response with citation indexes. Then the article generator writes against the outline and the collected references, keeping the same citation discipline through every subsection. When you read the output, you are not trusting a model’s memory; you are reading what the model found, with the receipts attached.
The second reason is that the research insight is reusable far beyond articles. The perspective finder is a genuinely clever trick: instead of asking what questions matter, it fetches the tables of contents of Wikipedia pages on similar topics and derives from them the personas a seasoned writer would embody. Those personas then drive the interviews, which is how the system achieves depth and breadth that flat prompting never reaches. The same perspective-guided questioning pattern transfers directly to competitive analysis, due diligence, literature review, or anywhere you need to interrogate a topic from multiple sides before writing about it. It also explains the project’s name in code rather than in a paper: question asking is not an afterthought bolted onto retrieval, it is the centerpiece the whole architecture exists to serve.
The third reason is that the whole thing is an object lesson in modular design. The engine interfaces define knowledge curation, article generation, retrievers, and LM configuration as abstract contracts, and both engines are just compositions of implementations of those contracts. The model adapters and retrieval modules mean you can run the identical system on GPT-4o with Bing, on Gemini with Serper, or fully local with Ollama and SearXNG — the examples folder ships a ready-made script for nearly every combination. Different components can even use different models: a cheap one for simulating conversations, a stronger one for final writing, which is how the README recommends balancing cost and quality.
The detail view: the wiki engine's assembly line of personas, interviews, outline, and writing on one side; the Co-STORM agents, warm start, and mind map insertion on the other; shared contracts and data structures underneath.
The detail diagram shows how cleanly the two engines split. The STORM-wiki side is an assembly line: the runner feeds a topic through the perspective finder, the ConvSimulator runs interviews in parallel via the knowledge curation module, the outline generator drafts and revises a table of contents, and the article generator writes each section against the outline before the polisher adds a summary and strips duplication. Typed handoffs keep the stages honest — DialogueTurn, StormInformationTable, and StormArticle in the storm_dataclass module move between stages, and the shared dataclass defines ConversationTurn and KnowledgeBase with embeddings for the collaborative side.
The Co-STORM side is where the project gets philosophically interesting. Rather than producing a document in one shot, the Co-STORM runner hosts a discourse: a warm start bootstraps the conversation from a hierarchical outline, Co-STORM experts answer with grounded evidence, a moderator interjects with thought-provoking questions about information nobody has used yet, and you can steer at any moment with your own utterances. Everything lands in a mind map, a hierarchical concept structure shared between you and the system, which the README notes reduces mental load when the discourse runs long. When you are satisfied, one call reorganizes the knowledge base and generates the report. Underneath, the supporting cast keeps the discourse honest: a grounding module turns claims into search queries, a utility file manages turn order and citation mapping, and the logging wrapper traces every model call so a long collaborative session stays auditable.
From Install to a Finished Article
The package installs from PyPI as pip install knowledge-storm, or you can clone the git repository for full source access. Create a secrets.toml with your keys — at minimum a language model key and a search engine key, such as OPENAI_API_KEY plus BING_SEARCH_API_KEY — then run one of the example scripts: python examples/storm_examples/run_storm_wiki_gpt.py --output-dir results --retriever bing --do-research --do-generate-outline --do-generate-article --do-polish-article. A few minutes later the output directory holds the finished article in markdown, the outline, and the conversation logs, so you can audit exactly how every citation was earned. The do_ flags let you stop after the research or the outline stage and inspect the intermediate artifacts, which is the best way to learn how the stages compose.
Honest limits: the README is candid that output is not publication-ready — experienced editors find it most useful in the pre-writing stage, and you should expect to edit; it needs paid search API keys for the hosted retrievers, though local SearXNG or your own vector store close that gap; multi-stage generation burns real tokens, so budget for it; and results are only as good as the retriever’s coverage. The Streamlit demo under frontend keeps the barrier low, but this is developer tooling, not a polished consumer app. Still, as a study of how to make an LLM cite its work, and as a toolbox for your own research writing, it is one of the most instructive codebases in the genre. Enjoyed this post? Never miss out on future posts by following us