Metadata-Version: 2.4
Name: a_mailx
Version: 0.1.0
Summary: A Multi-Agent Communication Protocol Solution Based on LangGraph
Home-page: https://github.com/dev-yang-ai/A_mail
Author: yanghhhhh
Author-email: developer_yang@qq.com
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: addict==2.4.0
Requires-Dist: aiohappyeyeballs==2.6.1
Requires-Dist: aiohttp==3.12.15
Requires-Dist: aiosignal==1.4.0
Requires-Dist: aiosqlite==0.21.0
Requires-Dist: annotated-types==0.7.0
Requires-Dist: anthropic==0.64.0
Requires-Dist: anyio==4.10.0
Requires-Dist: argon2-cffi==25.1.0
Requires-Dist: argon2-cffi-bindings==25.1.0
Requires-Dist: arrow==1.3.0
Requires-Dist: asttokens==3.0.0
Requires-Dist: async-lru==2.0.5
Requires-Dist: attrs==25.3.0
Requires-Dist: babel==2.17.0
Requires-Dist: beautifulsoup4==4.13.4
Requires-Dist: bleach==6.2.0
Requires-Dist: certifi==2025.8.3
Requires-Dist: cffi==1.17.1
Requires-Dist: charset-normalizer==3.4.2
Requires-Dist: click==8.2.1
Requires-Dist: colorama==0.4.6
Requires-Dist: comm==0.2.3
Requires-Dist: dataclasses-json==0.6.7
Requires-Dist: datasets==1.18.4
Requires-Dist: ddgs==9.5.2
Requires-Dist: debugpy==1.8.16
Requires-Dist: decorator==5.2.1
Requires-Dist: defusedxml==0.7.1
Requires-Dist: dill==0.3.8
Requires-Dist: distro==1.9.0
Requires-Dist: duckduckgo_search==8.1.1
Requires-Dist: executing==2.2.0
Requires-Dist: fastjsonschema==2.21.1
Requires-Dist: filelock==3.18.0
Requires-Dist: fqdn==1.5.1
Requires-Dist: frozenlist==1.7.0
Requires-Dist: fsspec==2024.2.0
Requires-Dist: greenlet==3.2.3
Requires-Dist: h11==0.16.0
Requires-Dist: httpcore==1.0.9
Requires-Dist: httpx==0.28.1
Requires-Dist: httpx-sse==0.4.1
Requires-Dist: huggingface-hub==0.34.3
Requires-Dist: idna==3.10
Requires-Dist: ipykernel==6.30.1
Requires-Dist: ipython==9.4.0
Requires-Dist: ipython_pygments_lexers==1.1.1
Requires-Dist: isoduration==20.11.0
Requires-Dist: jedi==0.19.2
Requires-Dist: Jinja2==3.1.6
Requires-Dist: jiter==0.10.0
Requires-Dist: json5==0.12.0
Requires-Dist: json_repair==0.40.0
Requires-Dist: jsonpatch==1.33
Requires-Dist: jsonpointer==3.0.0
Requires-Dist: jsonschema==4.25.0
Requires-Dist: jsonschema-specifications==2025.4.1
Requires-Dist: jupyter-events==0.12.0
Requires-Dist: jupyter-lsp==2.2.6
Requires-Dist: jupyter_client==8.6.3
Requires-Dist: jupyter_core==5.8.1
Requires-Dist: jupyter_server==2.16.0
Requires-Dist: jupyter_server_terminals==0.5.3
Requires-Dist: jupyterlab==4.4.5
Requires-Dist: jupyterlab_pygments==0.3.0
Requires-Dist: jupyterlab_server==2.27.3
Requires-Dist: langchain==0.3.27
Requires-Dist: langchain-anthropic==0.3.18
Requires-Dist: langchain-community==0.3.27
Requires-Dist: langchain-core==0.3.74
Requires-Dist: langchain-deepseek==0.1.4
Requires-Dist: langchain-openai==0.3.28
Requires-Dist: langchain-qwq==0.2.0
Requires-Dist: langchain-text-splitters==0.3.9
Requires-Dist: langgraph==0.6.4
Requires-Dist: langgraph-checkpoint==2.1.1
Requires-Dist: langgraph-checkpoint-sqlite==2.0.11
Requires-Dist: langgraph-prebuilt==0.6.4
Requires-Dist: langgraph-sdk==0.2.0
Requires-Dist: langsmith==0.4.11
Requires-Dist: lark==1.2.2
Requires-Dist: lxml==6.0.0
Requires-Dist: MarkupSafe==3.0.2
Requires-Dist: marshmallow==3.26.1
Requires-Dist: matplotlib-inline==0.1.7
Requires-Dist: mistune==3.1.3
Requires-Dist: modelscope==1.28.2
Requires-Dist: multidict==6.6.3
Requires-Dist: multiprocess==0.70.16
Requires-Dist: mypy_extensions==1.1.0
Requires-Dist: nbclient==0.10.2
Requires-Dist: nbconvert==7.16.6
Requires-Dist: nbformat==5.10.4
Requires-Dist: nest-asyncio==1.6.0
Requires-Dist: notebook==7.4.5
Requires-Dist: notebook_shim==0.2.4
Requires-Dist: numpy==2.3.2
Requires-Dist: openai==1.98.0
Requires-Dist: orjson==3.11.1
Requires-Dist: ormsgpack==1.10.0
Requires-Dist: overrides==7.7.0
Requires-Dist: packaging==25.0
Requires-Dist: pandas==2.3.1
Requires-Dist: pandocfilters==1.5.1
Requires-Dist: parso==0.8.4
Requires-Dist: platformdirs==4.3.8
Requires-Dist: primp==0.15.0
Requires-Dist: prometheus_client==0.22.1
Requires-Dist: prompt_toolkit==3.0.51
Requires-Dist: propcache==0.3.2
Requires-Dist: psutil==7.0.0
Requires-Dist: pure_eval==0.2.3
Requires-Dist: pyarrow-hotfix==0.7
Requires-Dist: pycparser==2.22
Requires-Dist: pydantic==2.11.7
Requires-Dist: pydantic-settings==2.10.1
Requires-Dist: pydantic_core==2.33.2
Requires-Dist: Pygments==2.19.2
Requires-Dist: python-dateutil==2.9.0.post0
Requires-Dist: python-dotenv==1.1.1
Requires-Dist: python-json-logger==3.3.0
Requires-Dist: pytz==2025.2
Requires-Dist: pywin32==311
Requires-Dist: pywinpty==2.0.15
Requires-Dist: PyYAML==6.0.2
Requires-Dist: pyzmq==27.0.1
Requires-Dist: referencing==0.36.2
Requires-Dist: regex==2025.7.34
Requires-Dist: requests==2.32.4
Requires-Dist: requests-toolbelt==1.0.0
Requires-Dist: responses==0.18.0
Requires-Dist: rfc3339-validator==0.1.4
Requires-Dist: rfc3986-validator==0.1.1
Requires-Dist: rfc3987-syntax==1.1.0
Requires-Dist: rpds-py==0.27.0
Requires-Dist: Send2Trash==1.8.3
Requires-Dist: setuptools==78.1.1
Requires-Dist: six==1.17.0
Requires-Dist: sniffio==1.3.1
Requires-Dist: soupsieve==2.7
Requires-Dist: SQLAlchemy==2.0.42
Requires-Dist: sqlite-vec==0.1.6
Requires-Dist: stack-data==0.6.3
Requires-Dist: tenacity==9.1.2
Requires-Dist: terminado==0.18.1
Requires-Dist: tiktoken==0.9.0
Requires-Dist: tinycss2==1.4.0
Requires-Dist: toml==0.10.2
Requires-Dist: tomli==2.2.1
Requires-Dist: tornado==6.5.2
Requires-Dist: tqdm==4.67.1
Requires-Dist: traitlets==5.14.3
Requires-Dist: types-python-dateutil==2.9.0.20250809
Requires-Dist: typing-inspect==0.9.0
Requires-Dist: typing-inspection==0.4.1
Requires-Dist: typing_extensions==4.14.1
Requires-Dist: tzdata==2025.2
Requires-Dist: uri-template==1.3.0
Requires-Dist: urllib3==2.5.0
Requires-Dist: wcwidth==0.2.13
Requires-Dist: webcolors==24.11.1
Requires-Dist: webencodings==0.5.1
Requires-Dist: websocket-client==1.8.0
Requires-Dist: wheel==0.45.1
Requires-Dist: xxhash==3.5.0
Requires-Dist: yarl==1.20.1
Requires-Dist: zstandard==0.23.0
Dynamic: author
Dynamic: author-email
Dynamic: classifier
Dynamic: description
Dynamic: description-content-type
Dynamic: home-page
Dynamic: license-file
Dynamic: requires-dist
Dynamic: requires-python
Dynamic: summary

