- Overview
- Features
- Installation
- Quick Start
- Project Structure
- Core Components
- Configuration
- Examples
- License
- Contributing
- Citation
AgenticPay is a framework and benchmark for evaluating LLM/VLM agents in realistic buyer–seller commerce. It extends negotiation beyond text-only, bilateral price haggling into multimodal, multi-dimensional contract negotiation across 4 real-world scenarios (E-commerce, Food Delivery, Ride-hailing, and Apartment Rental) and 8 market topologies, from 1-to-1 bargaining to many-to-many markets. The codebase keeps a Gymnasium-like API for easy integration, reproducible examples, and extensible environment registration.
- 🤖 LLM/VLM-based Agents: Buyer and Seller agents powered by text and vision-language models (OpenAI-compatible APIs, vLLM, SGLang, Qwen3-VL)
- 🖼️ Multimodal Product Grounding: Tasks can include product images, visual route context, listings, menus, and rich text attributes
- 📄 Multi-dimensional Contracts: Agents negotiate complete JSON contracts with price, continuous terms, and discrete terms instead of a single scalar price
- 💬 Multi-turn Conversations: Support for extended natural-language negotiation dialogues with structured contract proposals
- 🧠 Memory and Mental Models: Conversation history plus prompt-level opponent modeling for information-asymmetric bargaining
- 📊 Utility-based Metrics: GlobalScore, BuyerScore, and SellerScore evaluate feasibility, welfare, surplus split, and efficiency
- 🏪 Environment Registration System: Gymnasium-like environment registration for easy environment management
- 🛍️ 160 Benchmark Tasks: 4 scenarios × 8 market topologies × 5 tasks, with additional legacy/demo scripts
- 👥 Multi-Agent Scenarios: Multiple buyers, sellers, and products in parallel or sequential negotiation modes
- 👤 User Profiles: Personal preference system that influences product matching and negotiation behavior
# Create conda environment
conda create -n agenticpay python=3.10 -y
conda activate agenticpay
# Navigate to project directory
cd AgenticPay
# Install dependencies
pip install -r requirements.txt
# Install package in editable mode
pip install -e .Model Download: Download models from Hugging Face and save them to the agenticpay/models/download_models directory for local model usage.
- Configure the project: Copy
agenticpay/examples/config_example.pytoagenticpay/examples/config.pyand set API keys, local model paths, and common environment parameters. - Choose a model backend: The current examples use OpenAI-compatible text/VLM APIs, local VLM backends, and legacy local LLM backends depending on the task:
OpenAIVLM/OpenAILLM— cloud or OpenAI-compatible APIsQwen3VL,SGLangVLM,VLLMLLM— local multimodal/text inference
- Legacy Task1 model invocation examples: For the basic price negotiation task, the repo still provides three example files demonstrating different ways to call LLMs:
Task1_basic_price_negotiation_api_example.py— OpenAI/compatible APITask1_basic_price_negotiation_sglang_example.py— SGLang for local inferenceTask1_basic_price_negotiation_vllm_example.py— vLLM for local inference (multi-GPU)
To quickly try a current multimodal, multi-dimensional contract negotiation task, run one of the scenario scripts:
python agenticpay/examples/single_buyer_product_seller/Task4_s1_beauty_product_negotiation.pyThis script runs a single-buyer/single-seller E-commerce task grounded in a product image and a contract schema with price, delivery time, return policy, packaging, and user preference match.
To run all example groups, use:
bash agenticpay/examples/run_all_examples.shYou can still run the original text-only price negotiation demo with:
python agenticpay/examples/single_buyer_product_seller/Task1_basic_price_negotiation.pyThe low-level environment loop remains the same for legacy price-only tasks and current contract-mode tasks. For full multimodal contract_config examples, see the scenario scripts under agenticpay/examples/*/Task*_s*.py.
from agenticpay import make # Recommended: use registration system
from agenticpay.agents.buyer_agent import BuyerAgent
from agenticpay.agents.seller_agent import SellerAgent
import os
# Local models (SGLang, vLLM, etc.)
from agenticpay.models.sglang_vlm import SGLangVLM
from agenticpay.models.vllm_lm import VLLMLLM
model_path = "agenticpay/models/download_models/Qwen3-VL-8B-Instruct"
# Option 1: SGLang VLM
model = SGLangVLM(model_path=model_path)
# Option 2: vLLM LM (for multi-GPU setups)
# model = VLLMLLM(
# model_path=model_path,
# trust_remote_code=True,
# gpu_memory_utilization=0.9,
# tensor_parallel_size=4, # Number of GPUs
# )
# Create agents with bottom prices (confidential)
buyer_max_price = 120.0 # Maximum acceptable price for buyer
seller_min_price = 80.0 # Minimum acceptable price for seller
buyer = BuyerAgent(model=model, buyer_max_price=buyer_max_price)
seller = SellerAgent(model=model, seller_min_price=seller_min_price)
# Configure reward weights (optional)
reward_weights = {
"buyer_savings": 1.0, # Buyer savings weight
"seller_profit": 1.0, # Seller profit weight
"time_cost": 0.1, # Time cost weight
}
# Create environment using registration system (recommended)
env = make(
"Task1_basic_price_negotiation-v0",
buyer_agent=buyer,
seller_agent=seller,
max_rounds=20,
initial_seller_price=150.0,
buyer_max_price=buyer_max_price,
seller_min_price=seller_min_price,
environment_info={
"temperature": "warm",
"season": "summer",
"weather": "sunny",
},
price_tolerance=0.0,
reward_weights=reward_weights, # Optional: reward weights configuration
)
# User profile (optional text description of personal preferences)
user_profile = "User prefers business/professional style and likes to compare prices before making purchases. In negotiations, they may mention comparing other options and seek better deals."
# Reset and start negotiation
observation, info = env.reset(
user_requirement="I need a high-quality winter jacket",
product_info={
"name": "Premium Winter Jacket",
"brand": "Mountain Gear",
"price": 180.0,
"features": ["Waterproof", "Insulated", "Windproof", "Breathable"],
"condition": "New",
"material": "Gore-Tex",
},
user_profile=user_profile, # Optional
)
# Run negotiation loop
done = False
while not done:
# Buyer responds first
buyer_action = buyer.respond(
conversation_history=observation["conversation_history"],
current_state=observation
)
# Update conversation history with buyer's response
updated_conversation_history = observation["conversation_history"].copy()
if buyer_action:
current_round = observation.get("current_round", 0)
updated_conversation_history.append({
"role": "buyer",
"content": buyer_action,
"round": current_round
})
# Seller responds (can see buyer's message)
seller_action = seller.respond(
conversation_history=updated_conversation_history,
current_state=observation
)
# Execute step with both actions
observation, reward, terminated, truncated, info = env.step(
buyer_action=buyer_action,
seller_action=seller_action
)
done = terminated or truncated
env.render()
print(f"Negotiation ended: {info['status']}")
print(f"Final price: ${info.get('seller_price', 'N/A')}")
env.close()AgenticPay/
├── agenticpay/
│ ├── agents/ # Agent implementations (buyer, seller)
│ ├── envs/ # Environment implementations
│ │ ├── single_buyer_product_seller/ # Basic negotiation
│ │ ├── only_multi_products/ # Multi-product scenarios
│ │ ├── only_multi_seller/ # Multi-seller scenarios
│ │ ├── only_multi_buyer/ # Multi-buyer scenarios
│ │ └── multi_*/ # Complex multi-agent scenarios
│ ├── models/ # LLM/VLM implementations (OpenAI API, vLLM, SGLang, Qwen3-VL)
│ ├── memory/ # Conversation history management
│ ├── results/ # Evaluation outputs and paper-related materials
│ ├── utils/ # Utilities (state, user profile)
│ └── examples/ # Example scripts organized by market topology
├── rm_img/ # README figures
├── README.md
├── setup.py
└── requirements.txt
The framework provides negotiation environments organized by market topology. The latest benchmark instantiates 160 multimodal tasks: 4 real-world scenarios × 8 market topologies × 5 tasks per cell. Several legacy price-only demos remain for backward compatibility.
Basic negotiation scenarios with one buyer, one product, and one seller. The current examples include E-commerce, taxi/ride-hailing, food delivery, and apartment rental tasks, plus legacy price-only demos.
- Task1-3 - Legacy price-only negotiation demos
- Task4+ scenario scripts - Multimodal, multi-dimensional contract tasks such as beauty products, taxi rides, food delivery, and rental housing
Environments for negotiating multiple products or bundled products with a single buyer and seller.
- Task1: Multi-Product Negotiation - General multi-product negotiation
- Task2: Two Product Negotiation - Two products negotiation
- Task3: Five Product Negotiation - Five products negotiation
- Task4: Select Three from Five Negotiation - Product selection and negotiation
Environments with multiple sellers competing for a single buyer, in both parallel and sequential modes.
- Task1-2: Parallel Multi-Seller - Parallel negotiations with multiple sellers
- Task3-4: Sequential Multi-Seller - Sequential negotiations with multiple sellers
Environments with multiple buyers competing for products, in both parallel and sequential modes.
- Task1-2: Parallel Multi-Buyer - Parallel negotiations with multiple buyers
- Task3-4: Sequential Multi-Buyer - Sequential negotiations with multiple buyers
Complex environments with multiple buyers and multiple sellers.
Environments with multiple products and multiple sellers.
Environments with multiple buyers and multiple products.
Full-market environments with multiple buyers, products, and sellers.
Common Environment Methods:
reset(): Initialize a new negotiationstep(): Execute one negotiation turn (accepts agent actions and parses contract proposals)render(): Display current negotiation stateclose(): Close environment and clean up
Abstract base class for all agents.
Subclasses:
BuyerAgent: Represents the buyer, negotiates based on user requirements and budgetSellerAgent: Represents the seller, negotiates based on product information and market conditions
Gymnasium-like environment registration system for easy environment management.
Key Functions:
make(): Create environment instance by IDregister(): Register new environmentspec(): Get environment specificationpprint_registry(): List all registered environments
Usage:
from agenticpay import make
# Single buyer/product/seller
env = make("Task1_basic_price_negotiation-v0", buyer_agent=buyer, seller_agent=seller, max_rounds=20)
# Multi-product
env = make("Task1_multi_product_negotiation-v0", buyer_agent=buyer, seller_agent=seller, max_rounds_per_product=20)
# Multi-seller
env = make("Task1_parallel_two_seller_negotiation-v0", buyer_agent=buyer, seller_agents=[seller1, seller2], max_rounds=20)Manages conversation history and context.
Features:
- Message storage with metadata
- History retrieval (full or recent)
- Role-based filtering
AgenticPay reports utility-based scores for contract-mode tasks:
GlobalScore: Overall welfare, agreement quality, and negotiation efficiencyBuyerScore: Buyer-side normalized utility and efficiencySellerScore: Seller-side normalized utility and efficiency
Common parameters across environments:
max_rounds: Maximum number of negotiation roundsinitial_seller_price: Starting price from sellerbuyer_max_price: Maximum acceptable price for buyer (confidential)seller_min_price: Minimum acceptable price for seller (confidential)price_tolerance: Price difference threshold for agreementenvironment_info: Contextual information (weather, season, etc.)contract_config: Multi-dimensional contract schema and private utility weights for contract-mode tasksreward_weights: Dictionary controlling the relative importance of different reward componentsbuyer_savings: Weight for buyer savings (difference between max price and agreed price)seller_profit: Weight for seller profit (difference between agreed price and min price)time_cost: Weight for time cost (penalty for negotiation rounds)
- BuyerAgent:
buyer_max_price(maximum acceptable purchase price) - SellerAgent:
seller_min_price(minimum acceptable selling price)
User descriptions are passed as strings during negotiation initialization and can affect product preference matching, style, and bargaining behavior.
Current benchmark tasks use contract_config to define:
field_descriptions: Meaning ofprice,continuous_terms, anddiscrete_termscontinuous_bounds: Numeric ranges such as delivery days, wait time, or lease monthsdiscrete_options: Enumerated terms such as return policy, packaging, utilities, or preference matchbuyer_preferences/seller_preferences: Private base values and utility weights used for scoring
Supports multiple providers:
- Vision-Language Models:
OpenAIVLM,Qwen3VL,SGLangVLM- for image-grounded negotiation tasks - Local Text Models:
VLLMLLM- for local text model inference (supports multi-GPU setups) - OpenAI (API):
OpenAILLM- requires API key - Custom/OpenAI-compatible APIs:
CustomLLM- for compatible hosted endpoints
Examples are organized by market topology. Each topology directory contains Task*.py scenario scripts plus a run_all_tasks.sh helper; the root run_all_examples.sh runs all available groups.
-
Single Buyer + Product + Seller (
examples/single_buyer_product_seller/)Task1_basic_price_negotiation_api_example.py- Basic price negotiation via API (OpenAI/compatible)Task1_basic_price_negotiation_sglang_example.py- Basic price negotiation via SGLangTask1_basic_price_negotiation_vllm_example.py- Basic price negotiation via vLLMTask2_close_price_negotiation.py- Close price negotiationTask3_close_to_market_price_negotiation.py- Market price negotiationTask4_s1_beauty_product_negotiation.pyand later scenario scripts - multimodal contract-mode benchmark tasks
-
Multi-Product Negotiations (
examples/only_multi_products/)- Multiple-product and bundle negotiation examples
- Product selection and contract trade-off scenarios
-
Multi-Seller Negotiations (
examples/only_multi_seller/)- Parallel and sequential multi-seller scenarios
-
Multi-Buyer Negotiations (
examples/only_multi_buyer/)- Parallel and sequential multi-buyer scenarios
-
Complex Multi-Agent Scenarios
examples/multi_buyer_multi_seller/- Multiple buyers and sellersexamples/multi_products_multi_seller/- Multiple products and sellersexamples/multi_buyer_multi_products/- Multiple buyers and productsexamples/multi_buyer_multi_products_multi_seller/- Full multi-agent scenarios
The benchmark covers four scenario families: E-commerce, Ride-hailing, Food Delivery, and Apartment Rental. Current task scripts use names such as Task*_s*_taxi_*.py, Task*_s*_food_delivery_*.py, and Task*_s*_rent_house_*.py to indicate scenario instances.
- Create a new environment class inheriting from
BaseEnv - Implement
reset()andstep()methods - Register using the registration system
Example:
from agenticpay.core import BaseEnv
from agenticpay.envs import register
class MyCustomEnv(BaseEnv):
def reset(self, **kwargs):
# Implementation
return observation, info
def step(self, action):
# Implementation
return observation, reward, terminated, truncated, info
# Register environment
register(
id="MyCustomEnv-v0",
entry_point="agenticpay.envs.my_custom_env:MyCustomEnv",
max_episode_steps=100,
)The framework is designed to be extensible. Key extension points:
- Custom reward functions
- Custom contract schemas and utility weights
- Advanced price extraction
- Custom negotiation strategies
- Learning-based agent behaviors
- Additional agent types
- Additional VLM/LLM providers
- Custom memory systems
For detailed guides, see:
ENV_REGISTRATION.md- Environment registration systemPROJECT_STRUCTURE.md- Project structure and extension pointsQUICKSTART.md- Quick start guide
MIT License
Contributions are welcome! Please feel free to submit issues or pull requests.
If you use AgenticPay in your research, please cite:
@article{liu2026agenticpay,
title={AgenticPay: A Multi-Agent LLM Negotiation System for Buyer-Seller Transactions},
author={Liu, Xianyang and Gu, Shangding and Song, Dawn},
journal={arXiv preprint arXiv:2602.06008},
year={2026}
}

