Replies: 10 comments 6 replies
-
Thanks @albertpod. This is very exciting, I would like to help out with this. Standardizing the agent creation API will be an immensely valuable contribution! I've begun some very tentative explorations in this direction by investigating how best to hook up an RxInfer model within an RxEnvironments agent/environment dyad. @wouterwln has been invaluable counsel to that end. You can access my repo of these explorations here. TL;DR on my musings is: yes, a standard imperative main loop is probably best for initial implementation and no, I have not managed RxInfer model integration yet. I'll enumerate my thoughts and responses to your specifics as per their level of abstraction. Global ConsiderationsThe most abstract consideration that I would like to raise is where best to implement this agent API. Within RxInfer.jl (proper) or say RxEnvironments.jl? Should this even constitute a totally new package: "RxAgents.jl"; using RxInfer.jl and RxEnvironments.jl as dependencies? Personally, I think that it might be wisest to implement this in a new "RxAgents.jl" package. An "RxAgents.jl" agent could then fairly seamlessly instantiate an RxEnvironments.jl RxEntity. With the subsequent specification of the environment "Entity" and the definition of the interface functions from RxEnvironments, the full dyad would be complete - regardless of the commitment to an imperative/reactive paradigm. Core Agent InterfaceI like this proposed structure. I'm afraid I don't have any other thoughts on this right now. Key Operations
Open Questions:
Final Comments:Regarding the overall structure, I have no enlightening comments. I do wonder how/if specific methods will have to change to deal with reactivity. I think it is best to focus on an imperative implementation first. I can't think of any additional operations that might be nice to include, other than to perhaps optionally record the agent's history of states in addition to its current state. I haven't found/used any alternative approaches though @kobus78 may well have done so in the course of his extensive implementations. Regarding integration with RxEnvironmnments, I am very much in favour of this. I think that the agent API could neatly constitute an RxEntity and it seems to me that the question of multiple agent support could be partitioned off to RxEnvironments. I am very keen to assist with any aspect of this endeavour, going forward. I hope these thoughts are somewhat useful. |
Beta Was this translation helpful? Give feedback.
-
Thanks for bringing this @albertpod! I also mostly agree with @FraserP117, but I would still make some practical changes to the for loop, as it looks quite odd to me. Why the return value of the Of course, I know the answers to these questions, but it would be better if they didn’t arise in the first place. Here’s my proposed revision, which addresses these concerns: agent = Agent()
environment = Environment()
# Main agent loop
for t in 1:n_steps
# Prepare for the next time-step, can do nothing on the first iteration
# and "slide" on the next ones or do whatever it wants essentially
prepare!(agent)
# IMO `plan` should return "something", namely a "plan" or a series of actions
actions = plan!(agent, horizon=10)
# Execute next action (either first, or some other "picking" mechanism)
act!(environment, agent, first(actions))
# Get environment feedback, different agents observe different stuff
observation = observe!(environment, agent)
# Update agent's beliefs about the internal state of the world to be able to `act!` later on
learn!(agent, observation)
end which translates to the following core API:
prepare!(agent::BayesianAgent) -> Nothing
plan!(agent::BayesianAgent, horizon::Int) -> Vector{Action}
act!(environment::Environment, agent::BayesianAgent, action::Action) -> Nothing (or Success/Fail status?)
observe!(environment::Environment, agent::BayesianAgent) -> Observation
learn!(agent::BayesianAgent, observation::Observation) -> Nothing I don't have a strong opinion on whenever to use We also need some feedback from @wouterwln since he designed the API for RxEnvironments.jl and perhaps my proposal does not perfectly align with the API in RxEnvironments.jl. |
Beta Was this translation helpful? Give feedback.
-
I'll try to structure my feedback as well as I can. I like the idea of the API, and I think indeed, as Fraser said, we should incorporate it in a separate package
Now we have to think about some stuff. In my current POMDP implementation, I have the following structure:
(Ignoring backwards messages from the planning stage towards
And most of this is stuff we can hide. Let's discuss what we can hide and what we cannot. The API for
or something similar, at least a direct alias. This will trigger the environment to send an observation back to the agent which can be accessed either explicitly, or we can subscribe to it. In the end we can also do something like this:
And do some smart stuff with receding time horizons and such. RxEnvironments keeps these options open for you and I think we can write boilerplate on top of RxInfer and RxEnvironments which marries these interfaces. Let me know what you guys think. |
Beta Was this translation helpful? Give feedback.
-
Thank you for your work on this and acceptance of feedback. I am in much agreement with prior points, especially Albert's loop logic/ordering (the
I've given a fair amount of feedback on this so, just wanted to really share my thoughts on these other ends while I'm still available. Again, great work, will watch developments. |
Beta Was this translation helpful? Give feedback.
-
I would love to see this standardization effort embrace an even wider scope. As I see it, the
As 'traditional' machine learning seems to grow towards the bayesian approach, I would love to see our thinking also embrace the above so that the API will be generic enough, in both semantics and syntax, to cover all of the above. Indeed there are examples available already that showcase the applicability of RxInfer to the non-sequential areas. I think RxInfer could really become the tool for everyone, especially now that a Python implementation is also planned. Here is an example of what I mean. To consider the next data point in the case of:
To get a fuller picture of my thinking, please have a look at the following 2 posts, in particular the section 'Symbols/Nomenclature/Notation (KUF)' as well as the section 'MODELING' where the implementation happens: https://learnableloop.com/posts/LitterModel_PORT.html Best wishes with your valuable work! |
Beta Was this translation helpful? Give feedback.
-
Thanks to everyone for their input @LearnableLoopAI @bvdmitri @FraserP117 @wouterwln @apashea! I suggest spending some time during the next RxInfer meeting to devise the tasks and create the milestones associated with this discussion. |
Beta Was this translation helpful? Give feedback.
-
Thanks @albertpod, I'm really looking for ward to assisting with this. Yes I think that we can/should discuss the tasks and milestones for this project in the next RxInfer meeting. It's very possible to host the various milestones/tasks as an Institute page though I won't presume to know if that would be appropriate. A Suggested Course For Development:I would just like to offer something as an idea... I think it might be nice to have a running example/test case with which to experiment in creating the new agent API. The hope would be that we all get to focus/work on the same example, for ease of coordination/idea sharing/implementation. I propose that we use the existing Active Inference Mountain Car agent as this example. This is probably the best and most widely recognised implementation of an Active Inference agent with RxInfer - a natural starting point. RxEntities and RxEnvironments - Reiteration:As I mentioned before, I can see RxEnvironmetns.jl splitting into RxEnvironments (proper) and the new "RxAgents.jl". Both would use the RxEntity type to instantiate an agent and an environment. This is only a suggestion, though I think a good case can be made for it. My Experimentation:I have made a totally new Jupyter Notebook in an attempt to satisfy the above points. In this notebook, I am recreating the existing Active Inference Mountain Car agent with RxEnvironments.jl. I think this example could constitute a central working example with which to design and create the burgeoning agent API. Please feel free to make branches and do what you will. This is only a suggestion, perhaps there are other, better ways to start on this. Note: I have only managed to implement the "naive" agent policy with RxEnvironmetns.jl so far but I can see a direction as to how we should implement the proper Active Inference agent. This will involve specific choices as to the "act", "plan", and "observe" functions - exactly the sorts of choices that this discussion is designed to address. Many thanks again! Let me know what you think. |
Beta Was this translation helpful? Give feedback.
-
Hello all ~ Picking this back up after a discussion with @FraserP117 earlier today. We talked about how the Server-Client interface, is separable/distinct from the semantics of the Agent-Environment interface. Leaving the Server-Client topic aside, this motivated some discussion around a suitable level of constraint for a "standard API for RxInfer-based Agents" (what this thread is all about!). So on that wavelength, I worked today here: https://github.com/docxology/RxInferExamples.jl/tree/main/research/agent . That is a generic system where there are folders for Agents and Environment, then generic configuration, composition, logging, and simulation methods. There are type checks for the interface, so that at the generic level, the methods are just testing for the state space typing-coherence (hence the "handle for the agent-environment" interface, is minimally opinionated). Here are the typing check methods. For example HERE is Mountain Car Active Inference agent (where the @model is described), and HERE is the Mountain Car environment. Then HERE is an extremely thin orchestrator, which configures/points to which Agent + Environment to compose together and simulation. That simulation uses RxInfer methods/calls and outputs the simulation HERE. So to return to this question of generic Agent API -- my feeling is that since there are an infinite variety (indeed an Infinite Jest!) of Agents and Environments (hence transfinite number of combinations). Hence, in terms of what level of abstraction and type/extent of opinionation in an open source infrastructure-grade synthetic intelligence package (#RxInfer #ActiveInference), what resonates with me, is that the "standardization" level is just "the agent and the environment should match (and/or it should be obvious what the set-theoretic relationship is between Environment output, Agent perception, Agent action, Environment input). Within that meta-standardization situation, there could be further opinions (e.g. the Agent-Environment must match 1:1 with no excess, or have some match but it is OK if there are extra pieces overhanging or missing expected pieces). And of course those opinions cascade all the way down to the domain and model "Minute Particulars". There are also many degrees of freedom in specifying the simulation orchestration, as @apashea and others raise in this thread. And that capacity of RxInfer to support custom and reactive scheduling/logistics on Graphs, is a key advantage of the package. I feel that having the interface well-specified and flexible (as I believe the approach presented here is), gives total flexibility in simulation design, deployment, and operation. |
Beta Was this translation helpful? Give feedback.
-
@docxology @FraserP117 For the agent-environment interaction model, I think we should not impose tight constraints a priori, but provide the user with a toolbox that they can use to freely implement any additional constraints themselves. My first attempt at this was I've been working on a toolbox that would be a little bit easier to use, I'd love to get your thoughts on it. The (pseudo)code would look something like this: observations = []
# Do state inference whenever an observation comes in
every(observations) do obs
state_inference!(agent, obs)
end
# Make a plan every 50 milliseconds
every(50ms) do dt
plan!(agent)
end
# every 3 seconds do parameter learning
every(3s) do dt
learn!(agent)
end
# every 10ms do an update and present a new observation to the agent.
every(10ms) do dt
update!(environment, dt)
push!(observations, generate_observation(environment, agent)
end
# Run the sim for 10 seconds
for_next(10s) do
update!()
end The point here is to disentangle the different ongoing processes and scheduling them as independent jobs that run in relative isolation from each other (apart from sharing computational resources). I think an API like this would be expressive enough to capture most agent-environment interactions, while also allowing the user to build more constrained protocols (like 1:1) WDYT? |
Beta Was this translation helpful? Give feedback.
-
Thanks for the comments, I will provide some thoughts here. @wouterwln I agree with " I think we should not impose tight constraints a priori, but provide the user with a toolbox that they can use to freely implement any additional constraints themselves.". I think there are two separate issues here:
As to @FraserP117 's Option's, which focus on this RxEnvironment-like question of (a)synchronicity with and among entities. I think in Option 1, you bring up this issue that any locking operation (even a very short one, especially long ones) would then beget secondary questions of what happens if "you knock on the door and it is locked". Option 2 does seem preferable, as this is the approach taken by performant distributed database software, such as Kafka. Regardless, the approach to among-agent event passing (not to confuse the database engineer's concept of "message passing" among nodes, with the Bayesian graphical modeler's concept of [e.g. variational] message passing on factor graphs) -- that is a separable question from the API standard itself. It may be quite literally the distinction between Space and Time, where the API standard is (shared, composable) space, and the inter-entity handing describes the temporality of coordination. My focus is on the API schema itself, because then users could hook up RxInfer to arbitrary database approaches/backends/schedules. Perhaps a new thread could be created, e.g. "Entity interface API" for the schema definition (which I have suggested above, should be a meta-standard of just checking for coherence, reporting on that, and enabling user opinions on how much coherence they require), and "Among-Entity Orchestration" for discussion separate from the API interface, how to enable different coordination schedules/approaches, whether the interface itself is simple (e.g. binary bits flowing bi-directionally), or more sophisticated (many fields of different types). |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
We're looking to establish standardized APIs for implementing Bayesian (AIF) agents using RxInfer. While there's ongoing research about the implementation details of planning functions, having a clear interface would help developers start building agents with our toolbox.
Current State
Currently, we have scattered examples like the mountain car and drone simulations that demonstrate agent capabilities, but they lack a developer-friendly API structure. The implementations mix concerns and require deep understanding of the internals.
Proposed API Structure
Here's a proposed high-level API structure for discussion:
Core Agent Interface
Key Operations
I propose standardizing these core operations:
Example Usage
Note: The following examples use an imperative loop structure for clarity. Our end goal is to provide a fully reactive implementation. These examples serve as a conceptual starting point to illustrate the core operations.
Open Questions
Configuration Options: What configuration options should be available?
Multi-Agent Support: How should we extend this API for multi-agent scenarios?
Request for Comments
We'd love to hear your thoughts on:
RxEnvironments.jl
Please share your experiences and suggestions below!
Note: This is an initial proposal to start the discussion. All interfaces are subject to change based on community feedback and practical implementation experience.
Beta Was this translation helpful? Give feedback.
All reactions