Lejdi Prifti

0 %
Lejdi Prifti
Software Engineer • AI Engineer • Blockchain Engineer
  • Email:
    info@lejdiprifti.com
  • Residence:
    Tirana, Albania
  • Agents & Graph Engineering
  • Full-Stack Software Engineering
  • Problem Solving for SMBs
Full-Stack Development
API Design & Integration
Graph Engineering
Coordination & Leadership
Rapid Prototyping
MVP Development
Building Internal Tools
CRM System Development
  • Langchain, LangGraph, OpenAI
  • Java, JavaScript, Python
  • AWS, Kubernetes, Azure
  • Bootstrap, Materialize
  • Css, Sass, Less
  • Blockchain, Ethereum, Solidity
  • React, React Native, Flutter
  • Machine Learning, Deep Learning
0

No products in the basket.

3 Lessons I Learned Building Agentic Workflows

8. August 2026

For the past few months, I’ve been building agentic workflows, experimenting with graphs and agents, and integrating harnesses into them.

Coming from a software engineering background, I’ve found that AI engineering requires a different way of thinking. It introduces a new set of problems, many of which are fundamentally different from the ones we’re used to solving in traditional software engineering.

In this article, I’ll share 3 lessons I’ve learned from building and running agentic workflows over the past year.

Lesson #1: Do We Really Need Bash?

When I started developing my coding workflow, I spent a lot of time researching how some of the best agentic coding tools, such as Claude and Codex, were designed and what best practices they were following.

That’s where I came across a phrase that stuck with me:

“Bash is all you need.”

So, naturally, Bash was one of the first tools I added to my agents.

And it made sense. If you want an agent to behave like a software engineer, why not give it a terminal and let it execute commands just like a developer would?

Well, it turns out there is a downside.

My agents run inside sandboxed environments where they don’t have access to tools such as Maven, Docker, or other development utilities. Once Bash was available, the agents would constantly try to execute commands that would normally be part of a software development workflow.

I tried solving this through prompting. I explicitly told the agents which tools were unavailable and which commands they shouldn’t try to execute.

It didn’t help much. The agents would still attempt to use those tools, resulting in unnecessary LLM calls and wasted tokens.

But there was another problem.

Agents tend to explore.

Give an agent Bash access and it can easily start navigating through directories, inspecting files, checking metadata, and generally looking for more information than it actually needs.

Sometimes that exploration is useful. But in my workflow, most of the time, it wasn’t.

So I made what initially felt like a controversial decision:

I removed Bash.

Maybe we don’t need Bash after all.

The first successful result was immediate. The agents stopped trying to use tools such as Maven and Docker because they simply didn’t have a way to do it.

But something else happened that I found even more interesting.

The agents explored less.

And I don’t necessarily consider that a bad thing.

One of the things I’ve learned about graph-based agentic workflows is that the goal shouldn’t always be to make the agent more capable. Instead, the goal should be to take as much unnecessary responsibility away from the agent as possible.

If I know that an agent is going to execute node X, I can prepare the input it needs before it gets there. The agent doesn’t necessarily need to discover that information itself.

The workflow becomes more like:

Prepare → Execute → Validate → Continue

rather than:

Explore → Decide → Explore → Execute → Explore → Decide

And that distinction matters.

The more freedom you give an agent, the more opportunities you give it to make unnecessary decisions.

So my takeaway wasn’t really that Bash is bad.

It’s that more tools don’t necessarily make an agent better.

Sometimes, the best thing you can do for an agent is to take capabilities away.

In traditional software engineering, we often think about giving components more functionality. With agentic systems, I’ve found myself thinking about the opposite:

What is the minimum amount of freedom this agent needs to do its job well?

That question has changed the way I design my workflows.

Lesson #2: The Devil Is In The Prompt.

An agent is, at its core, a loop of LLM API calls. Apart from the initial prompt, the responses, tool outputs, and other information generated during execution are continuously fed back into the context.

That’s where the magic happens.

And sometimes, that’s where things go wrong.

During one of my workflows, I noticed that agents would occasionally stop and consider the work completed after simply creating a pom.xml file and a few directories.

The task they were supposed to execute was very clear in the prompt.

Yet, every once in a while, the agent would decide that creating the project structure was enough and stop there.

