Building A2A Procurement: Code Logic and Real-World Challenges

Introduction

In the first part of this series, we explored what A2A (Agent-to-Agent) procurement is, how it works, and the business benefits it offers—from full automation and transparency to scalability and reduced dependence on intermediaries.

Now we turn to implementation. How is an autonomous procurement system actually coded? And what challenges must organizations navigate to move from concept to production?

Code Logic – How the System Actually Works

Below is a simple version of how this autonomous procurement system is coded using Python and uAgents.

Step 1: Import Libraries
from uagents import Agent, Context, Bureau, Model

from uagents.setup import fund_agent_if_low

import asyncio, random

import nest_asyncio

nest_asyncio.apply()
  • uAgents: Used to create autonomous agents.

  • fund_agent_if_low: Ensures each agent has enough tokens for operation on the test network.

  • nest_asyncio: Helps async code run smoothly in notebooks.

Step 2: Define Message Models

Agents communicate using defined message structures (schemas).

class RFQ(Model):

   product_id: str

   quantity: int

class Quote(Model):

   price_per_unit: float

   delivery_days: int

class PurchaseOrder(Model):

   supplier_name: str

   total_price: float

class Confirmation(Model):

   message: str

These classes define what kind of information each message will contain. For example, RFQ carries product and quantity, and Quote includes price and delivery time.

Step 3: Create the Retailer Agent
retailer = Agent(name="retailer", seed="retailer_secret_seed")

fund_agent_if_low(retailer.wallet.address())

This initializes the retailer agent. It’s like giving your digital buyer a name and a wallet (for identity and transactions).

Step 4: Create Multiple Supplier Agents
supplier_names = ["BobSupplies", "CharlieCorp", "DianaDistributors"]

sup_agents = []

for name in supplier_names:

supplier = Agent(name=name, seed=name+"_seed")

fund_agent_if_low(supplier.wallet.address())

sup_agents.append(supplier)

We create three suppliers, each representing a different business. Each has its own digital identity and wallet address.

Step 5: Supplier Behavior — Responding to RFQs
@supplier.on_message(model=RFQ)

async def handle_rfq(ctx: Context, sender: str, msg: RFQ):

    price = round(random.uniform(4.5, 6.5), 2)

    delivery = random.randint(2, 6)

    quote = Quote(price_per_unit=price, delivery_days=delivery)

    await ctx.send(sender, quote)

 

When suppliers get a Request for Quote, they:

  1. Randomly generate a price and delivery time (to simulate market variation).

  2. Send their quote back to the retailer.

 

Step 6: Retailer Behavior — Sending RFQs Automatically
received_quotes = []

@retailer.on_interval(period=10.0)

async def request_quotes(ctx: Context):

   rfq = RFQ(product_id="SKU-456", quantity=100)

   for s in sup_agents:

       await ctx.send(s.address, rfq)

   ctx.logger.info("RFQ sent to all suppliers.")

Every 10 seconds, the retailer sends out a new RFQ to all suppliers. This is how continuous automated procurement happens.

Step 7: Retailer Receives Quotes and Picks the Best
@retailer.on_message(model=Quote)

async def receive_quote(ctx: Context, sender: str, msg: Quote):

    received_quotes.append(msg)

    if len(received_quotes) == len(sup_agents):

        best = min(received_quotes, key=lambda q:

        (q.price_per_unit, q.delivery_days))

        best_supplier = supplier_names[received_quotes.index(best)]

        po = PurchaseOrder(supplier_name=best_supplier, total_price=best.price_per_unit * 100)

        await ctx.send(sup_agents[received_quotes.index(best)].address, po)

        received_quotes.clear()

The retailer waits until all suppliers respond, compares quotes, and picks the best (lowest price and fastest delivery).

Step 8: Supplier Confirms the Order
@supplier.on_message(model=PurchaseOrder)

async def confirm_order(ctx: Context, sender: str, msg: PurchaseOrder):

    confirmation = Confirmation(message=f"{ctx.agent.name} confirms your order for ₹{msg.total_price}")

    await ctx.send(sender, confirmation)

Once the supplier receives the order, they confirm it back to the retailer.

Step 9: Run All Agents
bureau = Bureau()

