Agent Harnesses and Self-Improving Agents
AI is advancing at an unprecedented pace, turning artificial general intelligence (AGI) and artificial superintelligence (ASI) from distant ambitions into goals achievable in the near future. Recursive self-improvement (RSI) is also gaining remarkable attention for its potential to let AI improve itself without human involvement. To better exploit model intelligence, a wide range of agent harnesses have been developed, including Claude Code, Codex, RLMs, and OpenClaw. Furthermore, work on self-improving harnesses, including ACE, MCE, AIDE², STOP, DGM, ADAS, Hyperagents, DSH, Prime Agent, and Hermes Agent, explores how agents can modify and improve themselves.
With these advances, a trend is clear: as models become more capable and intelligent, they should gain greater autonomy and control within the harness, while mechanisms predefined by human designers become increasingly unnecessary or even harmful. This trend leads us to ask two questions:
First, what is the ultimate form of an agent harness for the ultimate superintelligent model? Of course, it should be capable of evolving on its own. Moreover, in line with the current trend, it should give the agent maximum freedom, with minimal behavior predefined by humans. Here, we push this to its limit and propose that the agent should write its own code as it runs, building itself from scratch, including deciding how and when to call the LLM.
Second, as the agent builds itself and continually changes itself, does it need a “self”—and if so, what defines it? We think the agent needs a clearly defined “self”. Otherwise, it is unclear whether it is improving itself or building a different agent. In addition, if any changes go wrong, something must be responsible for restoring the agent to a working state. The best candidate is the agent’s “self”. Taking these considerations together, we propose defining its “self” as the smallest possible immutable core that can act and repair the agent. As everything around it changes, this core preserves the agent’s identity. Under this definition, changing the core would create a different agent.
Let’s see how to put these principles into practice.
The Typical Agent Loop
Nearly all mainstream agents—including Claude Code, Codex, Pi, and OpenClaw—can be understood in terms of a ReAct-style loop (Yao et al., 2023), extended with tools and context management (Anthropic, 2025; Bolin, 2026). The model chooses actions within a human-engineered harness that coordinates model calls, tool execution, and feedback. This ReAct-style loop can be simplified as follows:
messages = [user_task]
while True:
response = llm(messages)
tool_call = response.tool_call
if tool_call is None:
print(response.text) # Agent response
break
result = execute_tool(tool_call)
messages += [response, result]
Let’s focus on the while True loop. If we unroll this loop, assuming it runs for three iterations with two tool calls followed by a final response, it becomes:
messages = [user_task]
# Step 1
response = llm(messages)
tool_call = response.tool_call
result = execute_tool(tool_call)
messages += [response, result]
# Step 2
response = llm(messages)
tool_call = response.tool_call
result = execute_tool(tool_call)
messages += [response, result]
# Step 3
response = llm(messages)
tool_call = response.tool_call
if tool_call is None:
print(response.text) # Agent response
# End — equivalent to break in the original loop
Writing the Next Step
Notice that each step calls the LLM, which is where the intelligence happens. So what if we asked the LLM to write the code for the agent’s next step, including how and when to call itself? The agent could then decide how each step works by writing its own harness code as it runs. This code could handle anything from tool calls to context management. For example:
- Tools and execution: call tools, install packages, and run subprocesses.
- Context and memory: manage and compact context, and save and recall memories.
- Model calls: preprocess input and switch reasoning levels or models.
- Output and termination: output a response or stop altogether.
The ReAct loop is just one special case. Note that we are simply splitting the unrolled loop into steps, so the LLM call can appear anywhere within a step, as long as the LLM is called in each step and generates the code for the next step.
To implement this, we give the LLM a tool called set_next_code. The LLM uses it to set the Python code for the next step (other languages would work too). Once the current step finishes, the harness executes the code it just generated in the same persistent Python session (we use IPython, which works particularly well for this). The pseudocode is shown below:
@host_tool
def set_next_code(code):
global next_code
if next_code is not None:
raise RuntimeError("Next step already scheduled.")
next_code = code
return "Next step scheduled."
def call_me(messages, *args, **kwargs):
system_prompt = """You are Fibona Agent.
...
Write Python code for your next step.
Use set_next_code exactly once per step to schedule it.
It runs after the current step finishes, in the same Python session.
Call call_me from your code to notify yourself and generate a subsequent step.
...
"""
return llm(
messages, *args,
system_prompt=system_prompt,
tools=[set_next_code], **kwargs,
)
# Bootstrap code: everything starts from here
next_code = "call_me([user_task])"
while True:
code, next_code = next_code, None
run_cell(code)
@host_tool behaves like a server-side tool: llm handles its execution and model continuation internally, similar to OpenAI-hosted tools. In addition, you may notice a new function, call_me. It wraps llm, adding a system prompt and the set_next_code tool while forwarding the supplied arguments. The name reflects the agent’s perspective: it uses the code it writes to notify itself and generate the next step, hence call_me.
This gives concrete form to the “self” proposed at the beginning, i.e., everything predefined by the engine, including the system prompt, the host tools, and a fixed model or fixed/minimum reasoning level if specified.
Recalling the Past
How can the agent learn from its own history and grow through experience? We add a variable history, and the engine records each cell’s code and outputs in it. The variable is also made available in the REPL session so that the agent can use it to recall, summarize, or reuse its past experience. The agent also decides which parts to include in call_me. This provides a foundation for memory without passing the entire history into every LLM call. In principle, this history can grow like the unbounded tape of a Turing machine, while each LLM call uses only a finite portion of it.
history = []
@host_tool
def set_next_code(code):
global next_code
if next_code is not None:
raise RuntimeError("Next step already scheduled.")
next_code = code
return "Next step scheduled."
def call_me(messages, *args, **kwargs):
system_prompt = """You are Fibona Agent.
...
Write Python code for your next step.
Use set_next_code exactly once per step to schedule it.
It runs after the current step finishes, in the same Python session.
Call call_me from your code to notify yourself and generate a subsequent step.
Inspect history in the REPL session and include what you need in call_me's input.
...
"""
return llm(
messages, *args,
system_prompt=system_prompt,
tools=[set_next_code], **kwargs,
)
# Bootstrap code: everything starts from here
next_code = "call_me([user_task])"
while True:
code, next_code = next_code, None
env.bind(history=history.snapshot())
output = run_cell(code)
history.append({"code": code, "output": output})
Recovering from Failure
Finally, how does the agent recover from failure, and who is responsible for that recovery? If a step raises an error or fails to set the next code, the engine records the result in history and falls back to a fixed repair cell. This cell calls call_me to ask the agent’s “self” to inspect its history, repair the failure, and continue. If it fails again, the recovery cell runs again. In addition, the persistent REPL session preserves state rather than rolling it back. This allows the agent to retain its full history of experience, including failures and recovery attempts.
history = []
@host_tool
def set_next_code(code):
global next_code
if next_code is not None:
raise RuntimeError("Next step already scheduled.")
next_code = code
return "Next step scheduled."
def call_me(messages, *args, **kwargs):
system_prompt = """You are Fibona Agent.
...
Write Python code for your next step.
Use set_next_code exactly once per step to schedule it.
It runs after the current step finishes, in the same Python session.
Call call_me from your code to notify yourself and generate a subsequent step.
Inspect history in the REPL session and include what you need in call_me's input.
...
"""
return llm(
messages, *args,
system_prompt=system_prompt,
tools=[set_next_code], **kwargs,
)
# Bootstrap code: everything starts from here
next_code = "call_me([user_task])"
while True:
code, next_code = next_code, None
env.bind(history=history.snapshot())
result = run_cell(code)
history.append({"code": code, "output": result.output, "error": result.error})
if result.error or next_code is None:
# the recovery cell
next_code = "call_me(['Inspect history, repair the failure and continue.'])"
Relation to Prior Work
Recent work has explored self-improving agents and their foundations through several complementary directions:
- Modifying programs and improvement procedures. AIDE², STOP, Gödel Agent, SICA, DGM, and Hyperagents explore how systems can revise agent code or code-improvement procedures.
- Designing and optimizing agents and harnesses. ADAS, AFlow, Meta-Harness, Self-Harness, and TTHE automate the design and adaptation of agents, workflows, and harnesses.
- Making agent behavior programmable. CodeAct, RLMs, and Prime Agent use code to express actions, process context, or invoke models.
- Adapting through tools, skills, and memory. Voyager, Alita, Reflexion, MemGPT, ACE, and MCE support adaptation by building reusable tools and skills, retaining feedback, or managing persistent memory and context.
- Extending the harness through plugins. DeepSeek Harness (DSH) follows an “Everything is a Plugin” philosophy, defining an elaborate plugin architecture through which the agent can extend itself.
Fibona may look similar to RLMs and Prime Agent, which also let agents execute arbitrary code in a persistent REPL environment. Fibona goes further by letting the agent write the code that invokes itself, bootstrapping its own harness from a minimal immutable core that also defines its “self.” This gives the agent direct control over how it constructs its next context. This seemingly small difference has significant implications. For example, provided the model and API support the relevant modalities, the agent can write its own code to include images in its next invocation or decide whether and how to accept audio input, without dedicated input mechanisms predefined by humans. Arbitrary code execution alone in a REPL environment does not provide this capability, as the REPL interaction is text-based. This essentially treats the REPL as just another tool. Compared with DSH, which also offers considerable extensibility through plugins, Fibona operates at a more fundamental level and leaves even that architectural choice to the agent: it could build its own plugin system and evolve into a DSH-like architecture as it runs.
Beyond these architectural differences, these works do not explicitly discuss or define what constitutes the agent’s “self”—a fundamental question for self-improving agents: what is being improved, and what makes it the same agent throughout that process? We examine this question explicitly and clearly define the agent’s “self” in our implementation. This establishes a clear boundary between the agent’s enduring identity and its evolving implementation, providing a conceptual framework for understanding self-improvement.
Final Thoughts
In designing Fibona as a self-improving agent, we found ourselves returning to a fundamental philosophical question for an agent: “Who am I?” For an agent that can continually change itself, this is not an easy question to answer, as in the well-known philosophical discussions of personal identity and the Ship of Theseus. On another level, this means giving the agent self-awareness: an understanding of what it is and what it can do. Here, we offer a practical answer from our work on the agent harness: the agent’s “self” is a minimal, stable core that cannot be modified but can act (i.e., the engine).
Looking ahead, the generality of this harness and the agent’s ability to write its own next steps leave open a far more ambitious possibility. With AGI widely anticipated in the near future, an agent built on this foundation could create its own tools, develop new capabilities, and construct increasingly complex environments. Step by step, it might build an entire universe of its own, even from a starting point of just a few hundred lines of code.
Check out our complete code on GitHub, try our online demo, or visit our project page to learn more.
References
[1] Zhang, Qizheng, et al. “Agentic Context Engineering: Evolving Contexts for Self-Improving Language Models.” arXiv, 2025.
[2] Srikanth, Dhruv, et al. “Recursive self-improvement of AI research agents.” arXiv, 2026.
[3] Zelikman, Eric, et al. “Self-Taught Optimizer (STOP): Recursively Self-Improving Code Generation.” arXiv, 2023.
[4] Zhang, Jenny, et al. “Darwin Godel Machine: Open-Ended Evolution of Self-Improving Agents.” arXiv, 2025.
[5] Hu, Shengran, Cong Lu, and Jeff Clune. “Automated Design of Agentic Systems.” arXiv, 2024.
[6] Zhang, Jenny, et al. “Hyperagents.” arXiv, 2026.
[7] Zhang, Alex L., Tim Kraska, and Omar Khattab. “Recursive Language Models.” arXiv, 2025.
[8] Karten, Seth, et al. “Prime Agent: A self-improving RLM agent.” Prime Intellect, 2026.
[9] Pi. Agent core documentation. Accessed September 29, 2026.
[10] OpenClaw. Agent loop. Accessed September 29, 2026.
[11] Yao, Shunyu, et al. “ReAct: Synergizing Reasoning and Acting in Language Models.” ICLR, 2023.
[12] Anthropic. “Building agents with the Claude Agent SDK.” 2025.
[13] Bolin, Michael. “Unrolling the Codex agent loop.” OpenAI, January 23, 2026.
[14] OpenAI. Web search. API documentation.
[15] Yin, Xunjian, et al. “Gödel Agent: A Self-Referential Agent Framework for Recursive Self-Improvement.” arXiv, 2024.
[16] Robeyns, Maxime, Martin Szummer, and Laurence Aitchison. “A Self-Improving Coding Agent.” arXiv, 2025.
[17] Zhang, Jiayi, et al. “AFlow: Automating Agentic Workflow Generation.” arXiv, 2024.
[18] Lee, Yoonho, et al. “Meta-Harness: End-to-End Optimization of Model Harnesses.” arXiv, 2026.
[19] Zhang, Hangfan, et al. “Self-Harness: Harnesses That Improve Themselves.” arXiv, 2026.
[20] Nie, Jun, et al. “TTHE: Test-Time Harness Evolution.” arXiv, 2026.
[21] Wang, Xingyao, et al. “Executable Code Actions Elicit Better LLM Agents.” arXiv, 2024.
[22] Wang, Guanzhi, et al. “Voyager: An Open-Ended Embodied Agent with Large Language Models.” arXiv, 2023.
[23] Qiu, Jiahao, et al. “Alita: Generalist Agent Enabling Scalable Agentic Reasoning with Minimal Predefinition and Maximal Self-Evolution.” arXiv, 2025.
[24] Shinn, Noah, et al. “Reflexion: Language Agents with Verbal Reinforcement Learning.” arXiv, 2023.
[25] Packer, Charles, et al. “MemGPT: Towards LLMs as Operating Systems.” arXiv, 2023.
[26] Wikipedia. Personal identity.
[27] Wikipedia. Ship of Theseus.
[28] OpenAI. Function calling. API documentation.
[29] DeepSeek-AI. “DeepSeek Harness: Everything is a Plugin.” GitHub, 2026.
[30] Ye, Haoran, et al. “Meta Context Engineering via Agentic Skill Evolution.” arXiv, 2026.
[31] Anthropic. Claude Code. GitHub. Accessed October 11, 2026.
[32] OpenAI. Codex. GitHub. Accessed October 11, 2026.
[33] OpenClaw. OpenClaw. GitHub. Accessed October 11, 2026.
[34] Nous Research. Hermes Agent. Accessed October 11, 2026.