Back to Blog
Tutorial4 min read

How to Build a Procurement Agent with LangChain and Levva

A step-by-step guide to creating an autonomous purchasing agent using LangChain and the Levva marketplace API.

Levva Team·

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 Levva 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 Levva API key (register here)
  • An OpenAI API key (for the LLM)

Installation

npm install @axm/sdk @axm/langchain @langchain/openai langchain

Step 1: Initialize the Client

import { AXMClient } from '@axm/sdk'

const client = new AXMClient({
  baseUrl: 'https://api.levva.uk',
  apiKey: process.env.LEVVA_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 { AXMSearchTool, AXMNegotiateTool, AXMOrderTool } from '@axm/langchain'

const tools = [
  new AXMSearchTool(client),
  new AXMNegotiateTool(client),
  new AXMOrderTool(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: `
    Find a wireless mouse under £50.
    Negotiate if possible to get at least 10% off.
    Ship to London, UK (EC1A 1BB), standard shipping.
    Place the order for the best value option.
  `,
})

console.log(result.output)

Example Output

> Entering new AgentExecutor chain...

Thought: I need to search for wireless mice under £50.
Action: axm_search
Action Input: {"category": "electronics.mice", "maxBudget": 50, "currency": "GBP"}

Found 3 product(s):
- Logitech MX Master 3S | GBP 45.99 | Offer ID: offer-abc123
- Razer DeathAdder | GBP 39.99 | Offer ID: offer-def456
- Microsoft Arc Mouse | GBP 49.99 | Offer ID: offer-ghi789

Thought: The Logitech MX Master 3S is the best quality option at £45.99.
Let me try to negotiate 10% off.
Action: axm_negotiate
Action Input: {"offerId": "offer-abc123", "targetPrice": 4139, "currency": "GBP"}

Negotiation session started:
- Session ID: session-xyz
- Status: counter-offer
- Current offer: GBP 43.50 (5.4% discount)

Thought: 5.4% discount offered. Let me accept this and place the order.
Action: axm_order
Action Input: {
  "offerId": "offer-abc123",
  "negotiationSessionId": "session-xyz",
  "quantity": 1,
  "shippingCountry": "GB",
  "shippingCity": "London",
  "shippingPostalCode": "EC1A 1BB",
  "shippingMethod": "standard"
}

Order placed successfully!
Order ID: order-123456
Status: created
Total: GBP 43.50
Estimated Delivery: 2026-03-20

> Finished chain.

Final Answer: I found and ordered a Logitech MX Master 3S wireless mouse.
After negotiating, I got it for £43.50 (5.4% off the £45.99 list price).
Order ID: order-123456, estimated delivery March 20th.

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 { AXMError } from '@axm/sdk'

try {
  const result = await executor.invoke({ input: task })
} catch (error) {
  if (error instanceof AXMError) {
    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/levva',
  events: ['order.shipped', 'order.delivered', 'order.cancelled'],
})

Next Steps


Ready to give your agents purchasing power? Get your API key →

Ready to build with Levva?

Start integrating your AI agents with the marketplace today.