chatchat — Agent Framework
Python agent framework with LLM tool calling, multi-agent orchestration, and a scheduler-based event-driven architecture.
Install
pip install chatchat
Quick Start
Single Agent
import asyncio
from chatchat.agent import AgentConfig, create_agent
from chatchat.tool import tool
@tool(
name='get_weather', description='get weather for a city',
parameters={
'type': 'object',
'properties': {
'city': {'type': 'string', 'description': 'the city name, e.g., Shanghai'},
},
'required': ['city'],
},
)
def get_weather(city):
return f'{city} is Sunny.'
agent = create_agent(AgentConfig(
name='assistant',
provider='agnes', model='agnes-2.5-flash',
instruction='You are a helpful assistant.',
tools=[get_weather],
))
async def main():
result = await agent.chat('How is the weather in Shanghai?')
print(result)
await agent.stop()
asyncio.run(main())
Multi-Agent Team
Teams inherit from Agent and carry management tools (create_agent, create_team, send_message, task_stop). Sub-agents are created on demand by the leader and communicate through the scheduler via runtime.request / reply.
import asyncio
from chatchat.team import TeamConfig, create_team
from chatchat.runtime import get_runtime, make_id
team = create_team(TeamConfig(
name='lead',
provider='agnes', model='agnes-2.5-flash',
instruction='You are a tech lead. Use create_agent to delegate tasks to sub-agents.',
agent_tools=[],
))
async def main():
reply = await get_runtime().request(
source=make_id(), target_id=team.id,
topic=f'entity:team:{team.id}:text',
data='write a tutorial to output.md', timeout=300,
)
print(reply)
await team.stop()
get_runtime().shutdown()
asyncio.run(main())
Tools
Tools are registered with the @tool decorator. They run inside the AgentLoop; the LLM's tool calls are accumulated by index, executed, and fed back for further turns.
from chatchat.tool import tool
@tool(
name='add', description='add two numbers',
parameters={
'type': 'object',
'properties': {
'a': {'type': 'integer'},
'b': {'type': 'integer'},
},
'required': ['a', 'b'],
},
)
def add(a, b):
return a + b
Skills
Skills are directories containing a SKILL.md. Their instruction block is injected into the agent's system prompt.
agent = create_agent(AgentConfig(
name='skilled',
provider='agnes', model='agnes-2.5-flash',
instruction='You are a helpful assistant.',
skills=['/path/to/skill_dir'],
))
Architecture
- Scheduler / Runtime — core message router. Agent-to-Agent and delegation communication go through the scheduler using topic-based addressing (
entity:<kind>:<id>:<type>), with blocking request/reply and fire-and-forget publish. Callingagent.chat()runs the agent loop directly in the caller. - Agent — wraps an LLM client, a tool set, and the AgentLoop (streaming, tool-call accumulation, lifecycle hooks
start/step/end/error). - Team — an Agent with management tools;
leader_toolsconfigure the leader's tools,agent_toolsconfigure tools given to created sub-agents. - Client / providers — async streaming LLM clients (aiohttp) for
agnes,deepseek,openrouter,google,alibaba,baidu,zhipu,tencent,xunfei, etc.
Observe runtime activity with get_runtime().enable_logging('agent', 'team', 'client', 'tool'). Lifecycle topics: lifecycle:agent:start/step/end/error, lifecycle:client:start/step/end/error, lifecycle:tool:start/step/end/error.
Configuration
chatchat config --list
chatchat config <provider>.api_key=YOUR_API_KEY
chatchat run --provider agnes --model agnes-2.5-flash --thinking
Rate limits can be set programmatically:
from chatchat.rate_limiter import set_rate_limits
set_rate_limits([
{'provider': 'agnes', 'rpm': 20, 'tpm': 0, 'max_concurrent': 0},
])
Examples
See examples for complete usage:
agent.py— Interactive terminal chat with tool callingteam.py— Leader team delegating tasks to dynamically created sub-agentstool.py— Raw client with tool callingclient.py— Raw LLM client streaming usagestate.py— Agent state serialization and restorationinteract.py— Interactive tool confirmationprogress.py— Streaming progress with custom tools
Sponsor
| 公众号 | |
|---|---|
| AliPay | WeChatPay |
Metadata
Release files for chatchat 0.5.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| chatchat-0.5.0.tar.gz | 39.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| chatchat-0.5.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 80.3 kB
Release files / chatchat-0.5.0.tar.gz
| Download URL | chatchat-0.5.0.tar.gz |
|---|---|
| Size | 39.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
bdfa1ffa817da63e15db80125f3619c3b382eab872b01c09201eacabd4ace050
|
|
BLAKE2b-256 checksum How to use checksums |
828d9e7f76b634fb667bfb7b3f29fd49b15ba8f1755c9e8c906af3379fd2e721
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / chatchat-0.5.0-py3-none-any.whl
| Download URL | chatchat-0.5.0-py3-none-any.whl |
|---|---|
| Size | 40.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
48d7297d9630d542d2ad59d004affeaf8b8bce1421c7e43315a41f21aa53f2ee
|
|
BLAKE2b-256 checksum How to use checksums |
ea5db5484347c993b3b7ebf077ec63ebc3517f81daa3bf8d4e39f3d96da8426a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|