Models

Build with Beam on Token Factory

Make your first calls to Reflection AI's Beam, a 501B open-weight coding and agent model, through the Token Factory OpenAI-compatible API, then wire it into a coding agent.

Build it with an agent

Paste into Claude Code, Cursor, or any coding agent — it builds the recipe for you.

Build a small, production-minded Python application that calls Reflection AI's Beam model through the Nebius Token Factory OpenAI-compatible chat completions API. Deliver `app.py`, `requirements.txt`, a `Dockerfile`, a `.dockerignore`, pytest tests under `tests/`, and a `README.md`.

Read the credential from `NEBIUS_API_KEY`, the API base URL from `NEBIUS_BASE_URL` (default `https://api.tokenfactory.nebius.com/v1`), and the model ID from `NEBIUS_MODEL` (default `reflection/beam`); never print or commit the credential. The application must expose one tool to the model, `run_tests`, which runs the project's own pytest suite and returns the summary line, and must implement the full tool-call loop: send the user task, execute any tool calls the model returns, append the assistant turn to the history including its `reasoning_content` field (Beam requires earlier reasoning to be sent back), append each result as a `tool` message with the matching `tool_call_id`, and repeat until the model answers without a tool call. Accept an optional `BEAM_REASONING_EFFORT` variable and pass it through as the `reasoning_effort` request field when set.

The container command `python app.py` must run one task ("report whether the test suite passes and how many tests ran"), exit zero, and print the final answer prefixed exactly with `Beam response:`. Tests must cover the loop with a fake client and must not call the network. Document local `.venv` setup, run the tests, then run the application once. Include clear verification, troubleshooting, Docker, and cleanup instructions, and state in the README which reasoning effort was used and the token usage of the run.

Recipe

Beam is Reflection AI’s first open-weight model: a sparse mixture-of-experts with 501 billion total parameters and 23 billion active, built for coding and agentic work and released under Apache 2.0. Nebius Token Factory serves it from day one, so you can call it through the same OpenAI-compatible API you already use, with no weights to download and no GPUs to provision.

This cookbook takes you from an API key to a working Beam call in a few minutes, shows the request settings that matter for an agent model, and ends with Beam driving a coding agent against a real repository.

What Beam is good at

Reflection positions Beam as a workhorse for enterprise coding and agentic workloads. The numbers below are Reflection’s own, from the benchmark tables in the Beam announcement as updated on October 8, 2026. Treat them as the vendor’s claims until you have run your own evaluation.

Area Benchmark Beam
Coding SWE-bench Verified 80.9
Coding SWE-bench Pro v1 65.5
Coding Terminal Bench v2.1 80.1
Reasoning AIME 2026 97.8
Reasoning GPQA Diamond 90.5
Tools and search MCP Atlas 78.7
Tools and search BrowseComp, with context management 77.4
Long context LongBench v2 65.5
Instruction following IFBench 79.7

A few facts that shape how you use it:

  • Text only. Beam reads and writes text. It can reason about images, audio, or files only when something else has turned them into text first.
  • Long context. Reflection reports an effective context length of 1M tokens after midtraining. The hosted limit on Token Factory may be lower; check the catalog entry before you plan around it.
  • Reasoning effort. Beam was trained with a controllable length penalty and exposes a user-facing reasoning effort setting. Lower effort is cheaper and faster; higher effort spends more output tokens thinking before it answers.
  • Compute efficiency. Reflection’s estimate is that Beam matches GLM 5.2 on advanced reasoning while using three to four times less inference compute, because only 23B parameters are active per token. That is an estimate from FLOPs, not a measured bill. Your Token Factory cost is what the catalog price says it is.

Prerequisites

  • A Nebius Token Factory account and an API key with access to Beam. Builder Program members get credits that cover this cookbook many times over.
  • Python 3.10 or newer, or any HTTP client. The examples use curl and the openai Python package.
  • The Beam model ID from the Token Factory model catalog. On Token Factory it is reflection/beam, with a hosted context of 1M tokens and a list price of $0.25 per 1M input tokens and $1.00 per 1M output tokens. Those values were checked on October 16, 2026 and can change, so confirm them on the catalog page before you plan a budget around them.

