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
  • Forecasting a decision
  • multi_agent
  • agent_map
  • World Modeling
  • Published Forecasts
  • MCP Server
  • Progress Monitoring
Guides
  • Turn Claude into an Accurate Forecaster
  • Forecasting the outcomes of a decision
  • Forecast Outcomes for a List of Entities
  • Forecast Categorical and Threshold Questions
  • Find Profitable Prediction Market Trades
  • Research a Question with a Team of Agents
  • Add a Column via Web Research
  • Forecast Conditional Scenarios
  • 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

Forecasting the outcomes of a decision

decision() forecasts one outcome under each option of a decision. Each row is one outcome question, a column lists the options, and each option is forecast as its own hypothetical; the options are researched together. The decision can be yours or anyone else's.

The call

import asyncio
from pandas import DataFrame
from futuresearch.ops import decision


async def main():
    result = await decision(
        input=DataFrame([
            {
                "question": "What will this household spend in total on home energy, including any installation costs, from 2027 through 2036?",
                "option": [
                    "Install a heat pump next year, taking the available grant",
                    "Run the gas boiler until it fails, then replace it with whatever is standard then",
                ],
            },
        ]),
        context=(
            "The household owns and lives in a 142 square metre semi-detached house built in "
            "1996 in Bad Nauheim, Hesse, and in 2025 it paid about 2,500 euros for 21,400 "
            "kilowatt-hours of gas and about 1,330 euros for 3,900 kilowatt-hours of "
            "electricity. Its gas condensing boiler was installed in 2004 and has needed two "
            "repairs since 2023, and a heating firm in nearby Friedberg quoted 34,200 euros in "
            "August 2026 for an air to water heat pump with a hot water cylinder and three "
            "larger radiators."
        ),
        alternatives_field="option",
        forecast_type="numeric",
        output_field="energy_spend",
        units="EUR",
    )
    print(result.data[["percentiles", "rationale"]])


asyncio.run(main())

The output

{
  "percentiles": {
    "Install a heat pump next year, taking the available grant": {
      "p10": 43330, "p25": 48330, "p50": 53330, "p75": 59500, "p90": 67000
    },
    "Run the gas boiler until it fails, then replace it with whatever is standard then": {
      "p10": 45170, "p25": 52670, "p50": 61500, "p75": 71170, "p90": 84330
    }
  },
  "rationale": "Installing the heat pump next year costs an estimated €53,330 at the median over the 2027-2036 window, structurally outperforming the €61,500 median cost of running the gas boiler to failure. ..."
}

percentiles maps each option to its own distribution and rationale explains the differences; for a binary outcome the column is probabilities, one probability per option. The values need not sum to 100 or move in order. See the published run.

Context

context is one string for the whole call. Put in it what the forecaster cannot look up about who is deciding, such as size, money, dates and constraints, never a number from an earlier forecast, and nothing that is public.

result = await decision(
    input=DataFrame([
        {
            "question": "How many paying subscribers will the company have twelve months from now?",
            "price": [
                "Leave the price at $20 a month",
                "Raise the price to $29 a month for new customers only",
                "Raise the price to $29 a month for everyone, including existing subscribers",
            ],
        },
    ]),
    context=None,
    alternatives_field="price",
    forecast_type="numeric",
    output_field="paying_subscribers",
    units="subscribers",
)

Holding the price comes back p10 to p90 of 660 to 22,000 subscribers: the run without context.

The same call, with two sentences about the company:

    context=(
        "Lessonpost is a scheduling, lesson notes and invoicing web app for independent "
        "music teachers, launched in March 2024, and in September 2026 it has 1,840 "
        "subscribers paying 20 dollars a month, which is 36,800 dollars of monthly "
        "recurring revenue. Gross subscriber churn has averaged 3.4 percent a month over "
        "the past year and about 95 new paid subscriptions start each month."
    ),

Holding the price now comes back 1,900 to 2,480: the run with context.

