Inside PAXAFE’s AI Agent Harness: Building Agentic AI for Supply Chains
The three primitives: agent, tools, and skills
We're seeing a trend in most of our customer conversations over the past few months where AI has graduated from a nice to have to a must have when they evaluate our platform. When customers say AI they are almost always referring to an LLM style offering, either a chat interface or something generative, rather than the more traditional ML prediction systems. This shift has been fascinating to watch from the inside. The data team at PAXAFE has been building and refining predictive models for logistics and supply chain since the platform's inception in 2020 (estimated time of arrival, advanced temperature prediction, risk prediction and so on) and those models now form the core of what we do. We'll be covering each of them in their own technical deep dive over the coming months. This first post is about something newer: how we built our own agent harness, which now powers several parts of the platform, and what we learned once real users got their hands on it.
What agentic actually means
Every AI chat app you use these days, ChatGPT, Claude, Gemini, is agentic now. What does that really mean? Not long ago all of these apps were text in and text out, with no access to any information the model hadn't seen at training time. Today they browse the internet, hit external APIs, write code to query databases, produce charts, open GitHub pull requests, and the list keeps growing. That transition happened because the models got very good at writing code and, more importantly, were given an execution environment to run it in. That combination is what unlocked the ability to work on complex tasks end to end, and that is what agentic means: the ability to execute a task independently until it is done.
The primitive underneath all of it is the tool. A tool is a piece of code that connects the model to the outside world and lets it take an action on your behalf. So the natural starting point for us was to build the arsenal of tools our agent would need: access to shipment telemetry and carrier events, the lane a shipment is running on, and the products moving on that lane. With those in hand the agent has enough autonomy to read a user's question, draft a plan, decide which tools it needs to call, and then go execute, spinning off sub agents asynchronously where the plan allows it.
Tools, and how to design them
We know what tools do. What matters more is what we decided they would not do, which is write anything. Every tool in our harness is read only, and that was deliberate from day one.
Our customers are pharmaceutical manufacturers and their 3PLs. The shipment record in our platform is often what a quality team reaches for when deciding whether a batch gets released or destroyed, and it may end up in a regulatory audit. An LLM is a probabilistic system. It is very good and it is also occasionally confidently wrong. The fix for that is not a longer system prompt asking it to be careful. The fix is to make the bad outcome impossible to express. There is no write tool in the registry, so the model can be as wrong as it likes about a shipment and the worst case is a wrong sentence on a screen, never a changed record.
The same idea runs one level down. Each tool is a typed schema plus a function that executes on our server, and the model only ever sees the schema. It never gets credentials, never writes SQL, never touches the database directly. Organization scoping is not an argument the model fills in. It lives inside the data helpers every tool calls, so one customer's agent asking for "all shipments last month" cannot resolve to another customer's data no matter how the question is phrased. Row limits sit in the schema too, so a sloppy question returns a capped result instead of half our telemetry table.
In practice this is pretty boring, which is the point. Someone asks which UPS shipments had excursions last month and the model emits:
search_shipments({ carrier: "UPS", has_excursion: true, days: 30, limit: 200 })
The schema gives the model a strict contract for valid inputs, making every tool call predictable and auditable.
Ask how a lane is doing and it calls get_lane_performance({ lane_id, days: 30 }), which returns on time rate, transit distribution and excursion counts. Ask something comparative, say excursion rate by carrier week over week, and it reaches for aggregate_shipments with a dimension, a metric and a bucket, and gets buckets back instead of raw rows.
Typed calls also mean the audit trail comes for free. When we read back what the agent did, we are reading a list of function calls with typed arguments, not reverse engineering intent out of generated SQL. For a customer base that lives in audits, that turned out to matter more than we expected.
What is an agent?
Strip it back and an agent is three things: a model, a loop, and a few tools. The model looks at the question and picks a tool, the loop hands the result back and asks whether it has enough, and that repeats until it does. Everything else people call an agent framework is scaffolding around those three things.
That is a more useful realization than it sounds, because once you have the engine you get to choose what sits in front of it. Put a chat interface in front and you have a capable chat experience where someone types a question and the agent goes and answers it. Put a scheduler in front instead, one that watches telemetry and carrier milestones as they land, and the same engine becomes a monitoring system that looks at shipments nobody asked about and raises the ones that need attention. That second mode comes with its own set of architectural problems, and it gets its own post.
Why reading the traces matters
We put the chat version in front of real users and the reactions were genuinely great. People liked it, demos went well, and internally it felt like we had shipped something significant. Then we went and read the traces.
The median conversation was two to three turns. The questions were things like "where is shipment X", "which shipments are delayed right now", "show me excursions on this lane last week". The agent answered all of them correctly and quickly, and there is nothing wrong with any of those questions. But we had a golden question set we had been evaluating against internally, full of much harder multi hop questions, and the agent was scoring well on those too.
So we were sitting on a system that could reason across a customer's entire shipment network, and it was being used almost entirely as a faster search bar. That was a frustrating thing to learn. None of the users knew the harder questions were available to ask, and nothing about a blank text box told them.
Skills get the most out of the model
The model could answer the hard questions. What it couldn't do was know which question was worth asking. That knowledge lived with our customers' quality and logistics teams, not with us and definitely not with the model.
A skill is our answer to that. It is a named, parameterized prompt that shows up in a menu next to the composer. You pick one, fill in a lane and a time window, and it sends the kind of question we had been writing in our eval set. No new tools, no new model, just a better question composed by someone who knows what a good question looks like.
PAXAFE pairs open-ended chat with predefined expert investigations.
The difference in output is not subtle. Ask a basic question about a lane and you get the on time rate. Run our lane review skill against the same lane and it pulls the performance history, breaks delays down by carrier and by leg, cross references excursion clusters against the specific handoff points where they occurred, compares all of it against the prior period, and comes back with a ranked set of things worth doing something about, every claim tied to shipments you can click into. That is analysis that would take an analyst hours, and in practice it is analysis most analysts would never run, because you have to already know to look at the handoff level. It also turned out to be a big unlock for teams that needed bespoke reporting for QBRs and had been assembling it by hand.
Skills are the cheapest lever we have. They cost a prompt. They get written by the people who understand the domain rather than the people who maintain the harness. And they double as documentation, because users read the menu, see what the system can do, and start typing harder questions of their own.
Where this goes next
Model, loop, tools, and a layer of skills on top so the right questions get asked. That is the harness, and it is less code than most people expect. The interesting problems start when you take the chat box away and let the same engine run on a schedule against every shipment in the network, deciding on its own when something is worth a second look and when it isn't. Stay tuned for the next post.
Triggers and schedulers let the engine act on its own. It monitors shipments and escalates what needs attention.
FAQ
What's the difference between an AI agent and a traditional ML model?
A traditional ML model (like ETA or risk prediction) outputs a single prediction from fixed inputs. An AI agent uses an LLM in a loop — it decides which tools to call, gathers information dynamically, and keeps working until the task is done, rather than producing one static output.
Why did PAXAFE make its AI agent read-only?
Because the shipment record often determines whether a pharmaceutical batch gets released or destroyed, and may end up in a regulatory audit. Making every tool read-only means the agent can be wrong in a sentence, but it can never alter the underlying data — the worst-case outcome is contained by design, not by prompting.
What is a "tool" in an AI agent architecture?
A tool is a typed schema plus a server-side function that lets the model take an action — like querying shipment telemetry — without ever touching credentials, writing SQL, or seeing the database directly. The model only sees the schema and decides when to call it.
What is an agent harness?
An agent harness is the underlying system of a model, a loop, and a set of tools that lets an LLM reason over a task and execute it step by step. The same harness can power very different products depending on what's placed in front of it — a chat interface, a monitoring scheduler, and so on.
What are "skills" in an AI agent, and how are they different from tools?
Skills are named, parameterized prompts — not new tools or models — that encode the kind of question a domain expert would know to ask. They surface in a menu so users can run sophisticated, multi-step analysis without having to know it's possible.
Is AI replacing ML-based predictions in supply chain and logistics?
No — at PAXAFE, ML prediction models (ETA, temperature, risk) remain the core of the platform. LLM-based agents are a newer, complementary layer built on top, handling investigation and reasoning tasks that traditional prediction models aren't designed for.
How do you keep an AI agent from leaking data across customers?
Organization scoping and row limits are enforced inside the data-access layer itself, not left to the model to respect. That way, no matter how a question is phrased, the agent's tool calls can't resolve to another customer's data.