· ARJUN · WRITING
What Challenges Come With Building a Complex Agent?
A complex Agent has to plan across multiple steps, call tools, recover from failures, and verify its own result. This article breaks down five common engineering challenges through a CI investigation that goes off course.
You give a coding agent a task:
Find the cause of last night’s CI failure, fix it, and open a pull request. Do not change the deployment configuration.
It reads the failed job’s logs, searches the codebase, increases a test timeout, reruns the test, and opens a PR. Every tool call returns successfully. The PR even includes a tidy explanation of the root cause.
It looks done.
But the log API returns only the last 500 lines by default. The agent sees test timed out after 60s at the end, but misses an earlier connection-pool exhaustion error. It raises the timeout from 60 to 120 seconds. One local rerun happens to pass, so it records “insufficient test time” as the root cause.
No tool failed. The workflow never stopped. The result still cannot be shipped.
A longer prompt is unlikely to fix this class of failure. The model, plan, tools, external environment, and stop conditions form one execution path. Break that path apart, and the engineering work falls into five challenges: defining reliability, keeping plans aligned with the environment, recovering safely from tool failures, reconstructing and evaluating a bad run, and controlling the cost and latency of the whole system.
Challenge 1: One successful run is still far from reliable
Start with the easiest detail to overlook: what exactly counts as done?
“Fix the CI failure” sounds like a clear goal to a person. To a runtime, it leaves out the important parts: what counts as a root cause, which files must not change, which tests would prove the fix, and when the agent must stop and ask for help.
When those details live only in prose, an agent can quietly treat “PR created” as “problem fixed.” A safer approach is to turn the pieces most likely to disappear during a long run into a checkable Task Contract:
goal: Find the root cause of the CI failure and submit the smallest valid fix
constraints:
- Do not change deployment configuration
- Do not write to production
evidence_required:
- Logs covering the complete failure window
- A reproduction of the original failure
- Passing relevant regression tests
deliverable:
- A pull request containing the root cause, change, and verification evidence
stop_when:
- Logs are incomplete
- The next action requires additional privileges
- Available evidence conflicts
This does not mean turning every natural-language request into a configuration file. It means pinning down four things that are easy to lose across multiple steps: the deliverable, boundaries, evidence, and stop conditions.
The model may choose how to proceed. It should not quietly redefine success halfway through the run.

The same task has to survive repeated runs
Run the same task twice and the agent may choose different tools or take a different route. Sampling is only one source of variation. Search results change, external APIs time out, context gets trimmed, and the repository may have moved since the previous run.
τ-bench evaluates agents in tasks with users, tools, and domain rules. Rather than scoring only the final response, it compares the database state at the end of a conversation with an annotated goal state. It also repeats tasks to measure whether an agent can keep succeeding. That design exposes something a single demo can hide: one passing run proves that run worked. It says little about whether the next run will follow the same rules.
Engineering teams do not need every natural-language trajectory to be identical. They need stable outcomes:
- The final state satisfies the acceptance criteria.
- Permission and business constraints remain intact.
- Every important decision points back to evidence.
- An unknown state stops the workflow before the blast radius grows.
Different execution paths can still produce a reliable result.
Challenge 2: The real environment will interrupt the plan
Complex work usually needs a plan, but “write five steps and follow them” is fragile. Missing logs, an unreproducible test, or an unavailable tool can invalidate the plan immediately.
ReAct interleaves reasoning and acting: take an action, read the environment’s observation, and use that result to choose the next step. Plan-and-Execute starts with a broader plan, executes it incrementally, and can replan when the situation changes. They operate at different levels of control. Neither is the universal answer.
Whichever pattern you use, the plan should live in persistent state instead of only in a paragraph generated by the model:
{
"step": "collect-ci-evidence",
"status": "blocked",
"depends_on": ["locate-failed-job"],
"evidence": ["job:9182/log-page:1"],
"missing": ["earlier_log_pages"],
"retry_budget": 1,
"next": "request-next-log-cursor"
}
Now the runtime can answer practical questions: Where is the run blocked? What evidence does it have? What is missing? May it retry? If the process resumes later, where should it continue?
The previous article on agent planning covers planning approaches in more detail. Here, the narrower question is how a plan is stored, checked, and revised once it reaches a production runtime.
Challenge 3: A successful tool call can still fail the task
A 200 response can still leave out half the evidence.
A tool call can succeed at four different layers:
- Transport: The request receives a response.
- Schema: The fields and types match the interface.
- Semantics: The result is complete, fresh, and relevant to the question.
- Effect: A state-changing action happens once, against the intended object.

The log request in the opening scenario satisfied only the first two. A useful response should expose completeness as data:
{
"status": "ok",
"lines": ["..."],
"window": {
"from": "2026-09-16T23:48:10Z",
"to": "2026-09-16T23:52:31Z"
},
"truncated": true,
"next_cursor": "log-page-2"
}
Schema validation can prevent next_cursor from arriving as an object. It cannot decide whether 500 lines are enough to establish the root cause. A tool contract also needs to describe the data range, source, freshness, truncation, and any side effects caused by the call.
The tool description should say more than “query CI logs.” It should tell the model when to use the tool, what the result cannot prove, which incomplete states it may return, and what to do when one of those states appears.
After a write times out, do not rush to retry it
“Retry up to three times” is an easy default. It can work for some reads. For writes, it can create a second problem.
Suppose the agent asks a Git platform to create a pull request and the client times out. The server may never have received the request. Or it may have created the PR and lost the response on the way back. Retrying immediately can create a duplicate.
A safer sequence looks like this:
Send create request
→ Response times out; outcome is unknown
→ Look for an existing PR by branch or operation identifier
→ Found: record the result and continue
→ Not found: retry only after confirming that replay is safe

