FutureSearch Logofuturesearch
  • Pricing
  • Research
  • Docs
  • Evals
  • Markets
  • Blog
  • Company
  • Try it for free
FutureSearch Logo

General inquiry? You can reach us at hello@futuresearch.ai.

Company

TeamCareersPressPrivacy PolicyTerms of Service

Developers

SDK DocsAPI ReferenceCase StudiesGitHubSupport

Integrations

Claude CodeCursorChatGPT CodexClaude.ai

Track Record

Trading ResultsAccuracy EvalsTournament Standings

Follow Us

X (Twitter)@dschwarz26LinkedIn
FutureSearchdocs
Frontier forecasting
Installation
  • All install methods
  • Claude.ai
  • Claude Code
  • Web App
  • Python SDK
  • Skill
Reference
  • API Key
  • forecast
  • decision
  • multi_agent
  • agent_map
  • World Modeling
  • Published Forecasts
  • MCP Server
  • Progress Monitoring
Guides
  • Turn Claude into an Accurate Forecaster
  • Forecast Outcomes for a List of Entities
  • Forecast Conditional Scenarios
  • Forecast Categorical and Threshold Questions
  • Find Profitable Prediction Market Trades
  • Research a Question with a Team of Agents
  • Add a Column via Web Research
  • Error Handling in FutureSearch: Failed Rows and Partial Results
Case Studies
  • Forecast a Decision: Grant Funding at Three Levels
  • Forecast a Decision: Which CEO Replacement Maximizes Share Price
  • Forecast a Binary Question End to End
  • Forecast a Date, Then Grade It
  • Forecast Categorical Outcomes for Two Stealth Labs
  • Forecast Conditional Scenarios for OpenAI's IPO
  • Forecast Anthropic and OpenAI IPOs: Dates and Valuations
  • Forecast a Sum-of-the-Parts SpaceX IPO Valuation
  • Forecast Founder Seed Valuations for AI Researchers
  • Find Startups Selling to Frontier AI Labs
  • Run 10,000 LLM Web Research Agents
FutureSearchby futuresearch
by futuresearch

Forecast Categorical and Threshold Questions

Not every question is yes or no. "Who wins?" has four answers. "How high does oil go?" has a ladder of them. Running each option as its own binary forecast produces probabilities that do not add up, because each run researches the question in isolation and none of them sees the others.

categorical and thresholded forecasts research all the options together in a single pass, so the probabilities come back coherent.

TypeQuestion shapeConstraint
categoricalWhich one of these outcomes?Options must be mutually exclusive and exhaustive. Probabilities sum to exactly 100.
thresholdedHow far past each threshold?One quantity, several cut-offs, ordered least strict to most strict. Probabilities do not sum to 100.

Both require effort_level="HIGH", which is the default. Both take their options from a named input column holding a JSON array, not from the question text.

Categorical: exhaustive or nothing

The exhaustiveness rule matters more than it looks. If your options are "Anthropic", "OpenAI" and "Google", and the real answer might be Meta, the probabilities are forced to sum to 100 across a set that excludes the truth, and every number is inflated. Add an explicit "Other" option whenever the list could be incomplete.

Two to fifty options are allowed, and they must be unique.

Worked examples we have published:

  • How many of four SpaceX bull-case milestones land?
  • How many named effort levels will the Gemini 3.5 Pro API expose?
  • How will Google ship its highest-capability Gemini 3.5-era model?

Thresholded: one quantity, several bars

Thresholds are for questions like "above $80, above $90, above $100". They are not mutually exclusive, so the probabilities are nested rather than summing to 100. Order them least strict to most strict and expect a monotonically falling series.

One threshold on its own is really a yes/no question. Use forecast_type="binary" for that and get a clean probability column instead.

Add FutureSearch to Claude Code if you haven't already:

claude mcp add futuresearch --scope project --transport http https://mcp.futuresearch.ai/mcp

Give Claude the options explicitly and it will build the array column:

Forecast how Google will deliver its highest-capability Gemini
3.5-era model as of 31 December 2026. The options are: a distinct
Ultra-tier model, Deep Think as the top tier, Pro as the top tier,
or something else.
Tool: futuresearch_forecast
├─ data: [{"question": "How will Google deliver its highest-capability...",
│          "options": ["Distinct Ultra-tier model",
│                      "Deep Think is the top tier",
│                      "Pro is the top tier",
│                      "Other"]}]
├─ forecast_type: "categorical"
├─ categories_field: "options"
└─ effort_level: "HIGH"

→ Submitted: 1 row for categorical forecasting.

Add the FutureSearch connector if you haven't already. List the options in the message and say that they are exhaustive:

Forecast which of these four outcomes happens. Treat the list as exhaustive and include an "Other" bucket.

Go to futuresearch.ai/app and spell out the options:

Forecast the probability of each outcome: Anthropic first, OpenAI first, neither by end of 2027.

For a batch, upload a CSV where one column holds each row's options as a JSON array.

pip install futuresearch
export FUTURESEARCH_API_KEY=your_key_here  # Get one at futuresearch.ai/app/api-key

Categorical. The options live in an input column as a JSON array of strings, named by categories_field:

import asyncio
import json
import pandas as pd
from futuresearch.ops import forecast

races = pd.DataFrame([
    {
        "question": (
            "As of 31 December 2026, how will Google deliver its single "
            "highest-capability Gemini 3.5-era model?"
        ),
        "options": json.dumps([
            "A distinct Ultra-tier model",
            "Deep Think is the top tier",
            "Pro is the top tier",
            "Other",
        ]),
    },
])

async def main():
    result = await forecast(
        input=races,
        forecast_type="categorical",
        categories_field="options",
        effort_level="HIGH",
    )
    for row in result.data.itertuples():
        print(json.loads(row.probabilities))

asyncio.run(main())

probabilities comes back as a JSON object mapping each outcome to its probability, summing to exactly 100, alongside a shared rationale.

Thresholded. Same shape, but the array holds cut-offs and is named by thresholds_field:

oil = pd.DataFrame([
    {
        "question": "What will Brent crude peak at during 2027, in USD?",
        "levels": json.dumps([80, 90, 100, 120]),
    },
])

result = await forecast(
    input=oil,
    forecast_type="thresholded",
    thresholds_field="levels",
    effort_level="HIGH",
)

probabilities maps each threshold to the probability of clearing it. Expect the series to fall as the thresholds get stricter.

Common mistakes

Options that overlap. "Under $100" and "Under $120" are not mutually exclusive, so they are thresholds, not categories. Picking the wrong type here is the most common error, and the sum-to-100 constraint will quietly distort the answer.

Forgetting "Other". If you can imagine a headline that satisfies none of your options, the list is not exhaustive.

Fifty near-identical buckets. The limit is fifty, but resolution beyond about ten options is usually noise. Coarser buckets give you numbers you can act on.


Built with FutureSearch. See the forecast documentation for all parameters and output formats. Related guides: Forecast Conditional Scenarios, Forecast Outcomes for a List of Entities, Turn Claude into an Accurate Forecaster.