Skip to main content

NEGotiations Managed by Agent Simulations

Project description

Python Pypi License Downloads Code Quality Pypi Build Status Coverage Status Coding style black https://static.pepy.tech/personalized-badge/negmas?period=total&units=international_system&left_color=black&right_color=blue&left_text=Downloads

NegMAS is a Python library for developing autonomous negotiation agents embedded in simulation environments. It supports bilateral and multilateral negotiations, multiple negotiation protocols, and complex multi-agent simulations with interconnected negotiations.

Documentation: https://negmas.readthedocs.io/

Installation

pip install negmas

For additional features:

# With Genius bridge support (Java-based agents)
pip install negmas[genius]

# With visualization support
pip install negmas[plots]

# All optional dependencies
pip install negmas[all]

Quick Start

Run a simple negotiation in 10 lines:

from negmas import SAOMechanism, TimeBasedConcedingNegotiator, make_issue
from negmas.preferences import LinearAdditiveUtilityFunction as LUFun

# Define what we're negotiating about
issues = [make_issue(name="price", values=100)]

# Create negotiation session (Stacked Alternating Offers)
session = SAOMechanism(issues=issues, n_steps=50)

# Add buyer (prefers low price) and seller (prefers high price)
session.add(
    TimeBasedConcedingNegotiator(name="buyer"),
    ufun=LUFun.random(issues=issues, reserved_value=0.0),
)
session.add(
    TimeBasedConcedingNegotiator(name="seller"),
    ufun=LUFun.random(issues=issues, reserved_value=0.0),
)

# Run and get result
result = session.run()
print(f"Agreement: {result.agreement}, Rounds: {result.step}")

Multi-issue negotiation with custom preferences:

from negmas import SAOMechanism, AspirationNegotiator, make_issue
from negmas.preferences import LinearAdditiveUtilityFunction

# Create a 2-issue negotiation domain
issues = [
    make_issue(name="price", values=10),
    make_issue(name="quantity", values=5),
]

# Define utility functions
buyer_ufun = LinearAdditiveUtilityFunction(
    values={
        "price": lambda x: 1.0 - x / 10.0,  # lower price = better
        "quantity": lambda x: x / 5.0,  # more quantity = better
    },
    issues=issues,
)
seller_ufun = LinearAdditiveUtilityFunction(
    values={
        "price": lambda x: x / 10.0,  # higher price = better
        "quantity": lambda x: 1.0 - x / 5.0,  # less quantity = better
    },
    issues=issues,
)

# Run negotiation
session = SAOMechanism(issues=issues, n_steps=100)
session.add(AspirationNegotiator(name="buyer"), ufun=buyer_ufun)
session.add(AspirationNegotiator(name="seller"), ufun=seller_ufun)
session.run()

# Visualize
session.plot()

Command Line Interface

NegMAS includes a negotiate CLI for quick experimentation:

# Run with default negotiators
negotiate -s 50

# Specify negotiators and steps
negotiate -n AspirationNegotiator -n NaiveTitForTatNegotiator -s 100

# Use Python-native Genius agents (no Java required)
negotiate -n GBoulware -n GConceder -s 50

# Use custom BOA components
negotiate -n "boa:offering=GTimeDependentOffering(e=0.2),acceptance=GACNext" -n AspirationNegotiator

# Save results and plot
negotiate -s 100 --save-path ./results

See negotiate --help for all options, or the CLI documentation.

Architecture Overview

NegMAS is built around four core concepts:

┌─────────────────────────────────────────────────────────────────┐
│                           WORLD                                 │
│  (Simulation environment where agents interact)                 │
│                                                                 │
│   ┌─────────┐     ┌─────────┐         ┌─────────────────────┐  │
│   │  Agent  │     │  Agent  │   ...   │  BulletinBoard      │  │
│   │         │     │         │         │  (Public info)      │  │
│   └────┬────┘     └────┬────┘         └─────────────────────┘  │
│        │               │                                        │
│        │ creates       │ creates                                │
│        ▼               ▼                                        │
│   ┌─────────────────────────────────────────────────────────┐  │
│   │                    MECHANISM                             │  │
│   │  (Negotiation protocol: SAO, SingleText, Auction, etc.) │  │
│   │                                                          │  │
│   │   ┌────────────┐  ┌────────────┐  ┌────────────┐        │  │
│   │   │ Negotiator │  │ Negotiator │  │ Negotiator │        │  │
│   │   │  + UFun    │  │  + UFun    │  │  + UFun    │        │  │
│   │   └────────────┘  └────────────┘  └────────────┘        │  │
│   └─────────────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────────────┘

