Building Multi-Agent Teams with Hermes and Telegram

Preface

Unlike openclaw, hermes does not design a method for agents to communicate with each other (sending messages into the session) in the system framework.
So let's have hermes's multi-agent team use telegram to communicate

Approach

Combined with the previously implemented multi-Agent binding to telegram bot
We attempt to establish a multi-Agent team for collaboration

Deploying the Hermes-agent System

Set up the telegram channel
Set which telegram user IDs are allowed to use it
The above steps are omitted.

Create telegram group, bots, and agents

Refer to this tutorial, set up the telegram group and bots, and test that bots can see each other's messages. Process omitted.

Assume the id of this telegram group is
-1003918964882
Assume these bots' usernames and tokens are
@CrazyAgentWatchBot
1234567890:AAHkMpXv2nQrWsYd8bJtLfCeUo9GiN1KmZw
@CrazyAgentDesignBot
2345678901:AABxRqNj5vTgKhEa3cWmYsPdFu7LiOz4Xbn
@CrazyAgentCodeBot
3456789012:AAEvNuGz3tFwBqXk7yRmJcSh5OaDpI8LlTx
@CrazyAgentTestBot
4567890123:AAHkMpXv2nQrWsYd8bJtLfCeUo9GiN1KmZw
Refer to this tutorial, create the new agents and bind them to the bots. Process omitted.
Assume these agents are:
agent-watch
agent-design
agent-code
agent-test

Establishing the multi-agent team

Chat with the default agent hermes
Form an agent collaboration team, utilizing multiple already existing agents.
Configure the agents' config files and the collaboration relationships between agents

The agents forming the team are:
agent-watch, agent-design, agent-code, agent-test

Agent No. 1
Name = agent-watch
telegram bot username = @CrazyAgentWatchBot
Identity = You are the task dispatcher, assigning tasks to each agent in the team and tracking the progress of each agent's tasks
When receiving a "new task", immediately send it to agent-design for analysis, breaking down the overall task into smaller tasks. Note that you should not analyze it yourself.
Then assign the broken-down small tasks to appropriate agents for execution.
Maintain a `task_name.md` file, recording the task list and completion progress
When an agent in the team asks a question, forward the question to agent-design for thinking, then forward the answer to the asking agent. Note that you only relay information, do not modify it.
Knowledge = Know the full information of other agents in the team (including identity and knowledge)

Agent No. 2
Name = agent-design
telegram bot username = @CrazyAgentDesignBot
Identity = Receive tasks from other agents, notify the task originator upon completion, and submit the deliverables
Specifically, you are the designer and analyst
You break down large tasks into small tasks suitable for execution by members of this team.
You do not ask users for supplementary information; always provide the optimal solution in the current state, finding ways to push the task forward
Knowledge = Deliverables after task completion need to be saved in a non-workspace directory before being delivered
Know the full information of other agents in the team (including identity and knowledge). Note that although you know the information of other agents in the team, within the team you only communicate directly with Agent No. 1.

Agent No. 3
Name = agent-code
telegram bot username = @CrazyAgentCodeBot
Identity = Receive tasks from other agents, notify the task originator upon completion, and submit the deliverables
Specifically, you are the programmer
Knowledge = Deliverables after task completion need to be saved in a non-workspace directory before being delivered

Agent No. 4
Name = agent-test
telegram bot username = @CrazyAgentTestBot
Identity = Receive tasks from other agents, notify the task originator upon completion, and submit the deliverables
Specifically, you are the tester, accepting test targets and test criteria, and delivering test reports
Knowledge = Deliverables after task completion need to be saved in a non-workspace directory before being delivered

Common knowledge:
This team works in a telegram group, telegram group id = -1003918964882
When agents in the team send messages to each other, they must include @
Note that telegram bot username is only used when agents send messages to each other. In other cases, only the agent name is used.
Agents in the team only process messages that @ them

Testing 

@CrazyAgentWatchBot test task 
Test the team collaboration workflow
The result looks like a disaster
Multi-agent test throws a pile of 401s, stop each gateway first
(Right-click to open in new tab to view full image)