Different failures need different policies:
| Failure | Response |
|---|---|
| Temporary network error on a side-effect-free read | Bounded retry with backoff |
| Arguments fail schema validation | Repair the arguments, then call again |
| Authentication or permission failure | Stop; retries cannot grant permission |
| Write times out with an unknown outcome | Reconcile external state before deciding whether to replay |
| Successful response with incomplete evidence | Fetch the missing evidence or mark the step blocked |
An idempotency key can let a service recognize a repeated operation, but only when the server implements that contract. Without it, the runtime should at least persist an operation identifier, the state observed before the call, and a business key it can use for reconciliation.
Recovery is often harder than the first successful call. The system has to know what happened, what was merely prepared, and what remains unknown.
Challenge 4: A bad run has to be reconstructable and measurable
A trace should preserve the scene you need to reconstruct.
Ordinary application logs often record “request started,” “request completed,” and an exception. That is not enough to explain why an agent moved from reading logs to changing a timeout.
A useful trace should connect at least:
- the task version, model version, and prompt version;
- current state and plan step;
- tool name, arguments, response range, and errors;
- latency, token usage, and retry count for each step;
- the reason a replan, stop, or human confirmation occurred;
- the final artifact and the evidence used to verify it.
LangSmith and Langfuse can both capture model calls, tool steps, latency, and token usage. They help collect and inspect that data. They do not decide which business rule is wrong. Your application still has to define the fields, redact sensitive data, and decide which evidence deserves long-term retention.
There is no need to store a model’s hidden chain of thought. Debugging depends on what the application can legitimately observe: inputs, outputs, state transitions, and external actions. Linking those pieces is usually enough to find where the workflow began to drift.
Evaluation should cover more than the final answer
If an evaluation asks only whether the final response reads well, a polished explanation of the wrong diagnosis can score highly. Agent evaluation needs at least three layers.
1. End state
Use deterministic checks where possible: Did the expected files change? Did the tests pass? Did the database reach the target state? Were forbidden operations absent?
2. Execution trajectory
Check whether the agent chose the wrong tool, repeated calls, ignored truncation, exceeded its step budget, or continued with a high-impact action after the evidence became uncertain.
3. Semantic quality
Check whether the root-cause explanation is accurate, whether the evidence supports the claim, and whether the PR description gives a reviewer enough context. A rubric-based LLM-as-a-Judge can help at this layer, but it should not become the only source of truth. Deterministic outcomes, human-labeled examples, and sampled review still matter.
The evaluation set should contain more than happy paths. Include tool timeouts, empty results, truncated data, permission failures, schema changes, duplicate writes, and conflicting evidence.
Then repeat the critical cases. Single-run success tells you whether the agent can complete a task. Repeated success is closer to the reliability a user experiences.

Challenge 5: Every step spends time and budget
Every additional model call, retrieval, or tool round trip adds cost and wait time. A more complex agent may handle a more open-ended task. If it only takes more turns to reach the same result, those steps are spending budget without buying capability.
In Building effective agents, Anthropic recommends starting with the simplest approach that works. Stable tasks with explicit rules often fit a code-orchestrated workflow. Add agent autonomy when the path cannot be fixed in advance and the model genuinely needs to choose the next step from environmental feedback.
Common optimizations need boundaries:
- Route simple requests to a short workflow instead of entering the full agent loop.
- Run independent reads in parallel; keep dependent or state-changing actions ordered.
- Cache only results whose inputs, permissions, and external state remain valid.
- Give each task a step, time, and cost budget. When it runs out, return the evidence collected so far.
- Streaming can show progress earlier. It does not automatically reduce the time required to finish the work in the background.
The goal is not to force the agent to think in fewer steps. It is to make every step earn its place.
Pre-launch checklist
| Check | Question |
|---|---|
| Completion criteria | What final state counts as shipped, rather than merely finished? |
| Permission boundary | Which actions run automatically, require approval, or stay forbidden? |
| Tool contract | Does each response expose source, time range, truncation, and side effects? |
| State persistence | After an interruption, can the runtime identify the last confirmed step? |
| Recovery policy | Do read failures, uncertain writes, and permission errors follow different paths? |
| Execution budget | Are steps, time, tokens, and repeated calls bounded? |
| Trace | Can the final result be traced back to evidence and state transitions? |
| Evaluation set | Does it cover end state, trajectory, failure paths, and repeated runs? |
Go back to the CI investigation. An agent that is ready to ship a change does more than open a pull request. It can show which complete log window supports the diagnosis, how the change follows from that evidence, which tests demonstrate the failure is gone, and which boundaries it left untouched.
Without those pieces, all you have is a tool chain that executed successfully and a summary that sounds like an answer.
Creating a PR only ends the workflow; the task is truly complete only when the root cause has been established and backed by complete evidence.
References
- Yao et al., ReAct: Synergizing Reasoning and Acting in Language Models: Interleaves reasoning traces with actions and uses environmental observations to update later steps.
- Yao et al., τ-bench: Evaluates agents against domain rules, user interaction, tool use, final database state, and reliability across repeated trials.
- Anthropic, Building effective agents: Distinguishes workflows from agents and discusses the tradeoff between flexibility, complexity, latency, and cost.
- Anthropic, Trustworthy agents in practice: Covers tool permissions, human control, and boundaries around consequential actions.
- Google Cloud, Agent observability: Covers model interactions, tool use, latency, errors, and quality monitoring for agents.
- LangSmith Observability and Langfuse Observability: Current implementations and data captured in agent traces.
- OpenAI, GDPval: Discusses the current boundary between automated graders and domain-expert evaluation.
- Original reference article: The starting set of ideas adapted for this article.