演示应用需按 examples/demo 目录内的说明单独运行;AMQPSpace 需要自备 RabbitMQ 等 AMQP 服务器;OpenAI 与 HuggingFace 示例需自行准备相应模型或 API 凭据
pip install agencyREADME 未说明显存或 GPU 要求;演示应用包含 OpenAI 与 HuggingFace transformers 示例,但未给出具体硬件规格
基于 Actor 模型的 Python 框架,用来把 AI Agent 和传统软件系统灵活连接起来
用 Actor 模型搭建智能体系统的轻量框架,启动快、开销小,适合需要高并发和低延迟的多智能体编排场景。
核心能力
- 用 @action 装饰器定义可被其他 Agent 发现并调用的动作
- 通过 LocalSpace 或 AMQPSpace 把多个 Agent 接入同一通信空间
- 支持多进程与多线程并发,AMQP 可跨网络组网
- 动作可设访问策略,并提供前后置与生命周期回调
- 附带 Gradio 演示应用和 Docker 配置供参考
容易踩的坑
- v1.6.3Release 1.6.3最新正式版2024-04-24 · 2024-04-24 20:59 UTC
Includes Parameterization of Max Workers in ResourceManager #185 from @migueldl96 🎉
- v1.6.12023-09-26 · 2023-09-26 05:12 UTC
查看更新说明
Updates
AMQPSpaceto use a topic exchange for better observability. Thanks @wwj718! 🙏 - v1.6.02023-09-26 · 2023-09-26 02:36 UTC
查看更新说明
I'm proud to announce Agency v1.6.0. Technically, it represents a big step forward and I believe is a milestone in terms of clarity for the project.
It took some iterating and lots of thoughtful feedback, but I think the learnings from the last few versions have come together to create a clearer picture for the API and architecture. I believe there is a good foundation now to focus on the next steps: js client, code execution, and multimodal support.
Special thanks to @wwj718 and @hidaris for their reviews and feedback that helped shape this release!
As with any major release, please do not hesitate to open issues or discussions if you have any questions or feedback. 🙇♂️
Summary of Changes
Spacetypes now support mixed threading/multiprocessing for agentsVersion 1.4 introduced multiprocessing but did not allow threading and multiprocessing based agents to be used together. Additionally the API prevented some use cases that were previously possible, due to not allowing direct access to agents from the main thread.
In 1.6.0, all agents are now
add'ed usingmultiprocessingbased subprocesses by default. Agents added this way may not be directly accessed, similar to 1.4.With 1.6.0 you now have the option to run agents in the "foreground" using
Space.add_foreground. When adding an agent this way, an instance of the agent is returned in the current thread. For example:my_agent = my_space.add_foreground(MyAgent, "my_agent")The tradeoff for adding an agent in the foreground is performance. Due to the python GIL, agents running in the foreground may not be fully parallel with other agents, and may block the main thread.
It's recommended to use
Space.add_foregroundonly when needed.MultiprocessSpaceandThreadSpaceclasses replaced withLocalSpaceSince all
Spacetypes now support mixed threading/multiprocessing,LocalSpacecombines these older types into a single class for in-application communication.Context manager support and
Space.destroymethod addedThese two additions allow for improved resource management. Creating and cleaning up a
Spacecan now be done using the context manager syntax:with AMQPSpace() as space: space.add(Host, "Host") ...This form will automatically clean up Space related resources upon exit of the
withblock.Direct control of cleanup is also possible using the
Space.destroymethod.space = AMQPSpace() space.add(Host, "Host") ... space.destroy()Agent.respond_withandAgent.raise_withmethods addedThese methods are intended for use with
Agent.requestand the response callbacks:Agent.handle_action_valueandAgent.handle_action_error.Automatic response behavior has changed from v1.5. Actions will no longer automatically return their return value to the sender.
To explicitly return a value to the sender associated with the current message, use
Agent.respond_with. For example:@action def ping(self): self.respond_with("pong")The above will invoke the
handle_action_valuecallback on the sender with the value"pong", or return the value"pong"directly when used with therequestmethod.Similarly you may return an error with:
@action def ping(self): self.raise_with(Exception("oops"))Actions that raise exceptions will automatically call the
raise_withmethod.Note that
respond_withandraise_withmay be called multiple times in a single action. Each call will invoke the appropriate callback on the sender.When using
requestthe first call torespond_withwill return the value to the calling thread. Subsequent responses will invoke thehandle_action_valuecallback.Performance Improvements
All busy wai
- v1.5.02023-09-18 · 2023-09-18 04:05 UTC
查看更新说明
This release addresses the request related issues brought up here regarding the use of multiple "meta" id's and the semantics of automatic responses to messages. Shoutout to @wwj718 for the great feedback for these updates!
Since this includes breaking changes, the version has been bumped to 1.5.0.
Summary:
-
All messages now populate the
meta.idfield with a UUID by default. Agents may set their own custommeta.idupon sending to overwrite the generated ID.In addition,
Agent.send()now returns themeta.idof the sent message. This way you may store the generated ID for your own purposes. -
Removed the use of
meta.response_idandmeta.request_id. These have been replaced bymeta.parent_id. I think the term "parent" is clearer. This choice is inspired by the Jupyter messaging docs.To be clear,
meta.parent_idif set, refers to themeta.idof the original message which the current message is responding to.To illustrate, the following would be typical meta fields in a send/response pair:
# send { "meta": { "id": "123", # the message ID here }, ... } # response { "meta": { "id": "456", # response has its own unique meta.id "parent_id": "123", # refers to the prior message }, ... } -
All messages will now result in a
[response]message like the above, returning the return value or error result from the message's action. These messages (unless using therequest()method) will invoke thehandle_action_value()andhandle_action_error()methods appropriately.One might want to filter these messages from view in a user interface. The demo Gradio app has been updated to demonstrate this. See the
_should_render()andget_chatbot_message()methods for an example. -
Agent.original_message()has been renamed toAgent.parent_message(). Additionallyparent_message()takes a message as a parameter, allowing you to traverse a chain of messages in reverse. -
Internally renamed
Agent._pending_responsestoAgent._pending_requestswhich I think is clearer. -
The logger has been updated to provide colorization of output for easier reading. You may change the default "monokai" pygments style used for object output, by setting the
LOG_PYGMENTS_STYLEenvironment variable. -
Log "warning" messages for unimplemented
handle_action_valueandhandle_action_errormethods have been updated to only print once per session, in order to reduce logging noise in the default setting. -
Tests and documentation updated.
-
- v1.4.12023-09-11 · 2023-09-11 08:28 UTC
查看更新说明
Fixes a regression in the 1.4.0 release related to the AMQP exchange parameter
用户点评
登录用户的真实使用记录,可按版本和硬件筛选还没有人点评。第一个说出真实体验的人最有价值。
Summary
Agency is a python library that provides an Actor model framework for creating agent-integrated systems.
The library provides an easy to use API that enables you to connect agents with traditional software systems in a flexible and scalable way, allowing you to develop any architecture you need.
Agency's goal is to enable developers to create custom agent-based applications by providing a minimal foundation to both experiment and build upon. So if you're looking to build a custom agent system of your own, Agency might be for you.
Features
Easy to use API
- Straightforward class/method based agent and action definition
- Up to date documentation and examples for reference
Performance and Scalability
- Supports multiprocessing and multithreading for concurrency
- AMQP support for networked agent systems
Observability and Control
- Action and lifecycle callbacks
- Access policies and permission callbacks
- Detailed logging
Demo application available at examples/demo
- Multiple agent examples for experimentation
- Two OpenAI agent examples
- HuggingFace transformers agent example
- Operating system access
- Includes Gradio UI
- Docker configuration for reference and development
API Overview
In Agency, all entities are represented as instances of the Agent class. This
includes all AI-driven agents, software interfaces, or human users that may
communicate as part of your application.
All agents may expose "actions" that other agents can discover and invoke at run time. An example of a simple agent could be:
class CalculatorAgent(Agent):
@action
def add(a, b):
return a + b
This defines an agent with a single action: add. Other agents will be able
to call this method by sending a message to an instance of CalculatorAgent and
specifying the add action. For example:
other_agent.send({
'to': 'CalcAgent',
'action': {
'name': 'add',
'args': {
'a': 1,
'b': 2,
}
},
})
Actions may specify an access policy, allowing you to control access for safety.
@action(access_policy=ACCESS_PERMITTED) # This allows the action at any time
def add(a, b):
...
@action(access_policy=ACCESS_REQUESTED) # This requires review before the action
def add(a, b):
...
Agents may also define callbacks for various purposes:
class CalculatorAgent(Agent):
...
def before_action(self, message: dict):
"""Called before an action is attempted"""
def after_action(self, message: dict, return_value: str, error: str):
"""Called after an action is attempted"""
def after_add(self):
"""Called after the agent is added to a space and may begin communicating"""
def before_remove(self):
"""Called before the agent is removed from the space"""
A Space is how you connect your agents together. An agent cannot communicate
with others until it is added to a common Space.
There are two included Space implementations to choose from:
LocalSpace- which connects agents within the same application.AMQPSpace- which connects agents across a network using an AMQP server like RabbitMQ.
Finally, here is a simple example of creating a LocalSpace and adding two
agents to it.
space = LocalSpace()
space.add(CalculatorAgent, "CalcAgent")
space.add(MyAgent, "MyAgent")
# The agents above can now communicate
These are just the basic features that Agency provides. For more information please see the help site.
Install
pip install agency
or
poetry add agency
The Demo Application
The demo application is maintained as an experimental development environment and a showcase for library features. It includes multiple agent examples which may communicate with eachother and supports a "slash" syntax for invoking actions as an agent yourself.
To run the demo, please follow the directions at examples/demo.
The following is a screenshot of the Gradio UI that demonstrates the example
OpenAIFunctionAgent following orders and interacting with the Host agent.
Contributing
Please do!
If you're considering a contribution, please check out the contributing guide.
Planned Work
If you have any suggestions or otherwise, feel free to add an issue or open a discussion.