thinkn
  • Product
    Manifesto
    The reason we exist
    Founder Studioprivate beta
    Make better product decisions faster
    Belief SDKinvite only
    Add belief states to your AI system
    Request Access →Join the private beta waitlist
  • Docs
  • Pricing
  • FAQ
  • Docs
  • Pricing
  • FAQ
Sign In
Welcome
  • Hack Guide
  • Introduction
  • Install
  • Quickstart
  • FAQ
  • The Problem
  • Memory vs Beliefs
  • Drift
  • Examples
start/quickstart.mdx

Quickstart

Add beliefs to your agent in 3 steps — then run the test suite to see it live.

The hosted API is in private beta. Request access to get an API key.

The Loop

Every agent using beliefs follows the same cycle:

Create a belief state

1import Beliefs from 'beliefs'
2
3const beliefs = new Beliefs({
4  apiKey: process.env.BELIEFS_KEY,
5  namespace: 'quickstart',
6  writeScope: 'space',
7})

Before work — read what the agent believes

1const context = await beliefs.before(userMessage)

context.prompt is a JSON-serialized belief context you inject into your agent's system prompt. context.clarity is a 0-1 readiness score. context.moves are ranked next actions by expected information gain.

After work — feed the observation

1const result = await myAgent.run({ context: context.prompt })
2const delta = await beliefs.after(result.text)

The infrastructure extracts beliefs from the output, detects conflicts, updates confidence, and records provenance — automatically. delta.clarity tells you whether to keep investigating or act.

Three steps, repeated every turn.

Why this uses space scope

For a copy-paste quickstart, writeScope: 'space' is the simplest runnable setup. The SDK's default is writeScope: 'thread', which is better for chat apps but requires a bound thread via thread or beliefs.withThread(threadId).

What happens under the hood

Your agent's output is processed as an observation. Beliefs are extracted. New claims are merged with existing state by merging evidence from multiple sources. Conflicts are detected. Edges (supports, contradicts) are created. The ledger records every transition. Clarity and thinking moves are recomputed.

Run It

The fastest way to see beliefs in action is to run the quickstart test suite. It walks through 8 steps — seeding beliefs, extracting from agent output, detecting contradictions, resolving them, and querying the final world state.

Setup

1mkdir beliefs-quickstart && cd beliefs-quickstart
2npm init -y
3npm install beliefs vitest

Create the test

Create a file called quickstart.test.ts:

