agency

operandMIT更新放缓

用 Actor 模型搭建智能体系统的轻量框架,启动快、开销小,适合需要高并发和低延迟的多智能体编排场景。

A fast and minimal framework for building agentic systems

v1.6.3发布于 2024-04-24 20:59 UTC490star28fork同步于 2026-11-07 07:29 UTC

怎么上手

由 README 提炼,执行前请确认
pip install agency
硬件要求按 README 说明

README 未说明显存或 GPU 要求;演示应用包含 OpenAI 与 HuggingFace transformers 示例,但未给出具体硬件规格

下载:源码 zip·GitHub Releases(安装包)本站不镜像安装包

项目说明

由 README 自动翻译提炼

基于 Actor 模型的 Python 框架,用来把 AI Agent 和传统软件系统灵活连接起来

用 Actor 模型搭建智能体系统的轻量框架,启动快、开销小,适合需要高并发和低延迟的多智能体编排场景。

核心能力

  • 用 @action 装饰器定义可被其他 Agent 发现并调用的动作
  • 通过 LocalSpace 或 AMQPSpace 把多个 Agent 接入同一通信空间
  • 支持多进程与多线程并发,AMQP 可跨网络组网
  • 动作可设访问策略,并提供前后置与生命周期回调
  • 附带 Gradio 演示应用和 Docker 配置供参考

容易踩的坑

演示应用需按 examples/demo 目录内的说明单独运行;AMQPSpace 需要自备 RabbitMQ 等 AMQP 服务器;OpenAI 与 HuggingFace 示例需自行准备相应模型或 API 凭据

内容由模型根据 README 生成,可能不完整或不准确,以官方文档为准。看原文 README

最近发版

5 个版本v1.6.3
  1. v1.6.3Release 1.6.3最新正式版2024-04-24 · 2024-04-24 20:59 UTC
  2. v1.6.12023-09-26 · 2023-09-26 05:12 UTC
    查看更新说明

    Updates AMQPSpace to use a topic exchange for better observability. Thanks @wwj718! 🙏

  3. 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

    Space types now support mixed threading/multiprocessing for agents

    Version 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 using multiprocessing based 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_foreground only when needed.

    MultiprocessSpace and ThreadSpace classes replaced with LocalSpace

    Since all Space types now support mixed threading/multiprocessing, LocalSpace combines these older types into a single class for in-application communication.

    Context manager support and Space.destroy method added

    These two additions allow for improved resource management. Creating and cleaning up a Space can 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 with block.

    Direct control of cleanup is also possible using the Space.destroy method.

    space = AMQPSpace()
    space.add(Host, "Host")
    ...
    space.destroy()
    

    Agent.respond_with and Agent.raise_with methods added

    These methods are intended for use with Agent.request and the response callbacks: Agent.handle_action_value and Agent.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_value callback on the sender with the value "pong", or return the value "pong" directly when used with the request method.

    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_with method.

    Note that respond_with and raise_with may be called multiple times in a single action. Each call will invoke the appropriate callback on the sender.

    When using request the first call to respond_with will return the value to the calling thread. Subsequent responses will invoke the handle_action_value callback.

    Performance Improvements

    All busy wai

  4. 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.id field with a UUID by default. Agents may set their own custom meta.id upon sending to overwrite the generated ID.

      In addition, Agent.send() now returns the meta.id of the sent message. This way you may store the generated ID for your own purposes.

    • Removed the use of meta.response_id and meta.request_id. These have been replaced by meta.parent_id. I think the term "parent" is clearer. This choice is inspired by the Jupyter messaging docs.

      To be clear, meta.parent_id if set, refers to the meta.id of 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 the request() method) will invoke the handle_action_value() and handle_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() and get_chatbot_message() methods for an example.

    • Agent.original_message() has been renamed to Agent.parent_message(). Additionally parent_message() takes a message as a parameter, allowing you to traverse a chain of messages in reverse.

    • Internally renamed Agent._pending_responses to Agent._pending_requests which 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_STYLE environment variable.

    • Log "warning" messages for unimplemented handle_action_value and handle_action_error methods have been updated to only print once per session, in order to reduce logging noise in the default setting.

    • Tests and documentation updated.

  5. 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

用户点评

登录用户的真实使用记录,可按版本和硬件筛选
共 0 条

    还没有人点评。第一个说出真实体验的人最有价值。

    README 原文

    未翻译

    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

    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

    See the issues page.

    If you have any suggestions or otherwise, feel free to add an issue or open a discussion.