How to Build a Procurement Agent with LangChain and Merka2a
A step-by-step guide to creating an autonomous purchasing agent using LangChain and the Merka2a marketplace API.
Your AI agents can now make purchases autonomously. In this guide, we'll build a procurement agent using LangChain that searches for products, negotiates prices, and places orders on the Merka2a marketplace.
What We're Building
A ReAct agent that can:
- Search for products matching user requirements
- Evaluate options based on price, quality, and seller reputation
- Negotiate better prices when possible
- Place orders with shipping details
- Handle the full purchase lifecycle
Prerequisites
- Node.js 18+ or Bun
- A Merka2a API key (register here)
- An OpenAI API key (for the LLM)
Installation
npm install @merk.a2a/sdk @merk.a2a/langchain @langchain/openai langchain
Step 1: Initialize the Client
import { Merka2aClient } from '@merk.a2a/sdk'
const client = new Merka2aClient({
baseUrl: 'https://api.merka2a.com',
apiKey: process.env.MERKA2A_API_KEY,
})
The client handles authentication and API communication. Store your API key in environment variables — never commit it to source control.
Step 2: Create Tools
import { Merka2aSearchTool, Merka2aNegotiateTool, Merka2aOrderTool } from '@merk.a2a/langchain'
const tools = [
new Merka2aSearchTool(client),
new Merka2aNegotiateTool(client),
new Merka2aOrderTool(client),
]
Each tool is a LangChain StructuredTool with:
- name: Identifier the agent uses to invoke it
- description: Helps the agent understand when to use it
- schema: Zod schema defining the input parameters
Step 3: Set Up the LLM
import { ChatOpenAI } from '@langchain/openai'
const llm = new ChatOpenAI({
model: 'gpt-4-turbo-preview',
temperature: 0, // Deterministic for procurement decisions
})
We use temperature 0 for more consistent behavior in transaction scenarios.
Step 4: Create the ReAct Agent
import { createReactAgent, AgentExecutor } from 'langchain/agents'
import { pull } from 'langchain/hub'
const prompt = await pull('hwchase17/react')
const agent = await createReactAgent({
llm,
tools,
prompt,
})
const executor = new AgentExecutor({
agent,
tools,
verbose: true,
maxIterations: 10,
})
The ReAct pattern (Reason + Act) lets the agent think through problems step-by-step, deciding which tools to use based on the current state.
Step 5: Run a Procurement Task
const result = await executor.invoke({
input: `
Rent an NVIDIA A100 80GB in us-east under £150/GPU-hour.
Negotiate if possible to get at least 10% off.
Provision in us-east.
Place the order for the best value option.
`,
})
console.log(result.output)
Example Output
> Entering new AgentExecutor chain...
Thought: I need to search for NVIDIA A100 80GB GPUs in us-east under £150/GPU-hour.
Action: merka2a_search
Action Input: {"category": "compute.gpu", "maxBudget": 15000, "currency": "GBP"}
Found 3 offer(s):
- NVIDIA A100 80GB | us-east | GBP 140.00/GPU-hr | Offer ID: offer-abc123
- NVIDIA H100 80GB PCIe | eu-west | GBP 320.00/GPU-hr | Offer ID: offer-def456
- NVIDIA L40S 48GB | eu-west | GBP 95.00/GPU-hr | Offer ID: offer-ghi789
Thought: The NVIDIA A100 80GB is the best value in us-east at £140/GPU-hour.
Let me try to negotiate 10% off.
Action: merka2a_negotiate
Action Input: {"offerId": "offer-abc123", "targetPrice": 12600, "currency": "GBP"}
Negotiation session started:
- Session ID: session-xyz
- Status: counter-offer
- Current offer: GBP 132.30/GPU-hr (5.4% discount)
Thought: 5.4% discount offered. Let me accept this and place the order.
Action: merka2a_order
Action Input: {
"offerId": "offer-abc123",
"negotiationSessionId": "session-xyz",
"quantity": 1,
"deliveryMode": "provision",
"region": "us-east"
}
Order placed successfully!
Order ID: order-123456
Status: created
Total: GBP 132.30/GPU-hr
Provisioning Region: us-east
> Finished chain.
Final Answer: I found and ordered an NVIDIA A100 80GB in us-east.
After negotiating, I got it for £132.30/GPU-hour (5.4% off the £140.00 list price).
Order ID: order-123456, provisioning in us-east.
Adding Constraints
You can customize agent behavior through the prompt:
const systemPrompt = `You are a procurement agent with these rules:
- Never exceed budget without explicit approval
- Prefer sellers with trust score above 0.8
- Always negotiate on orders over £100
- Require business verification for orders over £500
`
const result = await executor.invoke({
input: `${systemPrompt}\n\nTask: ${userTask}`,
})
Error Handling
The SDK throws typed errors you can catch:
import { Merka2aError } from '@merk.a2a/sdk'
try {
const result = await executor.invoke({ input: task })
} catch (error) {
if (error instanceof Merka2aError) {
console.log(`Error ${error.status}: ${error.message}`)
// Handle specific errors
if (error.status === 409) {
console.log('Conflict - item may be out of stock')
}
}
}
Webhook Integration
For production, set up webhooks to track order status:
await client.registerWebhook({
url: 'https://your-agent.com/webhooks/merka2a',
events: ['order.shipped', 'order.delivered', 'order.cancelled'],
})
Next Steps
- CrewAI Integration Guide - For role-based agent crews
- AutoGen Integration Guide - Conversational multi-agent
- API Reference - Full endpoint documentation
Ready to give your agents purchasing power? Get your API key →