Store the key in an environment variable. Never paste it into a notebook or commit it.

export NEBIUS_API_KEY="your-key"
export NEBIUS_BASE_URL="https://api.tokenfactory.nebius.com/v1"
export NEBIUS_MODEL="reflection/beam"

Your first Beam call

Token Factory speaks the OpenAI chat completions protocol, so the first request is one curl.

curl "$NEBIUS_BASE_URL/chat/completions" \
  -H "Authorization: Bearer $NEBIUS_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{
    \"model\": \"$NEBIUS_MODEL\",
    \"messages\": [
      {\"role\": \"user\", \"content\": \"Write a Python function that parses an ISO 8601 duration like PT1H30M into seconds. Include three pytest cases.\"}
    ],
    \"max_tokens\": 6000
  }"

The token cap is deliberately generous. Beam reasons before it answers, and at the default effort this prompt spent about 1,500 tokens thinking before writing a 600-token answer. A cap of 1,500 returns finish_reason: "length" with empty content and all of the budget gone to reasoning.

The response is a standard chat completion. The function and tests are in choices[0].message.content, and usage tells you what the call cost in tokens. Beam thinks before it answers, and Token Factory returns that thinking separately in choices[0].message.reasoning_content, so the visible answer stays clean. Keep that field: you will need to send it back on multi-turn calls, as the next section explains.

The same call from Python, using the official OpenAI client pointed at Token Factory:

import os
from openai import OpenAI

client = OpenAI(
    base_url=os.environ["NEBIUS_BASE_URL"],
    api_key=os.environ["NEBIUS_API_KEY"],
)

response = client.chat.completions.create(
    model=os.environ["NEBIUS_MODEL"],
    messages=[
        {
            "role": "user",
            "content": "Write a Python function that parses an ISO 8601 duration like PT1H30M into seconds. Include three pytest cases.",
        }
    ],
    max_tokens=6000,
)

print(response.choices[0].message.content)
print(response.usage)

Settings that matter for an agent model

Beam is tuned for multi-step work, so the request shape matters more than it does for a chat model.

Set reasoning effort on purpose. Reflection trained Beam with a user-facing reasoning effort control, passed as the reasoning_effort request field. Token Factory accepts the named levels none, minimal, low, medium, high, xhigh, and max, and rejects numbers with a 422. Start low for routine edits and raise it for planning, debugging, or anything where a wrong answer is expensive. On the duration-parser prompt above, low used about 1,200 reasoning tokens, medium about 1,000, and the default about 1,500, so the levels shift the budget rather than switch thinking off. The OpenAI Python client does not know the field, so it goes through extra_body.

response = client.chat.completions.create(
    model=os.environ["NEBIUS_MODEL"],
    messages=messages,
    max_tokens=4000,
    extra_body={"reasoning_effort": "high"},
)

Send the reasoning back on every turn. Beam’s quality drops when an earlier assistant turn arrives without the reasoning that produced it. Reflection’s reference serving stack rejects such requests outright; Token Factory accepts them and answers, so nothing will tell you the context is degraded. When you append an assistant message to the history, include its reasoning_content alongside content and tool_calls. Most agent frameworks drop that field by default, so check yours before you blame the model.

message = response.choices[0].message
messages.append(
    {
        "role": "assistant",
        "content": message.content,
        "tool_calls": [call.model_dump() for call in message.tool_calls or []],
        "reasoning_content": message.reasoning_content,
    }
)

Budget output tokens, not just input. Reasoning tokens count as output. A high-effort call on a hard problem can produce several thousand output tokens before the visible answer. Set max_tokens high enough that the answer is not cut off, and watch usage.completion_tokens in your logs.

Use tool calls for anything that touches the world. Beam scores well on tool-use benchmarks because it was trained to call tools rather than guess. Give it real tools through the standard tools parameter and let it decide when to use them.

tools = [
    {
        "type": "function",
        "function": {
            "name": "run_tests",
            "description": "Run the project's pytest suite and return the summary line and any failures.",
            "parameters": {"type": "object", "properties": {}, "required": []},
        },
    }
]