It was rare, but it kept happening. So I had to investigate.

The first place I looked was the prompt.

In my workflow, the prompt isn’t entirely static. Alongside the static instructions, I also inject dynamic instructions and information from the environment based on the current execution state.

The issue usually happened during the initial task, so I logged the complete prompt that was being sent to the model.

And there it was.

Buried inside the first prompt was a sentence that was intended to provide context, but the agent interpreted it as an instruction:

“…scaffold the project, create the directory structure and initial setup.”

The sentence itself wasn’t wrong. The problem was the context in which it appeared.

Because this piece of information was generated programmatically, it wasn’t something I had consciously written as part of the prompt. It also never caught my attention during my prompt evaluations.

So I removed it. All of it.

Since then, I haven’t encountered the same behavior during testing.

That doesn’t mean it will never happen again. With agentic systems, you can rarely be 100% certain about how a model will interpret a given context.

But this experience changed the way I think about prompts.

The prompt isn’t just the instructions you write.

The prompt is everything the agent sees.

Static instructions, dynamic instructions, previous responses, tool outputs, file contents, metadata, state information, and everything else you decide to put into the context can influence the next decision.

And sometimes, something that looks like harmless information to us can look like an instruction to the model.

At the end of the day, LLMs are extremely good at recognizing and following patterns. So if you put ambiguous patterns into the context, you shouldn’t be surprised when the agent follows them.

That’s why I now treat context engineering with the same level of care as prompt engineering.

Don’t just ask yourself, “What instructions did I give the agent?”

Ask:

“What exactly did the agent see before making this decision?”

That question has helped me debug agentic workflows more than once.

Lesson #3: Log. Analyze. Observe.

Working with agents requires patience.

You can run the same workflow multiple times and get different results. Sometimes the differences are small. Other times, the agent makes a completely different decision.

One of the problems I have faced, and continue to face, is unexpected decisions made by the agent.

The interesting part is that these problems don’t necessarily happen consistently. An agent might execute a workflow correctly ten times and then make a completely unexpected decision on the eleventh.

If I didn’t keep track of every execution, its logs, and the decisions made along the way, I could easily make the wrong conclusion.

And sometimes, I have.

That’s why I’ve learned that working with agents requires a different kind of debugging.

You can’t simply look at the latest execution and ask, “Why did this fail?”

You need to look at the history.

What did the agent see?
What tools did it use?
What decisions did it make?
What did the previous steps produce?
How often does this behavior actually happen?

The data is the evidence.

I think of it almost like being an investigator following a trail. Every execution leaves behind tracks. Logs, prompts, tool calls, outputs, errors, decisions, and state changes can all help explain why an agent behaved the way it did.

But logging alone isn’t enough.

You need to analyze those logs and look for patterns.

Once you find a pattern, you can make a change to the workflow and then observe what happens next.

Did the behavior improve?
Did the problem disappear?
Did you introduce a new problem somewhere else?

This creates a continuous loop:

Log → Analyze → Change → Observe → Repeat

And that’s probably one of the biggest differences I’ve experienced between traditional software engineering and agentic engineering.

With traditional software, we often try to reason about the system and implement the correct behavior.

With agentic workflows, you often have to experiment your way toward the correct behavior.

You run an experiment, collect the results, learn from them, change the system, and run it again.

In that sense, agentic workflow development feels inherently agile.

You rarely get everything right on the first attempt. But that’s okay.

Every experiment produces information.

And if you capture that information, analyze it, and use it to improve the next iteration, even a failed execution becomes valuable.

The goal is to build a system that gets better with every execution.

Final Thoughts

After a year of building and running agentic workflows, I’ve realized that AI engineering is not simply about giving an LLM more tools and asking it to do more work.

In many cases, it is almost the opposite.

You need to carefully decide what the agent can do, what information it receives, and how you observe its decisions.

For me, these three lessons have become increasingly important:

Give the agent less.
Show the agent only what it needs.
Observe what it does and learn from it.

Agentic systems are still evolving, and I don’t think there is a perfect formula for building them. What works for one workflow might not work for another.

But that’s also what makes this space interesting.

Thank you for reading!

Posted in Deep Learning, Machine Learning, Technology