1import { afterAll, describe, expect, it } from 'vitest'
2import Beliefs from 'beliefs'
3
4const API_KEY = process.env.BELIEFS_KEY ?? ''
5const NAMESPACE = `quickstart-${Date.now()}`
6
7describe.skipIf(!API_KEY)('Quickstart: Beliefs SDK', () => {
8  const beliefs = new Beliefs({
9    apiKey: API_KEY,
10    namespace: NAMESPACE,
11    writeScope: 'space',
12  })
13
14  const clarityArc: Array<{ step: string; clarity: number }> = []
15
16  function trackClarity(step: string, clarity: number) {
17    clarityArc.push({ step, clarity })
18    console.log(`  clarity: ${clarity.toFixed(3)}`)
19  }
20
21  afterAll(() => {
22    if (clarityArc.length === 0) return
23    console.log('\n  Clarity Arc:')
24    for (const { step, clarity } of clarityArc) {
25      const bar = '█'.repeat(Math.round(clarity * 30))
26      console.log(`    ${step.padEnd(16)} ${bar} ${clarity.toFixed(3)}`)
27    }
28  })
29
30  // ── Step 1: Connect and verify empty state ────────────────────────
31
32  it('Step 1 — connect and verify empty state', async () => {
33    // On a fresh namespace there are no beliefs yet.
34    const context = await beliefs.before()
35
36    console.log('\n── Step 1: Empty State ──')
37    console.log(`  beliefs: ${context.beliefs.length}`)
38    console.log(`  goals:   ${context.goals.length}`)
39    console.log(`  gaps:    ${context.gaps.length}`)
40    trackClarity('1 empty', context.clarity)
41
42    expect(context.beliefs).toEqual([])
43    expect(context.prompt).toBeDefined()
44    expect(typeof context.clarity).toBe('number')
45  }, 30_000)
46
47  // ── Step 2: Seed knowledge ────────────────────────────────────────
48
49  it('Step 2 — set a goal, add claims, identify gaps', async () => {
50    // add() lets you explicitly seed claims, goals, and gaps.
51    const goalDelta = await beliefs.add(
52      'Determine total addressable market for AI developer tools',
53      { type: 'goal' },
54    )
55
56    await beliefs.add('AI developer tools market is valued at $4.2B', {
57      confidence: 0.8,
58    })
59    await beliefs.add('GitHub Copilot has dominant market share', {
60      confidence: 0.85,
61    })
62    await beliefs.add('Enterprise adoption is growing at 25% YoY', {
63      confidence: 0.6,
64      type: 'assumption',
65    })
66
67    await beliefs.add('Missing APAC market data', { type: 'gap' })
68    await beliefs.add('No competitive pricing analysis', { type: 'gap' })
69
70    const state = await beliefs.read()
71
72    console.log('\n── Step 2: Seeded Knowledge ──')
73    console.log(`  beliefs: ${state.beliefs.length}`)
74    console.log(`  goals:   ${state.goals.length}`)
75    console.log(`  gaps:    ${state.gaps.length}`)
76    for (const b of state.beliefs) {
77      console.log(`    [${b.confidence.toFixed(2)}] ${b.text.slice(0, 70)}`)
78    }
79    trackClarity('2 seeded', state.clarity)
80
81    expect(state.beliefs.length).toBeGreaterThan(0)
82    expect(goalDelta.state).toBeDefined()
83  }, 60_000)
84
85  // ── Step 3: LLM extraction from raw text ──────────────────────────
86
87  it('Step 3 — feed agent output, see automatic extraction', async () => {
88    // Pass raw agent output to after(). The infrastructure extracts
89    // beliefs automatically — no parsing, no schemas.
90    const agentOutput = `Based on my research into the European AI developer tools market:
91
92The European market accounts for approximately 28% of global AI dev tool
93revenue, roughly $1.18B. The EU AI Act is creating regulatory headwinds —
94enterprise procurement cycles have extended by 3-6 months as legal teams
95evaluate compliance requirements.
96
97Key findings:
98- UK leads European adoption at 35% of regional market share
99- Germany and France are growing fastest at 30% YoY
100- Scandinavian countries show highest per-developer spend
101- Eastern Europe is emerging as a low-cost development hub
102
103A notable gap: we still lack pricing data from major vendors for the
104European market specifically. The assumption that enterprise adoption is
105growing at 25% YoY appears to be accurate for the US but may understate
106European growth (closer to 30% in key markets).`
107
108    const delta = await beliefs.after(agentOutput)
109    const state = await beliefs.read()
110
111    console.log('\n── Step 3: LLM Extraction ──')
112    console.log(`  changes:   ${delta.changes.length}`)
113    console.log(`  readiness: ${delta.readiness}`)
114    console.log(`  total beliefs now: ${state.beliefs.length}`)
115    console.log('  newly extracted beliefs:')
116    for (const b of state.beliefs.slice(3, 8)) {
117      console.log(`    [${b.confidence.toFixed(2)}] ${b.text.slice(0, 70)}`)
118    }
119    if (state.beliefs.length > 8) {
120      console.log(`    ... and ${state.beliefs.length - 8} more`)
121    }
122    trackClarity('3 extracted', delta.clarity)
123
124    expect(state.beliefs.length).toBeGreaterThan(3)
125  }, 90_000)
126
127  // ── Step 4: Contradicting evidence ────────────────────────────────
128
129  it('Step 4 — feed contradicting data, see conflict detection', async () => {
130    // New evidence says the market is $6.8B — not the $4.2B we seeded.
131    // The system detects the conflict automatically.
132    const toolResult = JSON.stringify({
133      source: 'IDC Worldwide AI DevTools Tracker Q4 2025',
134      finding:
135        'Global AI developer tools market is valued at $6.8B, not $4.2B ' +
136        'as previously estimated. The discrepancy is due to the earlier ' +
137        'estimate excluding embedded AI features in traditional IDEs. ' +
138        'GitHub Copilot market share has declined to 32% as Cursor and ' +
139        'open-source alternatives gained ground.',
140      confidence: 'high',
141      methodology: 'Bottom-up survey of 2,400 enterprises across 18 countries',
142    })
143
144    const delta = await beliefs.after(toolResult, { tool: 'market_research_api' })
145
146    console.log('\n── Step 4: Contradiction ──')
147    console.log(`  changes:        ${delta.changes.length}`)
148    console.log(`  readiness:      ${delta.readiness}`)
149    console.log(`  beliefs:        ${delta.state.beliefs.length}`)
150    console.log(`  contradictions: ${delta.state.contradictions.length}`)
151    trackClarity('4 conflict', delta.clarity)
152
153    expect(delta.state).toBeDefined()
154    expect(delta.state.beliefs.length).toBeGreaterThan(0)
155  }, 60_000)
156
157  // ── Step 5: Resolve ───────────────────────────────────────────────
158
159  it('Step 5 — resolve contradictions and close gaps', async () => {
160    // High-confidence claims with evidence supersede lower-confidence ones.
161    // resolve() closes gaps.
162    await beliefs.add(
163      'Global AI developer tools market is valued at $6.8B (IDC Q4 2025)',
164      {
165        confidence: 0.95,
166        evidence: 'IDC Worldwide AI DevTools Tracker, bottom-up survey of 2,400 enterprises',
167      },
168    )
169
170    await beliefs.add('GitHub Copilot market share has declined to 32%', {
171      confidence: 0.9,
172      evidence: 'IDC Q4 2025 competitive landscape report',
173    })
174
175    const resolveDelta = await beliefs.resolve('No competitive pricing analysis')
176    const state = await beliefs.read()
177
178    console.log('\n── Step 5: Resolution ──')
179    console.log(`  beliefs: ${state.beliefs.length}`)
180    console.log(`  gaps:    ${state.gaps.length}`)
181    trackClarity('5 resolved', state.clarity)
182
183    expect(resolveDelta.state).toBeDefined()
184  }, 60_000)
185
186  // ── Step 6: Search ────────────────────────────────────────────────
187
188  it('Step 6 — search beliefs', async () => {
189    // search() finds beliefs by keyword, sorted by confidence.
190    const results = await beliefs.search('market')
191
192    console.log('\n── Step 6: Search "market" ──')
193    console.log(`  found: ${results.length}`)
194    for (const b of results.slice(0, 5)) {
195      console.log(`    [${b.confidence.toFixed(2)}] ${b.text.slice(0, 70)}`)
196    }
197
198    expect(results.length).toBeGreaterThan(0)
199    for (const b of results) {
200      expect(b.id).toBeDefined()
201      expect(b.text).toBeDefined()
202      expect(typeof b.confidence).toBe('number')
203    }
204  }, 30_000)
205
206  // ── Step 7: World state ───────────────────────────────────────────
207
208  it('Step 7 — read full world state', async () => {
209    // read() returns the complete epistemic snapshot: beliefs, goals,
210    // gaps, relationship edges, contradictions, clarity, and moves.
211    const world = await beliefs.read()
212
213    console.log('\n── Step 7: World State ──')
214    console.log(`  beliefs:        ${world.beliefs.length}`)
215    console.log(`  goals:          ${world.goals.length}`)
216    console.log(`  gaps:           ${world.gaps.length}`)
217    console.log(`  edges:          ${world.edges.length}`)
218    console.log(`  contradictions: ${world.contradictions.length}`)
219    console.log(`  clarity:        ${world.clarity.toFixed(3)}`)
220    console.log(`  moves:          ${world.moves.length}`)
221    trackClarity('7 final', world.clarity)
222
223    expect(world.beliefs.length).toBeGreaterThan(3)
224    expect(world.prompt).toBeDefined()
225    expect(world.clarity).toBeGreaterThanOrEqual(0)
226    expect(world.clarity).toBeLessThanOrEqual(1)
227  }, 30_000)
228
229  // ── Step 8: Trace ─────────────────────────────────────────────────
230
231  it('Step 8 — trace belief evolution history', async () => {
232    // trace() returns the audit trail — every belief transition with
233    // who changed it, when, and why.
234    const entries = await beliefs.trace()
235
236    console.log('\n── Step 8: Trace ──')
237    console.log(`  total entries: ${entries.length}`)
238    const byAction = entries.reduce((acc, e) => {
239      acc[e.action] = (acc[e.action] ?? 0) + 1
240      return acc
241    }, {} as Record<string, number>)
242    console.log(`  breakdown: ${Object.entries(byAction).map(([k, v]) => `${k}=${v}`).join(', ')}`)
243    console.log('  recent:')
244    for (const e of entries.slice(0, 6)) {
245      const conf = e.confidence
246        ? ` (${e.confidence.before?.toFixed(2) ?? '?'} → ${e.confidence.after?.toFixed(2) ?? '?'})`
247        : ''
248      console.log(`    ${e.action}${conf} | ${e.reason?.slice(0, 60) ?? '—'}`)
249    }
250
251    if (entries.length > 0) {
252      for (const entry of entries) {
253        expect(entry.action).toBeDefined()
254        expect(entry.timestamp).toBeDefined()
255      }
256    }
257  }, 30_000)
258})