response = client.chat.completions.create(
    model=os.environ["NEBIUS_MODEL"],
    messages=[
        {"role": "system", "content": "You are fixing a failing test suite. Run the tests before and after every change."},
        {"role": "user", "content": "test_parse_duration fails on PT0S. Fix it."},
    ],
    tools=tools,
    max_tokens=4000,
)

message = response.choices[0].message
if message.tool_calls:
    for call in message.tool_calls:
        print(call.function.name, call.function.arguments)

A real loop executes each tool call, appends the assistant turn with its reasoning and then the result as a tool message, and calls the model again until it answers without requesting a tool. Handle names you did not declare: in testing, Beam followed run_tests with a call to bash, a tool it was never given. Return a tool message saying the tool does not exist and the model picks a declared one on the next turn. The first agent on Nebius cookbook walks through that loop in full.

Keep the long context for what needs it. A million tokens of context does not mean you should send a million tokens. Sending a whole repository on every turn is slow and expensive. Send the files the task touches, and let the model ask for more through a read_file tool.

Drive a coding agent with Beam

The fastest way to see what Beam can do on real code is to put it behind a coding agent. Any agent that supports OpenAI-compatible providers works. This example uses OpenCode, which reads its provider configuration from a JSON file.

Add Token Factory as a provider in ~/.config/opencode/opencode.json:

{
  "$schema": "https://opencode.ai/config.json",
  "provider": {
    "nebius": {
      "npm": "@ai-sdk/openai-compatible",
      "name": "Nebius Token Factory",
      "options": {
        "baseURL": "https://api.tokenfactory.nebius.com/v1",
        "apiKey": "{env:NEBIUS_API_KEY}"
      },
      "models": {
        "reflection/beam": {
          "name": "Beam"
        }
      }
    }
  }
}

Then open a repository and point the agent at Beam:

cd your-project
opencode --model nebius/reflection/beam

Give it a task that needs more than one step, such as “add input validation to the signup endpoint and cover it with tests,” and watch it read files, edit, run the tests, and iterate. The OpenCode on Token Factory cookbook has the full setup, including other agents.

Verify the result

You have a working setup when all three of these are true:

  1. The curl call returns HTTP 200 with a chat completion whose model field names Beam and whose usage block has nonzero completion_tokens.
  2. The Python tool-call example prints run_tests and an empty-object argument string, which shows Beam chose to run the tests before editing.
  3. The Token Factory console lists the requests against Beam under your project’s usage.

Measured on October 16, 2026, the first call above at default effort returned in 5.8 seconds with 75 prompt tokens and 2,101 completion tokens, 1,478 of them reasoning, for $0.0021 at list price. The tool-call turns were far cheaper, under 60 completion tokens each and under a second. Reasoning tokens are billed as output and show up under usage.completion_tokens_details.reasoning_tokens, so watch that field for a few runs before you estimate a budget.

Troubleshooting

  • 404 or model not found. The model ID is wrong or your key does not yet have access. Copy the ID exactly from the catalog page and confirm the key belongs to a project with Beam enabled.
  • 401. The key is missing or the Authorization header is malformed. Check that NEBIUS_API_KEY is exported in the shell you are running from.
  • Empty content with finish_reason: "length". The whole token budget went to reasoning. Raise max_tokens well above what you expect the answer to need, or lower the effort.
  • Slow first token at high effort. Expected. The model is thinking before it answers. Stream the response if you want to show progress, and use lower effort for interactive work.
  • The agent loops on the same tool call. Make sure you are appending the tool result as a tool message with the matching tool_call_id. Without it the model never sees the outcome.
  • Answers get worse as a conversation grows. Check that every assistant message in your history still carries its reasoning_content. If your framework strips it, look for a setting that preserves reasoning fields.

Clean up

Nothing persists on Nebius from this cookbook. Unset the variables when you are done, and rotate the key if it was ever printed.

unset NEBIUS_API_KEY NEBIUS_BASE_URL NEBIUS_MODEL

Going further