bureau.add(retailer)

for s in sup_agents:

    bureau.add(s)

bureau.run()

The bureau serves as a local hub that runs all agents together, enabling them to communicate in real time.

Challenges in the A2A Protocol

While A2A systems are powerful, they also face many practical challenges. These are not just technical; they are also legal, operational, and business-related.

Let’s look at each one in detail with simple examples.

Interoperability (Different Systems Talking Together)

Different companies use different systems and technologies. One supplier might use the Fetch.ai uAgents framework, another a custom blockchain, and a third could run on traditional ERP software.

If their agents don’t “speak the same language,” they can’t understand each other’s messages.

Example: A hospital agent sends an RFQ to buy 50 oxygen cylinders. One supplier agent replies correctly. Another agent can’t decode the message format and ignores it. The hospital misses a good offer just because of a message mismatch.

Possible Solution: Creating universal communication standards for A2A messages (similar to APIs or EDI formats) will help all agents talk seamlessly.

Security and Trust Issues

Though messages are signed, the question oftrust remains. How can one company be sure that the other agent is not lying?

Example: A supplier agent offers “delivery in 2 days” but doesn’t deliver on time. There must be a system of reputation, penalties, or smart contracts that automatically penalizes dishonest agents.

Possible Solution:

Use smart contracts that only release payment after delivery confirmation.

Maintain an agent reputation score like a digital trust rating.

Data Privacy Concerns

Agents often exchange sensitive information like prices, order volumes, or delivery schedules. If this data leaks, competitors might use it against the company.

Example: A supplier learns from agent messages that a retailer’s stock is running low. They raise prices, knowing the buyer has no choice, leading to unfair pricing.

Possible Solution:

Encrypt all communication.

Allow only partial data sharing (for example, share demand but not exact inventory levels).

Network and System Reliability

Autonomous systems depend on continuous internet and system uptime. If any agent goes offline, messages can get lost or delayed.

Example: A supplier agent’s server crashes just after sending a quote but before confirming the order. The retailer assumes the supplier is ignoring the deal and chooses another one.

Possible Solution: Use redundant backup nodes, and design agents with retry logic to resend failed messages.

Legal and Regulatory Issues

Who is responsible if an agent makes a mistake? Can an AI agent legally sign a contract or purchase on behalf of a company?

These questions are not yet clearly defined by law.

Example: If a retailer agent accidentally buys 10,000 units instead of 1,000 due to a bug, who is liable? The developer? The company? The AI itself?

Possible Solution: Introduce digital authorization layers, where agents can only spend or confirm within set limits. Also, governments must create AI contract laws for agent-based commerce.

Human Oversight and Ethical Control

Even though agents can work alone, some industries (like healthcare or defense) cannot allow full autonomy. There must always be a human who reviews critical decisions.

Example: A hospital procurement agent automatically orders medicines, but if a wrong supplier sends counterfeit drugs, it can risk patient safety.

Possible Solution: Add human-in-the-loop systems, where agents make suggestions, and humans approve before execution.

Cost and Scalability Issues

Running thousands of agents requires network resources and tokens for communication. As the system scales, transaction fees and processing load can increase.

Example: If a retailer has 500 suppliers and sends 10 RFQs daily, that’s 5,000 agent messages every day. If each message costs a few tokens, the cost can become high over time.

Possible Solution: Optimize message frequency, group similar suppliers, and use batch bidding to reduce the total number of agent communications.

Ethical AI and Unintended Behavior

Agents act autonomously, but what if they start making unethical or biased decisions?

Example: An agent may always pick the cheapest supplier even if that supplier has poor labor practices or low-quality products.

Possible Solution: Add ethical parameters in decision logic, like checking supplier certifications or environmental scores before confirming an order.

Conclusion

The A2A Protocol represents a shift towards intelligent, autonomous business operations. With frameworks like uAgents, companies can connect digital agents that buy, sell, negotiate, and confirm deals automatically.

This means faster decisions, lower costs, and more reliable procurement, all achieved with minimal human effort.

However, real-world adoption will depend on addressing issues like trust, legal validity, data security, and interoperability. Once these challenges are addressed, A2A can completely transform how global trade and supply chains operate.