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.1.post1.tar.gz (776.7 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.1.post1-py3-none-any.whl (851.7 kB view details)

Uploaded Python 3

File details

Details for the file negmas-0.15.1.post1.tar.gz.

File metadata

  • Download URL: negmas-0.15.1.post1.tar.gz
  • Upload date:
  • Size: 776.7 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.1.post1.tar.gz
Algorithm Hash digest
SHA256 18dea45c0059d60c42705db4fd28d0f9fb4cfa4c59a94b36dcd59bbbbb18ed01
MD5 eaa31e0c179b3aa5d6b6eed60526dfd0
BLAKE2b-256 ba6fb6d89b87a76d62ecf4436e673f751ac09e052a00b4bfcf68f5e573312649

See more details on using hashes here.

File details

Details for the file negmas-0.15.1.post1-py3-none-any.whl.

File metadata

  • Download URL: negmas-0.15.1.post1-py3-none-any.whl
  • Upload date:
  • Size: 851.7 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.1.post1-py3-none-any.whl
Algorithm Hash digest
SHA256 3c7bde084a16efdf3c47a9d0c6b2929ceb7a368ff0408a729b5a11f78bef263c
MD5 003b4e25f47fd4e3a0db82e5ccd39232
BLAKE2b-256 cca0a25b80ba89aa67ddf7fb025bf00e4fce892e32880c7fbf92728d10e493ea

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