28 KiB
Jose Celano5:23 PM https://www.symbolica.ai/blog/beyond-code-mode-agentica
ChatGPT5:23 PM Here’s a clear summary of the Symbolica.ai blog post “Beyond Code Mode: Agentica” based on the full article content:
The blog introduces Agentica, an open-source agent framework from Symbolica that rethinks how AI agents interact with the world of code and software. Symbolica’s core idea is to move beyond the usual “code mode” used in many LLM-based agent systems and instead build agents that directly interact with runtime objects through real code, not just structured tool calls. symbolica.ai
Traditional agent systems often generate tool-calls expressed as JSON or messages (e.g., “call get_weather(location=…)”), which limits how much an agent can compose and manipulate complex behavior. Agentica flips that on its head: rather than forcing the agent to treat capabilities as a flat list of external tools, it gives agents a real programming environment where code is the interface. Agents actually write and execute Python (or TypeScript) code in a sandbox that has access to real objects and type information. symbolica.ai
This has several implications:
Agents can grow their working context naturally as they manipulate objects and import code, rather than being trapped by a pre-declared list of tools. symbolica.ai
Object-oriented structures, with methods and relationships, become discoverable capabilities for the agent instead of abstract tool descriptions. symbolica.ai
Agents don’t just generate isolated calls; they can write code that loops, handles intermediate results, and chains operations meaningfully. symbolica.ai
Agents’ outputs aren’t opaque JSON: you can tell an agent to return a specific typed object, and the system will enforce type correctness so subsequent code can rely on it. symbolica.ai
The blog argues this approach unlocks much richer autonomous capability for agents: they can organize complex context, dynamically discover and use libraries, engineer their own context, and even spawn other agents programmatically. The result is a system where agents are closer to full-blown autonomous software entities capable of real engineering tasks rather than just making calls to canned tools. symbolica.ai
Underneath Agentica, Symbolica uses a sandboxed execution environment with careful isolation to prevent unsafe access, and it proxies objects back and forth so the agent can work with them as if they were local. symbolica.ai
In essence, *Agentica is a step toward agents that don’t just use tools, they write, compose, and reason with real code in structured environments—a richer, more software-native form of agentic AI. symbolica.ai
If you want, I can walk through an example from the article or explain how this compares with other agent-orchestration approaches (like tool calls vs code execution).
Show less
Jose Celano5:38 PM Do you think graphQL would be something in the middle?
ChatGPT5:38 PM Short answer: yes — GraphQL sits squarely in the middle, but in a very specific and slightly treacherous way.
Let’s place the pieces on the board.
On one extreme you have tool-call agents. Capabilities are flat, predeclared, and symbolic. The agent says “call get_user(id=3)” and hopes the universe complies. The surface area is intentionally small, which is safe, but also intellectually claustrophobic.
On the other extreme is Agentica-style code mode. The agent lives inside a real programming environment. Objects have identity, methods, types, lifetimes. Control flow exists. State can accumulate. This is software, not pantomime.
GraphQL lives between those worlds.
GraphQL is not “code”, but it is executable structure. A query is a tree of intent with constraints, arguments, and composition rules. The agent isn’t calling a single tool; it’s describing a shape of data it wants, and the runtime figures out how to satisfy that shape.
That middle-ness shows up in three important ways.
First, composition. GraphQL lets an agent compose needs declaratively: “Give me users, and for each user give me their last five torrents, and for each torrent give me the tracker stats.” That’s already far richer than JSON tool calls, which are usually one hop at a time.
Second, schema as affordance. A GraphQL schema is a discoverable capability map. Types, fields, arguments, nullability — these are not just documentation, they’re constraints the agent can reason against. This is closer to programming than people admit, and closer to Agentica’s “objects as interfaces” idea than REST ever was.
Third, controlled execution. The agent can’t invent loops, mutate state freely, or define new abstractions. It can only traverse the graph the schema allows. That’s the ceiling. GraphQL lets the agent navigate complexity, but not create complexity.
So the trade-off becomes clear.
GraphQL is excellent when the agent’s job is: – exploration – data retrieval – joining multiple domains safely – operating inside a bounded, inspectable capability space
It starts to creak when the agent needs: – intermediate state and memory – algorithmic control flow – synthesis of new behavior – orchestration across time, not just structure
From your perspective — especially given your interest in DDD boundaries and dependency direction — GraphQL is fascinating because it acts like a read-only anti-corruption layer. It exposes a domain graph without leaking implementation. An agent can ask questions of the domain without being allowed to do things to it.
Agentica, by contrast, lets the agent become a junior engineer inside the codebase. Powerful. Also dangerous in exactly the ways you already worry about when reviewing AI-written code.
A useful mental model is this:
GraphQL is a map. Code mode is a vehicle.
Maps are safer. Vehicles go places.
The interesting future isn’t choosing one — it’s stacking them. GraphQL as the high-level, typed, declarative perception layer. Code mode underneath for when the agent needs to reason, simulate, or build. That stack mirrors how humans work: read the map, then drive.
And like humans, agents given cars without maps tend to end up in ditches.
Show less
Jose Celano5:40 PM But agents can anyway write code to manipulate the data they get from MCP tools, what is the advantage of symbolica framework?
ChatGPT5:40 PM This is the right pressure point. If agents can already write code around MCP tools, why bother changing the paradigm at all?
The answer is subtle and architectural, not about raw capability.
Yes: with MCP (or classic tool calling), an agent can fetch data, then write code locally to manipulate the results. That part is true. But notice where the boundary is drawn. With MCP, the world looks like this:
There is a sealed toolbox on one side. There is free-form reasoning and code on the other. Between them is a narrow, symbolic membrane.
Symbolica’s advantage is not “agents can write code” — they already could. The advantage is where the code runs and what it can see.
In MCP-style systems, tools are opaque. The agent never really sees the object graph. It sees serialized snapshots. JSON is a fossil record of a computation that already happened elsewhere. Once the data crosses the boundary, the agent can manipulate it, but it cannot interrogate the machinery that produced it.
Symbolica collapses that boundary.
Instead of “call tool → receive blob → reason”, the agent is placed inside a live runtime where objects have identity, methods, and types. That changes several deep properties.
First, object continuity. With MCP, every tool call is amnesiac. You pass IDs back and forth, but the agent never holds the object itself. In Symbolica, the agent can keep references to objects across steps. That sounds mundane until you realize it enables incremental reasoning, caching, mutation, and long-lived workflows without inventing artificial state encodings.
Second, capabilities are discovered, not enumerated. MCP tools are declared up front as strings and schemas. If it’s not in the tool list, the agent cannot even imagine it. In Symbolica, capabilities emerge from imports, methods, and types. The agent can explore the surface area of a library the same way a human engineer would: by introspection and experimentation.
Third, control flow lives on the same side as effects. With MCP, loops, retries, branching, and error handling are all meta-behavior wrapped around tool calls. The tool itself is always a single atomic act. In Symbolica, control flow and effects interleave naturally. The agent can partially execute, inspect intermediate state, adjust strategy, and continue — without bouncing through a message-passing protocol.
Fourth, type pressure is real, not advisory. Tool schemas describe shapes, but they don’t enforce invariants once data is in the agent’s hands. In Symbolica, the agent is constrained by the host language’s type system. If something doesn’t type-check, it doesn’t run. This dramatically reduces a whole class of “looks right in JSON, explodes in reality” failures.
There’s also a philosophical difference that matters in practice.
MCP treats agents as orchestrators of remote actions. Symbolica treats agents as participants in a software system. That’s why the framework feels closer to embedding an AI inside your codebase than calling an API from it.
The cost, of course, is risk. You are giving the agent sharper tools. Sandboxing, capability scoping, and auditability become existential concerns, not optional features. This is why Symbolica makes sense in environments where you already trust human engineers with the same runtime — and much less sense in public, multi-tenant, or adversarial settings.
A clean way to summarize it:
MCP lets agents use software. Symbolica lets agents be inside software.
Once you see that distinction, the advantage stops being abstract and starts being architectural.
Show less
Jose Celano5:43 PM Is symbolica like an agent running in a REPL?
ChatGPT5:43 PM Yes — that’s a very good approximation, and also slightly misleading in a useful way.
Symbolica is like an agent living in a REPL, but not the cozy, stateless REPL we use to poke at ideas and then forget them. It’s closer to a persistent, typed, sandboxed REPL that is allowed to touch the real system.
Here’s the precise shape of the similarity.
In a REPL, you have: – a live runtime – objects with identity – incremental execution – the ability to inspect, modify, and reuse previous results
Symbolica gives the agent exactly that. The agent writes real code, executes it, gets real objects back, and can keep working with them across turns. That’s the REPL part, and it’s the key conceptual leap.
Where the analogy breaks — and where Symbolica becomes interesting — is intent and control.
A human at a REPL is exploratory but intentional. Symbolica’s agent is goal-driven. Each “REPL step” is produced by a planner that reasons about what code should exist next. The REPL isn’t a debugging aid; it’s the primary interface between cognition and action.
There are three important differences from a normal REPL.
First, capability fencing. A normal REPL can do anything the process can do. Symbolica’s REPL is deliberately uneven. Some modules exist, some don’t. Some objects are proxied. Some side effects are allowed, others are blocked. This makes it closer to a capability-based OS than a Python shell.
Second, object proxying across the boundary. The agent doesn’t necessarily “own” the objects it manipulates. Many are proxies to real resources managed elsewhere. That lets the agent hold references without being able to break invariants or escape the sandbox.
Third, evaluation is supervised. A human REPL trusts the human. Symbolica does not trust the agent. Code is executed under supervision, with guards, timeouts, and structural constraints. Think “REPL with a bouncer”.
A useful mental image is this:
A tool-based agent is writing requests. A Symbolica agent is writing code snippets into a long-lived REPL session.
That difference explains why Symbolica feels qualitatively different even though, superficially, “agents could already write code”.
If you want an even sharper analogy: Symbolica is less like ChatGPT calling tools, and more like Emacs + Lisp, where the boundary between editor, runtime, and program dissolves. The agent isn’t using the system — it’s cohabiting with it.
That’s powerful. It’s also exactly the sort of power that makes seasoned engineers instinctively nervous, which is usually a sign that something genuinely new is happening.
Show more
Jose Celano5:51 PM Jesus Perez is a software engineer who is building provisioning tools with KCL and Nutshell. The idea is to use the KCL language to define what your infrastructure can do (typed definition), then you can convert that into a final specification to provision your system. Nushell alloys to operate on those files or other artifacts. Both are typed languages but dynamic. Nushell is a REPL so it is similar to symbolica. Yoi could integrate your agent in that system to help you provision your infra.
ChatGPT5:51 PM This is a solid intuition, and you’re not forcing the analogy — you’re triangulating something real.
What Jesús is doing with KCL + Nushell is already most of the substrate Symbolica is gesturing toward, just without the agent in the loop yet.
Let’s line the pieces up carefully.
KCL gives you a typed, constrained declaration of “what is allowed to exist”. Not how to provision it, but the space of valid infrastructure states. That’s a capability boundary expressed as types and schemas. In agent terms, that’s a world model with guardrails.
Nushell then gives you a live, structured REPL over artifacts. Files aren’t strings; they’re tables. Pipelines preserve types. You can inspect, transform, validate, and compose outputs incrementally. That’s already far closer to “code mode” than JSON tool calls.
Put together, you get something important: – a declarative, typed domain (KCL) – a procedural, exploratory runtime (Nushell) – a REPL that persists context
That is structurally equivalent to Symbolica’s core idea.
The missing ingredient is not technology, it’s agency.
Right now, a human sits at the Nushell REPL and decides: – which KCL modules to load – which constraints to tighten – how to transform specs into concrete plans – when to stop and apply
Drop an agent into that loop, and suddenly you have: – an agent reasoning inside the infra language – discovering allowed actions via KCL types – manipulating real artifacts via Nushell pipelines – iterating toward a valid, provisionable spec
That’s not “AI helping with infra”. That’s infra as a living system with a cognitive co-processor.
There’s also a crucial safety advantage here that Symbolica users have to engineer manually.
Because KCL defines the allowed shape of reality, the agent cannot provision something that the schema doesn’t permit. The agent can explore, but only within the phase space you defined. This is much closer to how we wish agents behaved.
In other words: Symbolica says: “Put the agent in a sandbox and hope your fences are good.” KCL + Nushell says: “Make the world itself unbreakable, then let the agent wander.”
That’s a big deal.
There’s a deeper connection too, and this is where your DDD instincts show up again. KCL is acting like an aggregate root for infrastructure. Nushell is the application service layer. An agent inside Nushell is not allowed to violate invariants because the language won’t let it express them.
So yes — integrating an agent there makes sense, and it’s arguably cleaner than most agent frameworks because: – types are first-class – artifacts are inspectable – execution is incremental – side effects are explicit
You’ve basically described a path where agentic behavior emerges from good language design, not from prompt engineering.
If Symbolica is “agents inside code”, then what you’re describing is “agents inside languages that already know what they’re doing”. That’s not just similar — it may be the more civilized evolutionary branch.
This is the kind of setup where agents stop feeling spooky and start feeling boringly useful, which is the highest compliment infrastructure can receive.
Show less
Jose Celano5:55 PM How all this is it related to agents to write software? I guess the agents we are describing are agents on the production side helping end-user, but how can we use this for agents helping developers to build software?
ChatGPT5:55 PM You’re circling the right abstraction now. The moment you ask this, the fog lifts a bit.
What we’ve been talking about so far is not “AI coding assistants” in the GitHub Copilot sense. It’s something orthogonal. The connection only becomes clear once you separate two kinds of agency that usually get mashed together.
One kind of agent acts in the system. The other acts on the system.
Production agents — the Symbolica / KCL / Nushell style ones — act in a running world. They provision infra, answer users, rebalance queues, tune parameters. They are operators.
Developer-assist agents act on the software itself. They read, modify, and reason about code, tests, schemas, and invariants. They are meta-operators.
The mistake most tooling makes is treating developer agents as “better autocomplete”. That caps their intelligence very quickly.
The trick is to reuse the same ideas, but move the boundary.
For developer agents, the “runtime” is not Kubernetes or cloud APIs. The runtime is your codebase.
Imagine a Symbolica-style REPL, but instead of infra objects, it exposes: – ASTs (abstract syntax trees: the structured form of source code) – module graphs and dependency edges – test suites as executable objects – build pipelines as typed plans – architectural constraints as first-class rules
Now the agent isn’t “writing text that looks like Rust”. It’s manipulating the program as a living structure.
Here’s where your previous concerns snap into place.
Remember your frustration with enforcing DDD boundaries, test naming conventions, dependency direction? Those are exactly the kinds of invariants that do not belong in prompts. They belong in the environment.
A developer agent in this model: – explores the dependency graph – sees forbidden edges as type errors, not lint warnings – runs tests as part of its reasoning loop – refactors by transforming ASTs, not by guessing text edits
This is the same leap Symbolica makes for production — collapsing the tool boundary — applied to software construction.
There’s a second layer that matters even more: feedback latency.
Humans learn software by: edit → run → inspect → adjust
LLMs forced into chat break this loop. A REPL restores it. When an agent can: – make a small structural change – immediately re-run affected tests – inspect failures as structured data – try again
…you suddenly get something that behaves like a junior developer who can actually learn within a session.
This is also where typed, dynamic languages shine again. Types become teacher rails. The agent can’t compile nonsense. When it fails, the failure is precise.
So the mapping looks like this:
Production agent: – Runtime = infrastructure / services – Invariants = schemas, policies, types – Output = actions
Developer agent: – Runtime = codebase + build system – Invariants = architecture rules, tests, types – Output = patches
Same architecture. Different world.
The uncomfortable but honest conclusion is this:
If your development environment is sloppy, agents will be sloppy. If your development environment is precise, agents become surprisingly disciplined.
That’s why REPL-like, typed, inspectable systems matter so much. They turn “AI writes code” from a parlor trick into engineering with guardrails.
This is also why the future of AI-assisted software won’t be decided by models alone. It will be decided by who builds the best worlds for agents to inhabit.
Show more
Jose Celano6:00 PM And how can be build that world? I see some people crafting prompts or adding documents to force the behaviour of the agents. Another solution is to add more agents to audit the main ones, and finally we could declaratively define your architecture and invariants so they can be check deterministically, a guardrails no agents can leave.
ChatGPT6:00 PM You’re now asking the foundational question, and your own list already contains the answer — just not yet ordered by leverage.
Let’s de-mythologize this calmly.
There are three ways people try to “build the world” for agents, and only one of them scales beyond demos.
Prompt-crafting and document stuffing is behavioral nudging. Multi-agent auditing is social control. Declarative invariants are physics.
Only physics actually holds.
Prompting works the way telling a human “please be careful” works. It helps when things are easy and fails exactly when things matter. Documents in context are advice, not law. The model can forget, misinterpret, or rationalize its way around them. That’s not a bug — that’s what language models do.
Auditor agents are better, but they’re still turtles all the way down. You’re adding more fallible cognition to supervise fallible cognition. This can reduce error rates, but it never eliminates classes of error. Worse, it creates coordination and incentive problems: which agent wins, and why?
Declarative invariants are different because they remove choice.
When you encode architecture, dependency direction, naming rules, and domain boundaries as things that cannot be expressed, you’ve stopped negotiating with the agent. You’ve constrained the phase space of possible actions.
That’s the key shift.
So how do you actually build that world?
You build it in layers, and each layer answers a different failure mode.
At the bottom is the structural substrate. This is where your codebase stops being text and becomes data. ASTs, module graphs, dependency DAGs, schemas, build plans. If an agent can only see files as strings, you’ve already lost. This layer is deterministic and inspectable.
Above that sit declarative invariants. This is where DDD boundaries live. “Domain cannot depend on infrastructure.” “Tests must follow naming X.” “Aggregates cannot leak internal types.” These are not lints that warn — they are rules that make certain graphs invalid. Violations don’t get reviewed; they fail to exist.
Next is the execution loop. Agents must be able to try, fail, observe, and retry quickly. Compilation errors, test failures, and rule violations must be structured outputs, not walls of text. This is where REPL-like environments matter. Fast feedback turns stochastic models into iterative improvers.
Only above all that do prompts and documents belong. They explain why the rules exist, not whether they apply. They guide strategy, not enforce law.
And auditor agents? They move to the edges. They’re useful for soft qualities: readability, API ergonomics, “does this feel idiomatic Rust?”. Humans disagree on these too. Let agents argue there. But never let them arbitrate architecture.
A good litmus test is this:
If an invariant matters enough that you’d block a PR over it, it must be encoded where the agent physically cannot violate it.
This is why what you described earlier — KCL for infra, typed REPLs, Symbolica-style environments — is so important. They are not AI tools. They are world-builders.
Once the world is right, the agent becomes boringly effective. Without it, you’ll be stuck forever tuning prompts and inventing new supervisors.
The quiet truth is that we don’t need smarter agents nearly as much as we need more honest software environments. The agents are already good enough to reveal where our abstractions are weak.
Build the physics first. Intelligence adapts automatically.
Show less
Jose Celano6:05 PM What tools are there already available to build these declarations of our rules and force agents follow them
ChatGPT6:05 PM This is where things get refreshingly concrete. The good news is: most of the tools already exist. The bad news is: they’re scattered across ecosystems and were not built “for agents”, but for humans. Agents just happen to benefit enormously from them.
I’ll organize this by what kind of rule you want to make impossible to break, because that’s the right axis.
First: dependency and architectural rules These answer: what may depend on what.
In Rust, you already have strong primitives: – crate boundaries enforced by the compiler – pub(crate) and module visibility as hard walls – workspace layouts that encode layering
On top of that, there are explicit tools: – cargo-deny: blocks forbidden dependencies deterministically – cargo-deps / cargo-modules: produce dependency graphs agents can reason over – ArchUnit (JVM) and its conceptual cousins: architecture as executable tests
The key idea here is “architecture as graph + forbidden edges”. Once that graph is machine-readable, an agent literally cannot add an illegal edge without failing.
Second: type-level and schema-level invariants These answer: what shapes of things are allowed to exist.
You already mentioned some of the strongest ones: – KCL, CUE, Jsonnet: configuration as a constrained language, not a template – JSON Schema / OpenAPI when used as validators, not docs – Protocol Buffers / Avro for message-level invariants
These are powerful because they don’t care who produced the artifact — human or agent. Invalid specs simply do not validate.
This is the same move Rust made compared to dynamic languages: illegal states become unrepresentable.
Third: semantic rules expressed as executable checks These answer: this is legal syntax, but still wrong.
This is where linters and custom analyzers live: – Clippy (and your idea of custom Rust linters is exactly right here) – Semgrep: pattern-based semantic rules across languages – Tree-sitter: gives you ASTs so rules operate on structure, not text
These tools are especially agent-friendly because failures are deterministic and local. An agent can iterate until the rule passes instead of “trying to sound correct”.
Fourth: workflow and lifecycle rules These answer: when and how changes may happen.
Examples: – CI pipelines as hard gates – Required test coverage thresholds – Mandatory formatting (rustfmt, prettier) – Migration checks (DB schema diffs must be forward-only, etc.)
From an agent’s perspective, CI is the law of physics. It doesn’t argue. It fails.
Fifth: capability-based execution environments These answer: what actions are even possible.
This is where things get more Symbolica-like: – Sandboxed REPLs – Restricted file system views – Build systems that expose structured targets instead of shell access – Bazel / Buck-style hermetic builds
Agents operating here can’t “cheat” because the environment literally doesn’t offer the affordance.
Now, an important meta-point that ties all this together.
None of these tools were marketed as “agent guardrails”. They were marketed as “best practices”.
That’s not an accident.
Anything that: – is declarative – is typed or structured – fails deterministically – produces machine-readable errors
…is automatically an agent alignment tool, whether its authors intended it or not.
The uncomfortable but useful realization is this: teams that already run tight ships (clear architecture, strong typing, real CI discipline) will get dramatically better results from agents than teams that rely on convention and review culture.
So the frontier isn’t inventing brand-new AI frameworks. It’s lifting more of what we “review” into what we “cannot express”.
Once rules live there, agents don’t need to follow them.
They have no choice.
Show less