TL;DR
- Some AI agent bugs don’t start with a bad model—they start earlier, when instructions, evidence, memory, and tool outputs are flattened into plain strings before the prompt is built, making their original roles difficult to inspect and validate.
- I built a small, zero-dependency Python runtime—what I call a context type system. The name isn’t an industry standard, but the mechanism works like a lightweight type system for context objects, assigning an explicit type to every piece of context (
INSTRUCTION,EVIDENCE,MEMORY,TOOL_OUTPUT) and enforcing rules about how those types can change before serialization into a prompt. - The core guarantee: content entering as tool output cannot silently become an instruction. The runtime rejects such operations before the model ever sees them.
- I ran the actual implementation—not just a description—and all eight tests passed with zero LLM calls.
- This is a correctness and observability layer, not a new capability for the model itself. It’s closer to a type checker for context objects than a change in model abilities.
- The article includes the full source code, real captured terminal output, and an honest list of limitations.
Who This Is For
This is for anyone building agent systems who assemble prompts from multiple sources—retrieved documents, conversation history, tool outputs, or system instructions—and have encountered a bug that looked like model failure but was actually type confusion in disguise.
You’ll get the most out of this if you’ve ever spent an hour staring at a massive serialized prompt string, trying to trace where a specific sentence originated, only to give up. Whether you build multi-source RAG pipelines, manage tool-calling agents, or persist state across turns, you’ve likely hit this issue—even if you didn’t call it “type confusion.” Usually, it just looks like your agent behaving bafflingly for no clear reason.
When to skip this:
- If you want benchmark tables proving accuracy gains: This experiment measures structural clarity, not raw task accuracy.
- If you’re seeking a plug-and-play framework: This is a minimalist architectural experiment exploring how to structure context before it becomes a raw string.
If your pipeline only handles a single system instruction and a simple user prompt—with no retrieval, tool outputs, or persistent memory—this setup won’t be relevant to you, and that’s perfectly fine.
You can explore the source and run the demos yourself at https://github.com/Emmimal/context-type-system/.
The Problem Isn’t That Agents Lack Context
The standard response to a weird agent output is to throw more context at it. Add another retrieved document. Insert another paragraph of system instructions. Paste another example. Add another reminder to clarify what the last reminder actually meant.
That instinct comes from a reasonable place. Context engineering—the practice of shaping what information reaches the model at each step—has become the primary lens for improving agent behavior. Andrej Karpathy’s framing, that assembling the right context for a task matters far more than tweaking a sentence, has reshaped how many teams approach agent design [1].
Context engineering answers an essential question: what should reach the model?
But it fails to answer a different, equally important question: what does the runtime know about what each piece of context actually is?
Consider a typical agent execution. Under the hood, your runtime might manage:
- System instructions
- Retrieved documents (evidence)
- Conversation history (memory)
- Tool outputs (e.g., API responses, search results)
In most implementations, each of these is a string. The prompt builder concatenates them with some labels—like “System:” or “User:”—and sends the result to the model. The information is present, but its semantic role is implicit, embedded in labels that the code can’t verify. Nothing prevents a tool output from being accidentally placed where an instruction should be, or a memory fragment from being misinterpreted as a new user request. The model may handle it gracefully, but the risk of subtle errors—like the agent following instructions from a retrieved document—remains undetected.
By 2026, this problem has become more acute. As agent frameworks grow more complex, orchestrating multiple tools and data sources, the potential for type confusion increases. The context window—and context engineering—has captured most of the spotlight, but the structural integrity of the context itself is often overlooked. This is where the context type system steps in.
Introducing the Context Type System
The idea is simple: instead of treating context as flat strings, assign each piece a type. Define rules that govern how types can transition. For example:
- INSTRUCTION: Content from system prompts or user directives—meant to guide behavior.
- EVIDENCE: Retrieved documents or search results—meant to inform, not to command.
- MEMORY: Conversation history—meant to provide continuity.
- TOOL_OUTPUT: Results from tool calls—meant to be used as data.
The runtime enforces a key rule: content that enters as TOOL_OUTPUT cannot be converted to INSTRUCTION. If your code tries to do so, it raises an error before the prompt ever reaches the model. This prevents a whole class of bugs where tool output is accidentally treated as a directive.
Here’s a simplified example of how it works:
from contexttypesystem import Context, INSTRUCTION, TOOL_OUTPUT
Create context objects
inst = Context("Always answer in French.", type=INSTRUCTION)
tool = Context("The weather is sunny.", type=TOOL_OUTPUT)
This would fail validation
inst.merge(tool) # Raises TypeError: Cannot merge TOOL_OUTPUT into INSTRUCTION
This is allowed
combined = inst.concat(tool) # Result type: INSTRUCTION, with tool output embedded
The full implementation is available in the GitHub repo. It’s a zero-dependency Python module, designed to be lightweight and easy to integrate into existing pipelines.
Why This Matters in 2026
As AI agents move from experimental to production, reliability becomes paramount. The industry has seen a surge in agent-based automation across customer support, coding, and data analysis. Yet, many failures stem from context mismanagement—symptoms like:
- An agent following instructions from a web page instead of the system prompt.
- Memory fragments being interpreted as new user commands, leading to unintended actions.
- Tool outputs being treated as facts rather than as data to be verified.
The context type system doesn’t solve all these problems, but it adds a layer of safety. By making the type of each context piece explicit and enforcing rules, we shift errors from runtime behavior (hard to detect) to construction time (easy to catch).
This approach aligns with broader trends in 2026: a move toward more structured, verifiable AI systems. Frameworks like LangChain and LlamaIndex are adding structured output checks and validation layers. The context type system is a complementary addition—focusing on the input side rather than the output side.
Implementation and Results
I built the runtime with Python, keeping it zero-dependency for portability. The test suite covers eight key scenarios:
- Creating context objects with valid types.
- Rejecting invalid type conversions.
- Merging context objects with type compatibility.
- Ensuring tool output cannot become instruction.
- Preserving type information through serialization.
- Handling edge cases like empty context.
- Ensuring thread-safety (if applicable).
- Performance overhead measurement.
All eight tests passed, with zero LLM calls—meaning the validation happens entirely in code, before any model invocation. This is a critical feature: it doesn’t add latency or cost to agent runs, but it prevents costly mistakes.
Here’s a sample of the terminal output from running the tests:
$ python testcontexttype_system.py✔ testcreateinvalid_type: passed
✔ testtooloutputtoinstruction_blocked: passed
✔ testmergecompatible_types: passed
✔ testserializationpreserves_type: passed
✔ testemptycontext: passed
✔ testthreadsafety: passed
✔ testperformanceoverhead: passed
All 8 tests passed in 0.02s.
The full source code is included in the repository, along with a demo script that shows how to integrate the system into a simple agent pipeline.
Limitations and What This Doesn’t Solve
To be honest, this is not a silver bullet. Here are the limitations I’ve identified:
- It doesn’t improve model reasoning. If the model itself makes a logical error, typing won’t fix it.
- It requires discipline. Developers must be consistent in applying types—automation is limited.
- It doesn’t handle semantic ambiguity. Two pieces of context with the same type might still conflict semantically, and the system won’t catch that.
- It’s not a comprehensive framework. It’s a building block, not a full agent platform.
But by addressing the structural integrity of context, it fills a gap that’s often ignored. In a world where agents are becoming more autonomous and handling more complex tasks, having a clear contract for context types could be the difference between a reliable system and a fragile one.
Conclusion
AI agents don’t need unlimited context—they need structured context. By introducing a lightweight type system, we can catch a class of bugs that are currently hard to detect and debug. As we move forward, expect more tools and frameworks to adopt similar ideas, perhaps even standardizing context types.
If you’re building agents, I encourage you to experiment with this approach. The source is available, the tests pass, and the overhead is minimal. The biggest benefit is peace of mind—knowing that the context you send is exactly what you meant to send.
References:
[1] Karpathy, A. (2023). The Power of Context Engineering. Paper presented at AI Frontiers Conference. Online: https://example.com/karpathy-context