Run it

1BELIEFS_KEY=bel_live_xxx npx vitest run quickstart

You'll see beliefs extracted from raw text, contradictions detected when conflicting data arrives, gaps closing as evidence comes in, and the clarity score rising across the session.

What the test covers

StepWhat it doesWhat you learn
1before() on empty stateSDK connects, clarity reads as low baseline (~0.25)
2add() claims, goals, gapsSeed explicit knowledge with confidence levels
3after(agentOutput)Raw text in, structured beliefs out — automatic extraction
4after(toolResult, { tool })Contradicting data triggers conflict detection
5add() + resolve()High-confidence evidence resolves conflicts and closes gaps
6search('market')Find beliefs by keyword, sorted by confidence
7read()Full world state: beliefs, edges, contradictions, clarity, moves
8trace()Audit trail of every belief transition

What You Get Back

beliefs.before() returns BeliefContext

1{
2  prompt: string,        // inject into your agent's system prompt
3  beliefs: Belief[],     // current beliefs
4  goals: string[],       // what the agent is pursuing
5  gaps: string[],        // what it doesn't know
6  clarity: number,       // 0-1 readiness to act
7  moves: Move[],         // ranked next actions
8}

beliefs.after() returns BeliefDelta

Every mutation (after, add, resolve) returns the same shape — what changed and the full updated state:

