Beliefs → decisions

Make a decision, then call a tool

BeliefLang keeps the scores your workflow needs. A model updates them from new input. Rules use those scores to choose an action.

new message → belief snapshot → threshold rule → tool call

Each turn starts from the saved snapshot, so the model can update the decision state without reading every earlier message again.

Live API calls · 15 October 2026

What we measured

Two travel chats, 20 labeled turns, using gpt-6-luna.

20/20turns matched the labeled beliefs with either method
48%fewer reported tokens with saved beliefs
29%lower estimated model cost with saved beliefs
What the model readsLabel matchTokensEstimated cost
Chat history20/2015,668$0.001663
Saved beliefs + new message20/208,136$0.001175

The snapshot total includes the model calls that create and update it. This is a small scripted test. See the full method, older-model tests, and other results.

Jev result: Ordinary snapshot updates missed preference changes. A change-only update with jev-latest matched 20/20 mock tool choices twice on new scripted chats, using 2.7% less model input than full-history Jev. On earlier longer chats it saved 17.5%. This prototype turns explicit changes into hard yes/no values. See the Jev comparison.

Use a score to make a decision

The model estimates a score. The rule is deterministic: the same score and threshold produce the same tool call.

when confidence(intent.book_flight) > 0.9:
  call search_flights()

Settle each field separately

Choose a confidence threshold for each decision field. When its current value is certain enough, save it and omit that field from the next update. Keep updating uncertain fields. Reopen a settled field when new input could change it.

intent = book_flight (0.97) → settled
prefers_direct = uncertain (0.58) → update next turn

In a separate gpt-6-luna test, settled fields matched 20/20 labeled turns twice and used about 10% fewer tokens: 5,828 vs 6,494, then 5,809 vs 6,458. At a 0.90 threshold, 54 of 60 numeric field updates were omitted. See the method and limits.

Try it locally

Build the project, then run an example:

npm install
npm run build
node dist/src/cli.js run examples/intent.bel --trace

With OPENAI_API_KEY in your environment or local .env file, try the chat modes:

npm run chatbot
CHAT_MODE=full-history npm run chatbot
CHAT_MODE=coded npm run chatbot

For benchmark commands and details, see the README.

Live

Playground

Change the program and run it in your browser. The playground uses local example inference; live GPT and Jev calls run from the CLI.

Program

State

Variables

Observations

Actions

Trace

Language basics

Define beliefs, then act when a score passes a threshold:

belief intent exclusive closed {
  book_flight: 0.82
  book_hotel: 0.12
  unknown: 0.06
}

when confidence(intent.book_flight) > 0.7:
  call search_flights()

belief

Stores scores. exclusive means one main answer; multi allows several independent scores.

when

Checks a condition and runs one action. Use confidence(...) for a score and entropy(...) for uncertainty.

observe and infer

Record new input and ask an inference adapter to update beliefs. merge applies a belief patch.

Runtime API

Read state with getState() or confidence(path). Save and restore it with getBeliefSnapshot() and loadBeliefSnapshot(). Inspect decisions with getProvenance(), explainBelief(path), and --trace.

BeliefLang can infer with GPT or Jev. The integration and benchmark notes explain both adapters.