Core Components:

  1. Outcome Space (outcomes module) - Issues: Variables being negotiated (price, quantity, delivery date, etc.) - Outcomes: Specific assignments of values to issues - Supports discrete, continuous, and categorical issues

  2. Preferences (preferences module) - UtilityFunction: Maps outcomes to utility values - Built-in types: LinearAdditiveUtilityFunction, MappingUtilityFunction, NonLinearAggregationUtilityFunction, and more - Supports probabilistic and dynamic utility functions

  3. Negotiators (negotiators, sao modules) - Implement negotiation strategies - Built-in: AspirationNegotiator, TitForTatNegotiator, NaiveTitForTatNegotiator, BoulwareTBNegotiator, etc. - Easy to create custom negotiators

  4. Mechanisms (mechanisms, sao modules) - Implement negotiation protocols - SAOMechanism: Stacked Alternating Offers (most common) - Also: Single-text protocols, auction mechanisms, etc.

For Situated Negotiations (World Simulations):

  1. Worlds (situated module) - Simulate environments where agents negotiate - Agents can run multiple concurrent negotiations - Example: Supply chain simulations (SCML)

  2. Controllers (sao.controllers module) - Coordinate multiple negotiators - Useful when negotiations are interdependent

Key Features

  • Multiple Protocols: SAO (Alternating Offers), Single-Text, Auctions, and custom protocols

  • Rich Utility Functions: Linear, nonlinear, constraint-based, probabilistic, dynamic

  • Bilateral & Multilateral: Support for 2+ party negotiations

  • Concurrent Negotiations: Agents can participate in multiple negotiations simultaneously

  • World Simulations: Build complex multi-agent simulations with situated negotiations

  • Genius Integration: Run Java-based Genius agents via the built-in bridge

  • Visualization: Built-in plotting for negotiation analysis

  • Extensible: Easy to add new protocols, negotiators, and utility functions

Creating Custom Negotiators

NegMAS offers two approaches to creating custom negotiators:

  1. Inheritance: Subclass a base negotiator and override methods

  2. Composition: Combine multiple negotiators using MetaNegotiator

Inheritance (Traditional Approach)

Subclass a base negotiator and implement the required methods:

from negmas.sao import SAONegotiator, ResponseType


class MyNegotiator(SAONegotiator):
    """A simple negotiator using inheritance."""

    def propose(self, state, dest=None):
        # Propose a random outcome above reservation value
        return self.nmi.random_outcome()

    def respond(self, state, source=None):
        offer = state.current_offer
        # Accept any offer with utility > 0.8
        if offer is not None and self.ufun(offer) > 0.8:
            return ResponseType.ACCEPT_OFFER
        return ResponseType.REJECT_OFFER

Using the negotiator:

session = SAOMechanism(issues=issues, n_steps=100)
session.add(MyNegotiator(name="custom"), ufun=my_ufun)
session.add(AspirationNegotiator(name="opponent"), ufun=opponent_ufun)
session.run()

Composition (Ensemble Approach)

Use SAOAggMetaNegotiator to combine multiple negotiators and aggregate their decisions:

from negmas.sao import SAOMechanism, ResponseType
from negmas.sao.negotiators import (
    SAOAggMetaNegotiator,
    BoulwareTBNegotiator,
    NaiveTitForTatNegotiator,
)


class MajorityVoteNegotiator(SAOAggMetaNegotiator):
    """An ensemble negotiator that uses majority voting."""

    def aggregate_proposals(self, state, proposals, dest=None):
        # Use the proposal from the first negotiator that offers something
        for neg, proposal in proposals:
            if proposal is not None:
                return proposal
        return None

    def aggregate_responses(self, state, responses, offer, source=None):
        # Majority vote: accept if more than half accept
        accept_count = sum(1 for _, r in responses if r == ResponseType.ACCEPT_OFFER)
        if accept_count > len(responses) / 2:
            return ResponseType.ACCEPT_OFFER
        return ResponseType.REJECT_OFFER


# Create an ensemble of different strategies
ensemble = MajorityVoteNegotiator(
    negotiators=[
        BoulwareTBNegotiator(),  # Tough strategy
        NaiveTitForTatNegotiator(),  # Reactive strategy
        BoulwareTBNegotiator(),  # Another tough vote
    ],
    name="ensemble",
)

# Use in a negotiation
session = SAOMechanism(issues=issues, n_steps=100)
session.add(ensemble, ufun=my_ufun)
session.add(AspirationNegotiator(name="opponent"), ufun=opponent_ufun)
session.run()

The ensemble approach is useful for:

  • Voting strategies: Combine multiple negotiators via majority/weighted voting

  • Dynamic delegation: Switch between strategies at runtime

  • A/B testing: Compare strategies within the same negotiation

Composition (BOA Components)

Use BOANegotiator to build negotiators from reusable components following the Bidding-Opponent modeling-Acceptance (BOA) pattern:

from negmas.gb.negotiators.modular import BOANegotiator
from negmas.gb.components import (
    GSmithFrequencyModel,  # Opponent modeling
    GACTime,  # Acceptance strategy
    GTimeDependentOffering,  # Offering strategy
)