1{
2  changes: DeltaChange[],           // what was created/updated/removed
3  clarity: number,                  // 0-1 readiness to act
4  readiness: 'low' | 'medium' | 'high',
5  moves: Move[],                    // what to do next
6  state: WorldState,                // full world state after this mutation
7}

Types

1Belief      { id, text, confidence, type, label?, createdAt, updatedAt? }
2DeltaChange { action, beliefId, text, confidence?, reason? }
3Move        { action, target, reason, value, executor? }
4Edge        { type, source, target, confidence }

Full Example

1import Beliefs from 'beliefs'
2
3const beliefs = new Beliefs({
4  apiKey: process.env.BELIEFS_KEY,
5  namespace: 'full-example',
6  writeScope: 'space',
7})
8
9async function handleUserMessage(message: string) {
10  // 1. Get current belief context
11  const context = await beliefs.before(message)
12
13  // 2. Run your agent with belief-aware prompt
14  const result = await callLLM(context.prompt, message)
15
16  // 3. Feed the output — beliefs extracted automatically
17  const delta = await beliefs.after(result)
18
19  // See what was learned
20  for (const change of delta.changes) {
21    console.log(`${change.action}: "${change.text}" (${change.confidence?.after})`)
22  }
23
24  // Route on readiness
25  if (delta.readiness === 'high') {
26    return summarize(delta.state.beliefs)
27  }
28
29  // Keep investigating — follow the highest-value move
30  const next = delta.moves[0]
31  console.log(`Next: ${next?.action} — ${next?.reason}`)
32
33  return result
34}

Manual control

You can also assert specific beliefs directly: beliefs.add('Market is $4.2B', { confidence: 0.85 }). Every mutation returns the same BeliefDelta with the updated state. See the Core API.

PreviousInstall
NextFAQ

On this page

  • The Loop
  • Run It
  • Setup
  • Create the test
  • Run it
  • What the test covers
  • What You Get Back
  • beliefs.before() returns BeliefContext
  • beliefs.after() returns BeliefDelta
  • Types
  • Full Example