Several outcomes of one decision

Send one row per outcome, each row listing the same options.

rows = DataFrame([
    {
        "question": "How many sitting parliamentarians will be listed on ControlAI's campaign statement on December 31, 2028?",
        "grant": ["$0 (no grant)", "$250k", "$1M"],
    },
    {
        "question": "How many sitting parliamentarians will be listed on ControlAI's campaign statement on December 31, 2030?",
        "grant": ["$0 (no grant)", "$250k", "$1M"],
    },
])

Outcomes of different types, a date and a number for instance, need separate calls today.

Someone else's decision

The decider can be a company, a regulator or a government.

result = await decision(
    input=DataFrame([
        {
            "question": "By what percentage will weekday vehicle entries into the charging zone fall during the first full year of operation, compared with the year before?",
            "charge": [
                "Introduce no charge, leave the zone as it is",
                "Charge $9 per entry on weekdays between 6am and 8pm",
                "Charge $15 per entry on weekdays between 6am and 8pm",
                "Charge $9 at peak hours only, free at other times",
            ],
        },
    ]),
    context=(
        "The city is Chicago, and the zone is the central cordon bounded by Lake Michigan "
        "on the east, Chicago Avenue on the north, Halsted Street on the west and "
        "Roosevelt Road on the south, which about 360,000 vehicles enter on an average "
        "weekday. Chicago Transit Authority buses and trains carried 319.2 million rides "
        "in 2025 and Metra commuter rail carried 38.1 million, and all eleven Metra lines "
        "end at four downtown terminals inside or on the edge of that cordon."
    ),
    alternatives_field="charge",
    forecast_type="numeric",
    output_field="entry_reduction",
    units="percent",
)

Weekday entries fall 0 percent under no charge, 12.5 under $9, 17.8 under $15 and 7.0 under $9 at peak only: the published run. For a third party, context carries the terms of the decision, when it is taken and what stays fixed, rather than facts about them. If nobody decides the premise, use a conditional forecast instead.

When the options come back level

Cutting, holding or raising rates at the Fed's next meeting gives unemployment in December 2028 of 4.29, 4.27 and 4.31 percent (the run). The ten-year yield a month after the meeting comes back 5.11, 4.95 and 4.94 percent (the run). A level result is an answer, and the same decision can matter for a nearer outcome.

When something looks wrong

Wrong size. The forecaster did not know your scale and picked a typical one. Add two sentences to context: who you are and how big.

Ranges overlap. Read the rationale for what dominates instead, then ask for a nearer or narrower outcome if you need numbers that separate. Boeing's 2029 earnings per share came back at $7.10 if the board keeps its chief executive and $5.90 if it replaces them, with both ranges running from about $0 to $14 (the run).

A date comes back as "never". Asked in which year Boeing next outdelivers Airbus if it commits to a clean-sheet jet, the medians landed in the 2040s and the p90 was "never" under both options. Read that as: this may not happen under either option, so ask for a milestone that will arrive, or a quantity at a date.

The forecast disputes a fact you gave. It checks what you pass, so check your dates and names. An invented organization whose name is real will pull in the real one's facts.

The forecast is about the world, not about you. "What will energy prices be?" is the same under every option; "what will we spend?" is not. Point the outcome at whoever is deciding.

The options do not compare. They were run in separate calls, or one of them belongs to a different decider. Put every option in one call, and keep to one decider and one act.

It ran a conditional forecast. In the app, say "we're deciding" and list the options; in code, use decision() with alternatives_field, not forecast() with condition.

Two runs disagree. Runs vary by a few percent on a number and a few points on a probability, so repeat the run before trusting a gap that small.

Related

  • Forecasting a decision: parameters, outcome shapes and intervention assumptions.
  • Case studies: grant funding at three levels and Which CEO Replacement Maximizes Share Price.
  • How We Can Prevent Rogue Agents: four decisions by OpenAI, Anthropic and the US government.