# Create a BOA negotiator with Genius-style components
negotiator = BOANegotiator(
    offering=GTimeDependentOffering(e=0.2),  # Boulware-style offering
    acceptance=GACTime(t=0.95),  # Accept after 95% of time
    model=GSmithFrequencyModel(),  # Opponent frequency model
    name="my_boa_agent",
)

The BOA approach is useful for:

  • Mix-and-match: Combine different strategies from the Genius library

  • Research: Easily swap components to compare different strategies

  • Extensibility: Create custom components that integrate with existing ones

Creating Custom Protocols

from negmas import Mechanism, MechanismStepResult


class MyProtocol(Mechanism):
    def __call__(self, state, action=None):
        # Implement one round of your protocol
        # Return MechanismStepResult with updated state
        ...
        return MechanismStepResult(state=state)

Running World Simulations

For complex scenarios with multiple agents and concurrent negotiations:

from negmas.situated import World, Agent


class MyAgent(Agent):
    def step(self):
        # Called each simulation step
        # Request negotiations, respond to events, etc.
        pass


# See SCML package for a complete example
# pip install scml

Citation

If you use NegMAS in your research, please cite:

@inproceedings{mohammad2021negmas,
  title={NegMAS: A Platform for Automated Negotiations},
  author={Mohammad, Yasser and Nakadai, Shinji and Greenwald, Amy},
  booktitle={PRIMA 2020: Principles and Practice of Multi-Agent Systems},
  pages={343--351},
  year={2021},
  publisher={Springer},
  doi={10.1007/978-3-030-69322-0_23}
}

Reference:

Mohammad, Y., Nakadai, S., Greenwald, A. (2021). NegMAS: A Platform for Automated Negotiations. In: PRIMA 2020. LNCS, vol 12568. Springer. https://doi.org/10.1007/978-3-030-69322-0_23

The NegMAS Ecosystem

NegMAS is the core of a broader ecosystem for automated negotiation research:

NegMAS Ecosystem

Competition Frameworks

  • anl - Automated Negotiation League (ANAC negotiation track)

  • scml - Supply Chain Management League

Agent Repositories

Bridges & Extensions

Visualization & Tools

  • negmas-app - Applications and interfaces for NegMAS

  • scml-vis - SCML visualization

  • jnegmas - Java interface (not maintained)

Specialized Tools

  • negmas-elicit - Preference Elicitation during Negotiation Methods

More Resources

Papers Using NegMAS

Selected papers (see full list):

Core NegMAS Research (by the NegMAS authors)

Competition & Benchmarks

Negotiation Strategies

Applications

Last updated: February 2026

Contributing

Contributions are welcome! Please see the contributing guide.

License

NegMAS is released under the BSD 3-Clause License.

AI Assistance Disclosure

This project uses AI assistance for specific, limited tasks while remaining predominantly human-developed:

  • Publications list: AI assisted in compiling and formatting the publications list

  • Documentation polishing: AI assisted in proofreading and improving documentation clarity

  • gb.components.genius module: AI assisted in reimplementing Genius BOA components in NegMAS

  • Registry feature: AI assisted in developing the negotiator/mechanism registry system

  • Some tests: AI assisted in writing tests, particularly for new features like the registry

All AI-assisted contributions are reviewed and approved by human maintainers. The core architecture, algorithms, and research direction of NegMAS are human-driven and will remain so.

Acknowledgements

NegMAS was developed at the NEC-AIST collaborative laboratory. It uses scenarios from ANAC 2010-2018 competitions obtained from the Genius Platform.

Project details


Release history Release notifications | RSS feed

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

negmas-0.15.4.tar.gz (785.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

negmas-0.15.4-py3-none-any.whl (858.4 kB view details)

Uploaded Python 3

File details

Details for the file negmas-0.15.4.tar.gz.

File metadata

  • Download URL: negmas-0.15.4.tar.gz
  • Upload date:
  • Size: 785.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for negmas-0.15.4.tar.gz
Algorithm Hash digest
SHA256 a38982c637e905bdcd84da02923177a460c37f2c57e09523665c4ba3b87c407a
MD5 a0574951aae296e5aec726bc7df09753
BLAKE2b-256 810b1d715d7e8477cc7878aba5a1c0bf98d895d401905dd054baab754c2651f8

See more details on using hashes here.

File details

Details for the file negmas-0.15.4-py3-none-any.whl.

File metadata

  • Download URL: negmas-0.15.4-py3-none-any.whl
  • Upload date:
  • Size: 858.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for negmas-0.15.4-py3-none-any.whl
Algorithm Hash digest
SHA256 ddfc01fd9f5409b65002a0fc96c9c76ca5e151c4f5b397a4bf66b387c3ae64cb
MD5 47d3c3be2a4cf2c7778b4642136f58b3
BLAKE2b-256 9e1767bb9256a09c04e248c3d960ccd7f21dc56da744eabfaa10fc3c032fda04

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page