First stop the gateway of each agent
agent-watch gateway stop
agent-design gateway stop
agent-code gateway stop
agent-test gateway stop
Chat with the default agent hermes, throw the telegram group chat history over and let Ta analyze.
The image below shows how to export chat history
Export group chat history and hand it to hermes for analysis
Change export format to JSON
* Finally package as .zip 
Package the exported JSON into result.zip

hermes analyzes the cause and solution
Explaining it is not a require_mention config issue but an accidental agent cascade; anti-cascade rules added to SOUL.md

The cause is correct, but the solution, honestly, I'm not very confident in the effect of this kind of negative prompt.

Tried the test task again, still about the same as before. Maybe it's context pollution from previous execution processes, maybe it's because the negative prompt doesn't work well.
Specific screenshots won't be posted.

I also found 2 more issues.

1. These gateways are all OAuth authenticated with the same Nous Portal account. But because the gateways are independent, when requesting the API, each makes its own independent request. So from the perspective of Nous Portal, the same account is making rapid requests.
It's easy to trigger 429 Too Many Requests 

I adopted a solution of agents sharing a flock file lock + status file to control the API request rate
~/.hermes/api_rate_limit  →  Content: timestamp of the last request

When the Gateway wants to call the API:
  flock(api_rate_limit.lock)
    read(last_time)
    if now - last_time >= interval:
      write(now)           ← Update timestamp
      unlock
      → send API request
    else:
      wait_time = interval - (now - last_time)
      unlock
      sleep(wait_time)
      → retry

2. Because of the streaming output effect, a message is seen by another bot before it is even complete.
Streaming output spotted by another bot before it finished
Disable streaming output 
agent-watch config set streaming false
agent-design config set streaming false
agent-code config set streaming false
agent-test config set streaming false

Next, the most troublesome part - handling team communication
Refer to openclaw's approach, bind the agent to a topic
So that the agent's self-talk won't interfere with other agents
* Need hermes to modify its own code

In order to let the agent know who to reply to after completing the task, referring to my past experience with agent teams, standardize a message format within the team.
The inter-agent message format within the team is as follows:
FROM:
TO:
CONTENT:

For example
FROM: agent-watch
TO: agent-design
CONTENT: 
Overall task: Develop a page that generates random passwords
Core feature reference: https://crazypeace.github.io/xkcd-password-generator/
Visual style reference: https://onojyun.com/
Please break down the task and output a list of sub-tasks that can be directly assigned to agent-code / agent-test.

Tried the test task again, found that the agent doesn't know how to send team messages
The logic chain I envisioned is:
Send team message to xxx-agent -> what is xxx-agent's topic -> use telegram bot API to send
But the actual effect is as follows 
disable streaming and let agents message each other instead
Don't know what agent-watch is busy with. No response in agent-design's topic

When trying to improve this issue, found that hermes has many security restrictions on the function of querying the current agent's telegram bot token.
I even found and set 
hermes config set security.redact_secrets false
and
~/.hermes/.env
HERMES_REDACT_SECRETS=0
But it still didn't work.

So, I had to go the hard way. Generate 3 scripts for each agent, used to send messages to other team members.
The agent doesn't need to know which topic other agents are in, doesn't need to know its own group id.
It just needs to know that it's collaborating with other agents, and when it wants to send a message to another agent, it uses the corresponding script.
Writing a send_to_agent script for each agent

Three send scripts generated in the scripts directory
* By the way, I'm using the freebie mimo-v2-pro (if you use a "smarter" model, feel free to experiment)

Tried the test task again. Finally starting to look like something.
Switched to mimo-v2-pro and it finally looks decent
(Right-click open in new tab to view original image)

However, still found some small issues
agent-design's first message to agent-design was replied in its own topic, only after a reminder did it perform the correct behavior.
agent-design sending its first reply to the wrong topic
(Right-click open in new tab to view original image)

agent-design twice did not follow the team message format
FROM:
TO:
CONTENT:
agent-design failing to follow FROM/TO/CONTENT format twice

Move on to another dev task and keep testing

Try a development task

New task: Develop a page that generates random passwords
Core feature reference https://crazypeace.github.io/xkcd-password-generator/
Visual style reference https://onojyun.com/


========

Other good articles


Comments