A minimal, efficient, easy-to-integrate, flexible, and beginner-friendly LLM agent development framework with powerful context management.
Project description
极简高效、易于集成、灵活扩展、上下文管理强大、适合新手的 LLM 智能体开发框架
CrazyAgent 是专为智能体开发新手打造的框架,语法简洁明了,便于将大模型与各类工具和组件高效集成,并能灵活管理上下文记忆,大幅提升开发效率。即使是刚接触 Python 的用户也能快速上手。
特性
- 更少的错误: CrazyAgent 采用简洁明了的 API 设计,显著减少开发者编写代码的错误
- 快速开发: CrazyAgent 提供了一系列工具,帮助开发者快速构建智能体应用
- 易于使用: CrazyAgent 设计简单易用且易于学习,减少阅读文档的时间
兼容的模型服务
依赖
CrazyAgent 站在以下巨人肩膀上
安装
$ python -m pip install crazyagent
对话
CrazyAgent 所支持的大模型厂商的接口都会在 crazyagent.chat 模块中实现,您可以根据自己的需求选择对应接口类
API 密钥获取:
同步输出
from crazyagent.chat import Deepseek
import os
# 从环境变量中获取 Deepseek 的 API 密钥
llm = Deepseek(api_key=os.environ.get('DEEPSEEK_API_KEY'))
response = llm.invoke("你好,我叫小明")
print(response.content)
同步流式输出
from crazyagent.chat import Deepseek
import os
llm = Deepseek(api_key=os.environ.get('DEEPSEEK_API_KEY'))
for response in llm.stream("你好,我叫小明"):
print(response.content, end="", flush=True)
异步输出
from crazyagent.chat import Deepseek
import os
llm = Deepseek(api_key=os.environ.get('DEEPSEEK_API_KEY'))
async def main():
response = await llm.ainvoke("你好,我叫小明")
print(response.content)
import asyncio
asyncio.run(main())
异步流式输出
from crazyagent.chat import Deepseek
import os
llm = Deepseek(api_key=os.environ.get('DEEPSEEK_API_KEY'))
async def main():
async for response in llm.astream("你好,我叫小明"):
print(response.content, end="", flush=True)
import asyncio
asyncio.run(main())
记忆
CrazyAgent 提供了功能强大的 Memory 类来管理对话上下文
该类不仅具备完善的记忆管理能力,还兼容 Python 内置的 print 和 list 函数接口
让开发者能够轻松进行可视化调试和灵活的数据处理操作
- 通过
print函数可以以彩色文本形式可视化不同类型的消息,让开发过程更直观 - 通过
list函数轻松获取list[dict[str, str]]格式的消息记录,便于在应用中灵活调用和处理
print(memory)会显示出所有的消息记录,消息角色包括:系统、用户、助手、助手(调用工具)、工具
1. Memory 构造函数的参数
| 参数 | 说明 | 是否必填 | 默认值 |
|---|---|---|---|
max_turns |
最大对话轮数,用于控制用于聊天时记忆的长度 | 否 | 5 |
2. 对话中使用记忆
由于 memory 实现了 __str__ 方法,用户可以直接使用 print(memory) 以彩色表格的形式直观展示记忆中的消息记录
from crazyagent.chat import Deepseek
from crazyagent.memory import Memory
import os
llm = Deepseek(api_key=os.environ.get('DEEPSEEK_API_KEY'))
memory = Memory() # 创建一个新的记忆对象
# 把 memory 作为参数传递给 llm 的 stream 方法
# 这样 llm 就会把该次对话的记录保存到 memory 中
for response in llm.stream("你好,我叫小明", memory=memory):
print(response.content, end="", flush=True)
# 在流式输出正常结束后
else:
print()
print(memory) # 打印记忆中的消息记录
3. 自定义记忆和系统提示词
自定义的记忆也可以用于对话中,只需要把 memory 作为参数传递给 llm 的 stream 或 invoke 方法即可
自定义的消息必须是成双数,即 HumanMessage 和 AIMessage 必须成对出现,否则后续使用会抛出异常
from crazyagent.memory import Memory, HumanMessage, AIMessage, SystemMessage
memory = Memory()
memory.system_message = SystemMessage("你是一个疯狂的助手") # 自定义系统提示词
# 向记忆中添加消息记录
memory.update(
HumanMessage("你好,我叫小明。"),
AIMessage("你好呀,小明!我是一个疯狂的助手。"),
)
print(memory) # 打印记忆中的消息记录
4. 实战案例,添加初始记忆后进行多轮对话
from crazyagent.chat import Deepseek
from crazyagent.memory import Memory, HumanMessage, AIMessage, SystemMessage
import os
llm = Deepseek(api_key=os.environ.get('DEEPSEEK_API_KEY'))
memory = Memory()
memory.system_message = SystemMessage("你是一个疯狂的助手") # 自定义系统提示词
# 向记忆中添加自定义消息记录
memory.update(
HumanMessage("你好,我叫小明。"),
AIMessage("你好呀,小明!我是一个疯狂的助手。"),
)
while True:
user_input = input("> ") # 等待用户输入
for response in llm.stream(user_input, memory=memory):
print(response.content, end="", flush=True)
else:
# 流式输出正常结束后,打印记忆中的消息记录
print()
print(memory)
工具
CrazyAgent 提供了整个地球上最精简、高效、迅速和稳定的工具构建框架!
工具函数的每个参数必须要使用类型注解!而且函数的文档字符串要完整!
与工具函数相关的所有参数类型都必须属于 JSONType!
from types import UnionType, NoneType
JSONType: UnionType = dict | list | tuple | str | int | float | bool | NoneType
1. Argument 构造函数的参数
| 参数名称 | 数据类型 | 是否必填 | 默认值 | 说明 |
|---|---|---|---|---|
description |
str |
是 | - | 参数的描述信息 |
default |
JSONType |
否 | ... |
参数的默认值 |
required |
bool |
否 | True |
该参数是否必须 |
enum |
List[JSONType] |
否 | ... |
参数的枚举值 |
2. 把普通函数转化为工具函数
这是一个用于查询天气的普通函数
def get_weather(city_name: str) -> dict:
"""
查询天气
Args:
city_name: 城市名称
Returns:
dict: 天气信息
"""
... # 假设这里是查询天气的逻辑
return {
"city_name": city_name,
"weather": "晴",
"temperature": "25°C",
"wind": "微风",
}
要把这个函数转化为大模型可以使用的工具函数
只需要把函数用 @crazy_tool 装饰器装饰,然后把每个参数的默认值设置为 Argument 对象即可
异步工具函数只能在
llm.ainvoke和llm.astream中被使用,它们同时也兼容同步工具函数但
llm.invoke和llm.stream不支持使用异步工具函数
from crazyagent.toolkit.core import crazy_tool, Argument
# 普通工具函数
@crazy_tool
def get_weather(city_name: str = Argument("城市名称")) -> dict:
"""查询天气"""
... # 假设这里是查询天气的逻辑
return {
"city_name": city_name,
"weather": "晴",
"temperature": "25°C",
"wind": "微风",
}
# 异步工具函数
@crazy_tool
async def async_get_weather(city_name: str = Argument("城市名称")) -> dict:
"""查询天气"""
... # 假设这里是查询天气的逻辑
return {
"city_name": city_name,
"weather": "晴",
"temperature": "25°C",
"wind": "微风",
}
3. 实战案例,对话中使用多个工具函数
CrazyAgent 提供了许多已封装好的工具函数,大致分为两类:外部工具和私有工具
具体的工具函数可以查看
crazyagent.toolkit._external和crazyagent.toolkit._private模块下的文件,这些工具会在crazyagent.toolkit模块下的__init__.py文件中被导入和导出,可以直接通过from crazyagent.toolkit import *导入所有 CrazyAgent 提供的工具函数
外部工具一般是一些第三方免费的 API 私有工具一般是一些内部使用的工具,比如查询数据库、发送邮件等 使用内部工具时需要先调用对应的 configure 函数来配置私有工具的 API 密钥
from crazyagent.toolkit import (
get_weather, # 外部工具函数, 查询天气
send_email, # 私有工具函数, 发送邮件
configure_email_service,
)
from crazyagent.memory import Memory
from crazyagent.chat import Deepseek
import os
# 为私有工具函数 send_email 配置邮件服务的 API 密钥信息
configure_email_service(
sender_mail='...', # 替换为实际的发件人邮箱地址
authorization_code='...', # 替换为实际的授权码
server='...' # 替换为实际的 SMTP 服务器地址
)
llm = Deepseek(api_key=os.environ.get('DEEPSEEK_API_KEY'))
memory = Memory()
while True:
user_prompt = input('> ')
# 这里把 获取天气 和 发送邮件 两个工具函数传入 tools 参数, 这样在对话中大模型就会知道这些工具的存在, 并根据用户的输入来选择使用哪个工具
for response in llm.stream(
user_prompt,
memory=memory,
tools=[get_weather, send_email]
):
print(response.content, end='', flush=True)
else:
print()
print(memory)
在代码中,我们传入了 get_weather 和 send_email 两个工具函数到 llm.stream 方法的 tools 参数中
然后我们提问:“告诉我妹妹(她的邮箱是2036166178@qq.com)今天广州的天气怎么样”
然后大模型就理解了用户的意图,首先选择了 get_weather 工具函数来获取天气信息,然后选择了 send_email 工具函数来发送邮件
这么丝滑稳定的使用体验,归功于 CrazyAgent 对于工具模块极其优秀的设计理念
漂亮的提示词
CrazyAgent 提供非常多优秀的提示词,有着不同的种类,可以通过 crazyagent.pretty_prompts 模块导入
from crazyagent.pretty_prompts import LOVER
from crazyagent.memory import Memory, SystemMessage
memory = Memory()
memory.system_message = SystemMessage(LOVER) # 把优秀的提示词作为系统提示词
... # 对话逻辑
response 对象的属性
| 参数名称 | 数据类型 | 说明 |
|---|---|---|
content |
str |
大模型返回的聊天内容,如果是流式输出,则为当前流式内容 |
stop_usage |
dict |
结束对话时 prompt 和 completion 的 token 使用量 |
tool_calls_info |
list[dict] |
包含了该次对话中所有的工具调用信息 |
total_tokens |
int |
该次对话的总 token 使用量(包括结束对话和所有工具调用) |
如果是流式输出,则除了 content 之外的其它三个属性要在最后一个 response 中才能获取到
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file crazyagent-1.4.1.tar.gz.
File metadata
- Download URL: crazyagent-1.4.1.tar.gz
- Upload date:
- Size: 25.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6455af8715be6f764e85d408b512bbf7683ed4585cb1263b2f4e544c8f7f8422
|
|
| MD5 |
e4b2ced604990cb246c16f7967d63008
|
|
| BLAKE2b-256 |
56ef360ad11fb4b22464079cc62f0fb26c230e12e9aadfbda6216580fd148704
|
File details
Details for the file crazyagent-1.4.1-py3-none-any.whl.
File metadata
- Download URL: crazyagent-1.4.1-py3-none-any.whl
- Upload date:
- Size: 20.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3d4f20fe06d5f631de7e720f365fdd8ea0d79ec4b6aa863d447a8eaf6675a9d2
|
|
| MD5 |
b074dac65bbb63220498ee38a9fbeacd
|
|
| BLAKE2b-256 |
d94941429849018e0382d40df0f1da8fd09c74bc296478d03bb500b5cc568e83
|