Skip to content
docs
Arxo ↗

Choose an integration pattern

For LLMs5 sections

An agent can stand on an Arxo canon in four ways. They differ in two things: what the model sees, and what the answer carries back. Pick the pattern before you write instructions or tools, because it decides who pins the canon, who asks for the date of law, and whether every answer can be replayed.

In three of the four patterns the model never sees Arxo at all. It calls tools named after your domain — “end of a period”, “check the claim documents” — and your application answers them with the engine. The user sees your product; the canon is the foundation underneath.

PatternWhat the model seesWhere the canon runsWhat an answer carriesUse it when
Domain tools over the local SDKyour tools, e.g. period_endin your process, @arxo/law with the engine in WebAssembly, offline after installstatus, values, proof, sources, three hashes, the canonical documentyou ship a product on one or a few canons
Domain tools over your own law serveyour toolsa long-running HTTP service you host, with journalsthe same answer, plus the exact embedded document bytesseveral applications or languages share one pinned deployment
Domain tools over a generated moduleyour toolscode printed from the canon by law codegen (TypeScript, Python, Go); no engine at run timetruth status, evaluation status, issues, judgment requests — no proof, no hashesthe engine cannot ship with the product and replay is not required
The agent explores the canon over MCPArxo tools: law_search, law_rules, law_ask and the restthe public Arxo host or your own MCP serverthe host’s answer projectionresearch assistants and open questions across many canons

The first agent of this section uses the first pattern; example A (one labour-law question) uses the fourth.

The application opens a pinned canon by name and version and keeps the handle for the life of the process:

JavaScript
import { open } from '@arxo/law';
const canon = await open('de.bgb.fristen@0.1.0'); // checked against its contentHash

Each domain tool is a small function: it maps the tool’s arguments to typed facts, asks one question, and returns the status, the values and the grounds in the application’s own words. The SDK rejects a fact that does not fit the canon — an unknown relation, a wrong arity or type — with FactError before the engine runs, so a model that invents a field cannot reach a result.

Status: ran locally (@arxo/law 0.3.3, de.bgb.fristen@0.1.0); the complete tool is in Build your first agent.

The same tools, but the application asks a service instead of an in-process engine: open(name, { serve: { endpoint, token } }). The service is a journaled HTTP deployment with /v1/... routes that you run and upgrade yourself; see Private HTTP service. Choose it when the pinned world must be one shared deployment rather than a copy inside each application.

law codegen prints an installable TypeScript, Python or Go package from a canon installed in a project. The module evaluates without the engine and returns one answer envelope per question: truth status, evaluation status, issues and judgment requests, under the same status names. It carries no proof graph and no hashes, so an answer cannot be replayed or audited byte for byte, and a canon construct outside the generator’s coverage is refused when the module is generated, not at run time.

Status: NOT RUN in this section — there is no agent example on a generated module yet. The command accepts the targets py, ts and go; to try it, install a canon into a project and run law codegen <package> --target ts --name <npm-name> --version 0.1.0 --out lib-ts.

The model itself searches for a question, reads the rules’ input contract (law_rules with contract: true), collects facts and calls law_ask. This is the right pattern when the question is not known in advance. An MCP profile narrows the tool surface and the packages a server exposes; it restricts what the agent can reach, it is not a different way of computing. Connect and discover covers this pattern end to end.

  • The engine decides. Neither the model nor your application computes, rounds, compares against a threshold or fills a missing value. A domain tool returns what the engine returned.
  • The date of law comes from a person. A tool takes it as an argument; the agent asks for it and never defaults it to today.
  • Statuses survive the translation. A domain tool must pass the evaluation status through. An empty collection, NEITHER or a non-COMPUTED status is a stop, not “no” and not zero. The full reading is in Read answers.
  • The contract applies to the whole system. When the model cannot see a field, the obligation moves into your application code; see The agent contract.
  1. Is the question known when you build the product? If yes, write domain tools; if the agent must find the question, use MCP.
  2. Must every answer be replayable and carry its proof? If yes, use the SDK or law serve; a generated module does not carry them.
  3. One process or a shared deployment? One process: the SDK. Several applications on one pinned world: law serve.

Failure case: the tool that drops the status

Section titled “Failure case: the tool that drops the status”

A domain tool returns only end_dates[0]. On a case where the user did not give the period’s length, the engine completes the evaluation with an empty collection; the tool returns undefined, and the model fills the gap with a date it counted itself. The fix is structural: return the status, the full value list and the grounds every time, and say in the tool result that an empty list is not an answer. The first agent’s tool does exactly that.

Status: labeled illustration; the empty-collection behavior itself ran locally and is recorded in Build your first agent.

  • Open a canon with @arxo/law and ask one question; the answer has evaluationStatus, value, proof and hashes.
  • Run law codegen --help and read the target list.
  • Connect to an MCP server and read tools/list; it is the authority on which tools exist.

Previous: Agent Engineering with Arxo Next: Build your first agent

Documentation for Arxo. Writings — blog.arxo.io.

Anonymous visit counts on stats.arxo.io, no cookies.