ARCANE · System 1 model
ARC 1: Grounded Decisions Without Generation
ARCANE's 1.3M-parameter System 1 model turns a request and schema into typed tool calls, extracted fields, and classifications in 2.5 milliseconds on a standard CPU.
Learned probes resonate with the input, then return a bounded decision with calibrated confidence and abstention. Extracted values are copied from evidence instead of invented through generation. ARC 1 ships as one 0.77 MB .rcn file under the MIT license.
Try it live
Runs the real model on a live server. Pick an example or type your own request. Switch the harness to + Hippocampus to give ARC 1 a memory of examples: the New tools scene uses tools it never trained on, taught by a few examples instead of fine-tuning. How Hippocampus works
Lights and weather, two tools to choose between
What it does
ARC 1 can run a bounded RSAA perception loop before a decision is committed. Higher perception states align lower states, then every tool, argument, option, and label listens to the resulting field in 3 short binding cycles. Matching probes open a spiking gate and readouts return typed results directly, with no decoding loop. The deployed checkpoint defaults to RSAA off because its same-checkpoint evaluation favored the legacy path.
Schema as input
Tools, fields, and labels are passed with each request. Changing them needs no retraining.
Copies, never invents
Text values are spans of your input; labels come from your list.
Abstains
When no tool fits, it returns no call instead of guessing.
Calibrated confidence
Stated confidence tracks real accuracy, so a threshold can decide when to ask a person.
Built from ARCANE parts: ResonantChannelMixer, FieldResonance, and the GSER gate.
Architecture
ARC 1 uses Resonant Schema Binding with optional RSAA alignment. The request and every schema element go through the same perception hierarchy; bounded, state-only alignment can use higher layers as feedback and re-evaluate the current input with fixed weights. Each schema element becomes a probe that binds in 3 shared-weight cycles, and four readouts are taken from the settled probes. Nothing is decoded token by token.
Fire, anchor and select each have a temperature fitted on held-out data, which is what makes the reported confidence meaningful. RSAA reports initial divergence, final divergence, and per-example steps; the model caps alignment at two cycles. On this checkpoint, neither aligned profile passed the replacement gate, so zero is the production default. The live controls expose the measured profiles without presenting them as an accuracy gain.
Accuracy
Measured mostly on held-out synthetic examples, including tool values never seen in training. One check uses real text, below.
98.3%
right tool
295 of 300 requests
86.0%
exact call, tool and arguments
258 of 300 requests
96.6%
extraction F1
150 texts
100.0%
correct abstention
no-tool requests
Expected calibration error on tool decisions is 0.6% over 749 test decisions. Full-call and label calibration has not been measured.
On 600 real utterances from CLINC150, for intents that were left out of every training set, it picked the right one of 5 labels 57.7% of the time (chance is 20.0%). Before the language distillation described below, the same check scored about 38%.
How it was trained
ARC 1 starts with no language knowledge, so a frozen Qwen3-Embedding-0.6B teaches it offline which texts mean the same thing. The teacher is not in the download and is never run at inference, so the size and speed are unchanged.
- Contrastive pre-training. Each request is pulled toward its tool or intent and pushed away from the others (35k pairs from the synthetic tools, CLINC150 and Banking77), while its vectors learn to match the teacher's sense of similarity.
- Hard negatives. The same, with the teacher's nearest wrong answers added as negatives.
- Multi-task training with replay. The usual tool, extraction and label losses, with 40% of each step replaying stage 1 so the new knowledge is not forgotten.
The trade-off: against the previous checkpoint this gains about 19 points on real phrasings and 31 points on classifying requests for unseen tools, and gives up about 6 points on exact tool calls and fully correct extracted records. Recipe and commands are in the repository README.
Limitations
Unseen tools
Right tool 49.3%, exact call 38.7% (150 requests). New kinds of tools need training examples.
Weak categories
Classification is 74.7% overall; feed ranking (50.0%), product topics (54.5%) and search intent (58.3%) are weakest, on small subsets.
Grounded is not correct
Values are copied from the request but can land in the wrong field. Required details the user never gave are still filled, and option lists always return a closest choice. Validate before acting.
Mostly synthetic test data
Most scores come from generated held-out examples, not real traffic. The one real-text check is 600 CLINC150 utterances in a five-way choice.
Scope
English only, inputs cut at 160 tokens, each tool called at most once per request, only the light language knowledge distilled from a small text encoder and no world knowledge, and no chat replies.
Comparison
| Chat-style LLM | Laya AI | ARC 1 | |
|---|---|---|---|
| Size | Billions of parameters | 421M parameters | 1.32M parameters |
| Download | Gigabytes | About 808 MB | 0.77 MB |
| Hardware | GPU or paid API | GPU, 32.8 ms | CPU,2.5 ms median |
| Tool calls and extraction | Generated, values can be invented | Not offered | Built in, values copied from input |
| Calibration error | Varies | 8.1% (its own tasks) | 0.6% on tool decisions |
Laya AI figures are from its public page (English checkpoint, checked September 2026), measured on its own tasks and a GPU. This compares size and capability, not accuracy on a shared dataset.
Get started
Needs fine-tuning or Hippocampus. This download is a base checkpoint, not a finished model. Fine-tune it on your own data and tools, or give it a few decided examples of each through the Hippocampus harness, and test it on your own requests before relying on it in your application.
Free, with no sign-in. If you find ARC 1 useful, a star on GitHub is appreciated.
pip install gpbacay-arcaneimport gpbacay_arcane as arcanefrom gpbacay_arcane import ToolParam, ToolSpecagent = arcane.load_arc1() # bundled arc1-tiny.rcn; load_arc1("my.rcn") for your own# Call a toolweather = ToolSpec("get_weather", "Get the current weather for a city.", [ToolParam("city", description="City name")])agent.run("is it raining in Tokyo?", tools=[weather])# {"function_calls": [{"name": "get_weather", "arguments": {"city": "Tokyo"}}], ...}# Pull out detailsagent.extract("My name is Maria Santos and I live in Cebu", {"name": "Person name", "city": "City"})# {"record": {"name": "Maria Santos", "city": "Cebu"}, ...}# Sort into labelsagent.classify("the headphones sound amazing", ["positive", "negative", "neutral"])# {"label": "positive", "confidence": ..., "distribution": {...}}On a server, it runs the same model in a local Python process, so the Python package must be installed too. To run with no Python at all, use the browser build below.
pip install gpbacay-arcanenpm install gpbacay-arcaneconst { load } = require("gpbacay-arcane");const agent = await load(); // load({ python: "path/to/python", model: "my.rcn" }) to overrideawait agent.run("is it raining in Tokyo?", [ { name: "get_weather", description: "Get the current weather for a city.", parameters: [{ name: "city", description: "City name" }] },]);// { function_calls: [{ name: "get_weather", arguments: { city: "Tokyo" } }], ... }await agent.extract("My name is Maria Santos and I live in Cebu", { name: "Person name", city: "City" });await agent.classify("the headphones sound amazing", ["positive", "negative", "neutral"]);await agent.embed("hello");agent.close();gpbacay-arcane/web runs ARC 1 client-side with onnxruntime-web (WebAssembly), with no server and no Python. The 5.5 MB model is fetched once and cached by the browser. It has the same API as the Node build and returns the same results, and calls take about 10 to 20 ms once loaded.
npm install gpbacay-arcane onnxruntime-web"use client"; // Next.js: use it in a client componentimport { load } from "gpbacay-arcane/web";const agent = await load(); // once, e.g. in useEffectconst r = await agent.run("is it raining in Tokyo?", [ { name: "get_weather", description: "Get the current weather for a city.", parameters: [{ name: "city", description: "City name" }] },]);// r.function_calls -> [{ name: "get_weather", arguments: { city: "Tokyo" } }]await agent.extract("My name is Maria Santos and I live in Cebu", { name: "Person name", city: "City" });await agent.classify("the headphones sound amazing", ["positive", "negative", "neutral"]);await agent.embed("hello");To serve the files yourself, use load({ model: "/arc1/arc1.onnx", config: "/arc1/arc1.json", wasmPaths: "/ort/" }). To export your own model, run python examples/export_arc1_onnx.py --model your.rcn. Binding cycles are fixed at export time.
Need open-ended replies too? Pair ARC 1 with the ARCANE small language model.
Finetuning
The downloaded arc1-tiny.rcn is a base checkpoint. Finetuning teaches it your own tools, fields and labels. Training runs from the source repository and learns from examples it generates out of tool definitions you write, so you describe each tool once and it produces the phrasings. It needs Python and TensorFlow. The download remains the validated zero-cycle artifact; the optional live RSAA profiles did not pass the replacement gate for these weights.
1. Set up the repository
git clone https://github.com/gpbacay/gpbacay_arcanecd gpbacay_arcanepip install -e .2. Unpack the download into trainable files
An .rcn file is for running the model. Convert it back to weights and a tokenizer so training can continue from it. The file names below are the ones the trainer looks for.
import osfrom gpbacay_arcane.rcn import load_rcnos.makedirs("Models", exist_ok=True)model, tokenizer, _ = load_rcn("arc1-tiny.rcn")model.save_weights("Models/arc1_arc1_tiny.weights.h5")tokenizer.save("Models/arc1_arc1_tiny_tokenizer.json")3. Describe your tools
Open gpbacay_arcane/arc1_data.py and add a ToolDef to the list in build_tool_library(). Give it a few descriptions, its parameters, and 10 or more phrasings with {param} placeholders. A SlotDef says how each value is written in text.
ToolDef( "book_table", ["Reserve a table at a restaurant.", "Make a dinner reservation."], [P("restaurant", "string", "Restaurant name"), P("guests", "integer", "Party size")], ["book a table at {restaurant} for {guests}", "reserve {restaurant}, {guests} people", "table for {guests} at {restaurant} please"], {"restaurant": SlotDef(choice_of(["Luigi's", "Sushi Zen", "The Anchor", "Casa Verde"])), "guests": SlotDef(lambda r, s: _int_surface(r, 1, 12), _int)}, domain="food",),choice_of takes a fixed list of values. The file also has pool, which splits values into training and held-out sets so the evaluation in step 5 can test values the model has not seen.
4. Train from the checkpoint
python examples/train_arc1.py --preset arc1-tiny --resume --steps 1500 --learning-rate 3e-4--resume starts from the weights and tokenizer from step 2. The default learning rate is 2e-3, which is for training from scratch. Use a smaller one so the model keeps what it already knows. Loss is printed every 50 steps and weights are saved every 500. Fine-tuning only on your own tools can wear away the distilled language knowledge, so check the real-text score in the metrics file afterwards.
5. Calibrate and evaluate
python examples/train_arc1.py --preset arc1-tiny --eval-onlyThis refits the confidence temperatures on held-out values, prints accuracy, and writes Models/arc1_arc1_tiny.metrics.json. Run it before you export, and check that your new tools score well and the old ones did not drop.
6. Export and use it
python examples/export_arc1.py --config Models/arc1_arc1_tiny.config.json \ --weights Models/arc1_arc1_tiny.weights.h5 \ --tokenizer Models/arc1_arc1_tiny_tokenizer.json \ --rcn my-arc1.rcn --quant rq8import gpbacay_arcane as arcaneagent = arcane.load_arc1("my-arc1.rcn")For Node use load({ model: "my-arc1.rcn" }). For the browser, convert it with python examples/export_arc1_onnx.py --model my-arc1.rcn.
Open the cloned repository in a coding assistant (Claude Code, Cursor, Codex and the like), download arc1-tiny.rcn into it, and paste this prompt. Replace the bracketed part with your tools, fields or labels. The assistant does the same six steps as the other tab.
Finetune the ARC 1 model in this repository (gpbacay_arcane) for my own tools.What I need it to do:[List each tool: name, what it does, its parameters (name, type, description),and 5 or more example ways a user would ask for it. Add any fields to extractor labels to classify into.]Do this in order, and stop and tell me if a step fails:1. Run "pip install -e ." if the package is not installed.2. Load ./arc1-tiny.rcn with gpbacay_arcane.rcn.load_rcn, then save the weights to Models/arc1_arc1_tiny.weights.h5 and the tokenizer to Models/arc1_arc1_tiny_tokenizer.json.3. Add a ToolDef for each of my tools to build_tool_library() in gpbacay_arcane/arc1_data.py. Follow the existing entries: descriptions, params, templates with {param} placeholders (10 or more), and a SlotDef per parameter.4. Run: python examples/train_arc1.py --preset arc1-tiny --resume --steps 1500 --learning-rate 3e-45. Run: python examples/train_arc1.py --preset arc1-tiny --eval-only Report the accuracy for my new tools and confirm the original tools did not get worse.6. Only if the results look good, export with: python examples/export_arc1.py --config Models/arc1_arc1_tiny.config.json --weights Models/arc1_arc1_tiny.weights.h5 --tokenizer Models/arc1_arc1_tiny_tokenizer.json --rcn my-arc1.rcn --quant rq8 Then check that gpbacay_arcane.load_arc1("my-arc1.rcn") runs one of my tools.Do not change any model code other than build_tool_library().Read the assistant's evaluation numbers yourself before you use the exported file.