<p align="center">
  <img src="./image/logo.png" alt="Logo" width="500">
</p>


# A_mail — A Multi-Agent Communication Protocol Solution Based on LangGraph

[简体中文](README_zh.md) | English Version

## Table of Contents

- [Acknowledgements](#acknowledgements)
- [Introduction](#introduction)
- [Problems Encountered](#problems-encountered)
- [Solution Approach](#solution-approach)
- [A_mail_demo System Features and Limitations](#a_mail_demo-system-features-and-limitations)
- [Quick Start Guide](#quick-start-guide)
  - [1. Clone the Repository](#1-clone-the-repository)
  - [2. Install Dependencies](#2-install-dependencies)
  - [3. Configure the Model](#3-configure-the-model)
  - [4. Design Prompts](#4-design-prompts)
  - [5. Develop Tools](#5-develop-tools)
  - [6. Run the System](#6-run-the-system)
- [Prompt Writing Instructions](#prompt-writing-instructions)
- [Tool Development Instructions](#tool-development-instructions)
- [Example Projects](#example-projects)
- [License](#license)
- [Final Notes](#final-notes)

---

## Acknowledgements

> 🙏 **Special Thanks to LangGraph** 
> 
> We would like to express our sincere gratitude to the **[LangGraph](https://github.com/langchain-ai/langgraph)** framework for providing powerful multi-agent architecture support and convenient API tools. The rich architectural patterns and robust functionality of LangGraph laid the foundation for A_mail's development. Without LangGraph's excellent framework support, this project would not have been possible.

---
 
## Introduction

LangGraph provides rich multi-agent architecture patterns (such as network architecture, Supervisor architecture, hierarchical architecture, etc.) along with convenient API tools, making it easy for developers to quickly build systems.

However, in actual development, **building complex multi-agent systems that integrate multiple architectural patterns still requires a lot of coding work**, especially when it comes to routing design. Prompt engineering also demands significant experience.

---

## Problems Encountered

In early development, I used the most direct approach to implement routing between Agents: using a large number of `if...else...` statements and command calls.

As the system scaled from 6 Agents to 14, then to 16 (because models are far less capable than we initially assumed, so tasks had to be more granular, leading to more agents), problems gradually emerged:

- Routing logic was hardcoded, making it difficult to extend — violating the **Open/Closed Principle**
- Routing logic was pre-created — violating the **Creator Principle**
- Routing rules were tightly coupled with prompts, causing cascading issues when changes were made

If continued this way, both system expansion and maintenance would become extremely difficult.

---

## Solution Approach

Is there a way to introduce an **intermediate layer** to solve this problem?

This intermediate layer defines a unified **output format** and **parsing rules**, responsible for forwarding messages between all Agents, eliminating direct dependencies between them.

![](./image/parse_forward_en.drawio.svg)

Thus, **A_mail** was born.

> **A_mail = Structured Output + Corresponding Parsing Rules**

See details in:

`sra_mail/core/sys_prompt.py`

It abstracts communication between agents into "mail"-like objects (inspired by the Command Pattern) and implements automatic routing, state saving/restoration, and fast prototyping via a mediator module:

- **Automatic Routing**
- **State Saving & Recovery**
- **Rapid Prototype Iteration**

This allows developers to focus on overall architecture design, prompt optimization, and tool development (with AI-assisted design support), without being slowed down by tedious routing code.


When the number of agents increases, the structure will look like this:



![](./image/al_en.drawio.svg)


---

## A_mail_demo System Features and Limitations

### ✅ What Our System Can Do

| Feature | Description |
|--------|-------------|
| **Rapid Multi-Agent System Construction** | Only requires **prompt design** and **tool coding**; the rest is handled by the framework |
| **Automatic Node Routing** | Automatically parses agent outputs and determines message destinations without complex routing logic |
| **Graph State Save & Restore** | Supports saving execution graph state and resuming after interruptions to avoid redundant operations |
| **Flexible & Extensible Message Format (A-mail)** | Customizable fields make it easy to prototype and extend multi-agent systems |
| **Auto Format Validation & Error Handling** | Parsing nodes detect output format errors and guide agents to regenerate, improving fault tolerance |
| **Unified Prompt Management for Multiple Agents** | Uses TOML for centralized prompt management, facilitating maintenance and consistent design |
| **Support for Multi-Agent Collaboration & Tool Calls** | Standardized message passing between agents and tool injection for complex task division and invocation |
| **Streaming Console Monitoring** | View streaming output results directly in the console |

### ❌ What Our System Cannot Do

| Feature | Description |
|--------|-------------|
| **Efficient Parallel Execution (MapReduce Functionality)** | Does not currently support LangGraph's `send()` concurrent execution, only serial task flow. Will be implemented in future versions |
| **Advanced Memory Management & Context Optimization** | Simple memory management, not deeply integrated with LangMem, lacks advanced context engineering and memory optimization |
| **Context & Token Consumption Optimization** | Due to verbose prompt templates and large context windows, token consumption is high, requiring strong model context capabilities |
| **Code Structure Standardization** | Current code mixes classes and functions with inconsistent styles. Will refactor in future versions |
| **Model Adaptation Issues** | Currently supports models with OpenAI API format. Other deployment formats not yet supported; will adapt in later versions |

---

## Quick Start Guide

### 1. Clone the Repository

Note: Python 3.12 was used during development. It is recommended to use Python 3.12.

```bash
git clone https://github.com/dev-yang-ai/A_mail.git
```

### 2. Install Dependencies

After entering the project directory, run the following command to install dependencies:

```bash
pip install -r requirements.txt
```

### 3. Write Model Configuration File

The system currently supports models that use the OpenAI API Key format, including common OpenAI models, DeepSeek, Qwen series, and Moonshot's Kimi model.

Create a model configuration file in the following format:

```yaml
deepseek:
  api_key: sk-XXX
  base_url: https://api.deepseek.com  
  models:
    - name: deepseek-chat
      input_price: 0.000001
      output_price: 0.000004
```

(Note: Input/output fields are not yet functional. Any numbers can be filled in.)

Ensure that the model names in the configuration match those in the prompt TOML file.

### 4. Write Prompt Files

One of the cores of a multi-agent system is prompt design.

You can edit or add prompts at the following path and specify the entry agent:

You can create a TOML file and write prompts as shown here: [Prompt Writing Instructions](#prompt-writing-instructions)

### 5. Develop Tools

Tools are the interface for system interaction with the external environment.

According to the design documentation, implement or extend tool functionality in the following file:

Create a Python tool file and follow the method shown here: [Tool Development Instructions](#tool-development-instructions)

After completing tool development, make sure to maintain the dictionary mapping agents to their tools.

### 6. Run the System

Create a Python file to input the model configuration, prompt file path, and tool dictionary into the framework:

```python
from a_mail.core.graph import MultiAgentSystem
from user_examples.deep_research_brief.deep_reacher_tool import agent_tools_map

mas = MultiAgentSystem(
    prompt_path="prompts.toml",
    model_path="model_config.yaml",
    tool_dict=agent_tools_map
)

# Print mermaid diagram, which can be copied to a parser for viewing
mas.show_mermaid_graph()

# Run the system without rollback
mas.run_with_checkpoint(input_message="please follow the rules and run")

# Run the system with rollback, continuing from the previous breakpoint of thread ID XXX-XXX-XXX
mas.run_with_checkpoint(
    input_message="please follow the rules and run",
    continue_run=True,
    thread_id="XXX-XXX-XXX"
)
```

On first run, the system generates a UUID as the execution identifier.

If the run is manually terminated or interrupted due to network/server issues, you can resume execution by inputting this UUID and setting `is_continue` to `true`.

> ⚠️ Note: Ensure all agent names and tool names are consistently configured to avoid invocation errors.

---

## Prompt Writing Instructions

The basic requirements for prompts are as follows:

### 1. Entry Agent

```toml
[[entry_agent]]
name = "user_clarifier"
```

We need to specify the system's entry agent.

### 2. Agent Prompt Design

```toml
[[agents]]
name = "user_clarifier"
name_zh = "User Clarifier"
description = "Responsible for analyzing user messages, determining if clarification is needed, and notifying the research lead when sufficient information is available"
role_desc = """
Your core responsibility is to communicate with users and confirm their needs, determine whether to communicate with the user, and ask the user to clarify the question.
"""
tools_desc = """
- ask_human(): Call this tool when you need to ask the user a question.
- write_conversation(): Record your conversation with the user.
"""
collaboration_agents = ["research_topic_generator"]
examples = ""
notes = ""
workflow_spec = """
1. Use the tool ask_human to communicate with the user, clarify the research direction, ensure user explanation aligns with your understanding. You can call this tool multiple times to ask the user. Proceed when you feel there is no ambiguity.
2. Use the tool write_conversation to record your conversation with the user.
3. Contact research_topic_generator to inform them that communication is complete and they can proceed with work.
"""
group = "report_generation_process"
llm_name = "qwen3-coder-plus"
```

#### Field Descriptions

| Field Name | Required | Purpose |
|------------|----------|---------|
| `name` | ✅ Required | Unique identifier for the agent, used within the program |
| `name_zh` | ❌ Optional | Chinese readable name for easier understanding |
| `description` | ✅ Recommended | Functional summary, used to introduce the agent to other agents |
| `role_desc` | ✅ Required | Role definition for the LLM |
| `tools_desc` | ✅ Required | Tool usage instructions, focusing on additional usage notes; no need to specify exact call parameters |
| `collaboration_agents` | ✅ Recommended | Collaboration relationships, supporting automatic routing |
| `examples` | ❌ Optional | Few-shot examples to improve consistency. Use A-mail format to build the final output for agent interaction |
| `notes` | ❌ Optional | Additional notes, boundary handling |
| `workflow_spec` | ✅ Strongly Recommended | Clear execution process, supporting automated parsing |
| `group` | ❌ Optional | Extension field, under development |
| `llm_name` | ✅ Required | Specifies the model to run |

---

## Tool Development Instructions

Tools act as the sensory system for agents. We hope to build them in this way.

Here is an example of a tool that interacts with the user:

```python
def talk_with_user(
    question: Annotated[str, "The question to ask the user"]
) -> str:
    """Ask the user a question and get their response"""
    print(f"\n🤖 Question: {question}")
    try:
        return input("👤 Answer: ")
    except KeyboardInterrupt:
        return "User canceled operation"
```

> ⚠️ Be sure to use the function's docstring to explain the tool's purpose and recommend using `Annotated` to add annotations to tool parameters.

After developing and designing the tool, be sure to construct the agent-tool mapping dictionary in the following file:

```python
agent_tools = {
    "user_clarifier": [talk_with_user, write_conversation],
    "research_topic_generator": [get_conversations],
    "lead_researcher": [],
    "sub_researcher": [duckduckgo_search, write_report, fetch_page_content],
    "report_generation": [get_research_raw_info, write_final_report]
}
```

The system will automatically recognize and add them to the agents.

---

## Example Projects

```
user_examples/deep_research_brief
```

We roughly reproduced the `open_deep_research` project from the LangChain team to demonstrate how to build a multi-agent project.

Agent design is as follows:

![](./image/open_deep_research_en.drawio.svg)

Run the following command to experience our console streaming output:

```bash
python user_examples/deep_research_brief/run.py
```

```
user_examples/four_basic_operations
```

We also built a simple multi-agent system for basic arithmetic operations using the Supervisor architecture.

You can try running:

```bash
python user_examples/four_basic_operations/run.py
```

---

## License

This project is licensed under the permissive MIT License. Both individual developers and enterprises are free to use, modify, and develop it further.

This project aims to improve development efficiency and inspire new ideas.

If this project has been helpful to you, feel free to mention "A_mail" when introducing or sharing it. Thank you for your support!

---

## Final Notes

The current system was developed to solve a problem in my own project: writing routing logic was too cumbersome, requiring a lot of code and often failing to catch errors.

I found that no one (or perhaps I haven’t seen it) has shared a solution (possibly because LangGraph is a relatively new framework). So I’m offering my solution to everyone.

If this can inspire fellow developers, I’ll be very happy.

Regarding maintenance, I will definitely keep it up, as I find this approach quite interesting and capable of achieving some fun things.

If any developers want to join and help solve some of the issues ~~this project hasn’t addressed yet — like making it possible to boot up LangGraph, maybe we could rename it to `langgraphboot` — just kidding, hahaha — I’m very welcome to that.~~

You can contact me via email:

`developer_yang@qq.com`

This project still has some bugs. If you encounter any while using it, feel free to open an issue. I should respond and fix it within a week (as long as there aren’t too many bugs).

---
