How it works

Send logic, not data.

Most agents let the model drive every step: reading raw data, deciding, calling a tool, reading more. It’s expensive and non-deterministic. OpenSymbolic narrows the model’s job to writing a plan, then runs that plan as real code. Here’s exactly how that works.

01 · The shift in control

The model plans. Code executes.

In a standard agent loop, the language model is in the driver’s seat the whole way through, so it re-reads the same documents every turn, improvises each step, and gives you a different answer to the same question. OpenSymbolic inverts that. The model writes a plan once, in code, against a fixed set of typed building blocks. Ordinary Python runs the plan (retrieval, filtering, extraction, calculation), and the model only ever sees the small, relevant result at the end. The heavy lifting is deterministic code, so it’s cheap, repeatable, and traceable.

PLAN~1K tokens
The model generates an execution plan.
You can read and approve it before anything runs.
EXECUTE0 model tokens
Python runs the plan against typed primitives.
Deterministic, repeatable, no model in the loop.
REASON~3K tokens
The model sees only the selected evidence.
It writes the answer from the facts it actually needs.
02 · The introspection boundary

The model never touches your raw data.

This is why it’s so much cheaper. During planning, the model works with variable names and short summaries, never raw page content. Documents stay in Python memory and move between steps as variables, whether that’s 100 rows or 100,000. Context grows ~0.5–2K tokens per step instead of the 5–30K a raw-data loop re-sends every iteration. In independent testing, this produced 86% fewer tokens with zero errors.

Same task. 15 tool calls vs. one plan.
Representative: final snippets supplied at pilot
standard_react.py~15 CALLS
# Standard ReAct: every step round-trips the model
# Re-sends a long system prompt + full history every call
for doc in retrieve("vendor_contracts"):
if "yes" in ask(f"Is {doc.id} relevant?"):
clause = ask(f"Extract penalty: {doc.text}")
amount = ask(f"Parse amount: {clause}")
if ask(f"Is {amount} over $50k?"):
flagged.append(doc.id)
 
# ~15 model calls · 67K tokens · $0.61
opensymbolic_plan.py1 PLAN
# model writes the plan once, code runs it
class RAGAgent(PlanExecute):
@decomposition(intent="Flag high-penalty vendor contracts")
def flag(self):
docs = self.retrieve("vendor_contracts")
clauses = self.extract(docs, field="penalty")
flagged = self.filter(clauses, amount > 50_000)
return self.rank(flagged, by="amount")
# 1 plan · 9.5K tokens · $0.08
The plan, executed: an annotated trace.
trace: flag_high_penalty_contractsillustrative asset
PLAN model writes 4-step plan ........... 1,042 tokens
─────────────────────────────────
step 1 docs = retrieve(...) → 128 docs · 0 tokens
step 2 clauses = extract(...) → 128 rows · 0 tokens
step 3 flagged = filter(...) → 11 rows · 0 tokens
step 4 answer = reason(flagged) → 2,980 tokens
─────────────────────────────────
TOTAL 4,022 tokens · $0.05 · 2 model calls
Nothing to hallucinate. The model writes the plan; primitives do the work.
03 · Three blueprints

One framework, three execution models. Pick the one that fits the problem.

PLANEXECUTE
Single-turn
The model plans once, Python executes.
Best for retrieval, extraction, and structured tasks.
DESIGNEXECUTE
Control flow
Adds if / for / while with built-in loop guards.
Best for conditional workflows and data pipelines.
GOALSEEKING
Iterative
Plan → execute → evaluate, looping until the goal is met.
Best for multi-hop reasoning, research, open-ended tasks.

All three share the same primitives, the same security model, and the same plan-then-execute core. Swap patterns without rewriting your agent.

04 · Provable answers

For logic, don’t guess. Prove.

For deductive and constraint problems, the model translates the question into formal logic and a theorem prover (Z3) checks it. The model handles language; the prover handles truth. On the FOLIO first-order-logic benchmark this reached 89.2% (near the 96% human bar) with a 100% plan-success rate, because a prover catches what a model would otherwise guess at.

premises → Z3 → verdict
premise contracts over $50k need VP sign-off
premise contract #4471 is valued at $82,000
─────────────────────────────
Z3 #4471 requires VP sign-off ✓ proven
05 · Security by design

Not guardrails. Structural guarantees.

Because the model plans over variable names and can only call approved functions, whole classes of risk are closed off by construction rather than by prompt.

01
Symbolic firewall
The model plans with variables, never raw content. Blocks indirect prompt injection by design.
02
Allowlisted capabilities
Only registered primitives can run. Default deny.
03
Mutation gating
Write operations pause for human approval before they execute.
04
Sandboxed execution
No eval, exec, or import; every plan is AST-validated before it runs.
05
Type enforcement
Wrong type is a hard fail, not a silent pass.
06
Complete audit trail
Every operation logged: what, args, who, when, result.
07
Data sovereignty
Run fully local / air-gapped, or route PII locally and reasoning to the cloud.
06 · The improvement loop

The improvement loop that actually closes.

Prompt engineering plateaus: past ~70% accuracy, every fix introduces a new regression. OpenSymbolic replaces prompt archaeology with a structural loop. Improvements are additive and measurable, and they don’t break what already worked. This is why 7 of 11 models hit 100% on TravelPlanner: the framework handles the hard part.

OBSERVE
A failure shows up in the trace.
DIAGNOSE
Find the real cause: “missing primitive,” not “tweak the prompt.”
ADD
Add a primitive or example. Change no existing code.
VERIFY
Re-run the failing case and the full suite.
Run it yourself

Don’t take our word for it.

The framework is open source: MIT, pip install opensymbolicai-core. Build a working agent in five minutes, read the generated plan, inspect the trace, see the token count. Swapping models is a one-line config change.