# How to narrow the variants of agents returned by \`random\_agent\`?

**URL:** <https://discourse.julialang.org/t/how-to-narrow-the-variants-of-agents-returned-by-random-agent/135674>\
**Category:** Modelling & Simulations\
**Tags:** agents\
**Created:** [February 16, 2026, 9:51am UTC](https://discourse.julialang.org/t/how-to-narrow-the-variants-of-agents-returned-by-random-agent/135674 "2026-02-16T09:51:57Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![filipe](https://avatars.discourse-cdn.com/v4/letter/f/35a633/32.png) [@filipe](https://discourse.julialang.org/u/filipe)\
**Post date:** [February 16, 2026, 9:51am UTC](https://discourse.julialang.org/t/how-to-narrow-the-variants-of-agents-returned-by-random-agent/135674/1 "2026-02-16T09:51:57Z")

</div>

Hello! Is there a way to tell `random_agent` which variant of a `@multiagent` model to return?

My specific problem is this:

```julia
@agent struct Supplier(NoSpaceAgent)
    sellingPrice::Float64 = 1
end

@agent struct Buyer(NoSpaceAgent)
    supplier::Supplier
end

@multiagent MarketActor(Buyer, Supplier)

# […]

# When initially adding agents to the model
supplier = random_agent(model, a -> variantof(a) <: Supplier) # `supplier` is a MarketActor
add_agent!(MarketActor ∘ Buyer, model; supplier) # which cannot be converted to a narrower type(?)

```

I guess I could just store IDs instead of an actual pointer to the supplier, but that seems… less clean? I don’t know.

Thank you in advance!

EDIT: I think the more general question is how to, in general, “narrow” agent variants? Is this possible?

---

<div class="post-metadata">

**Author:** ![Datseris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/datseris/32/13406_2.png) [@Datseris](https://discourse.julialang.org/u/Datseris)\
**Post date:** [February 16, 2026, 10:21am UTC](https://discourse.julialang.org/t/how-to-narrow-the-variants-of-agents-returned-by-random-agent/135674/2 "2026-02-16T10:21:18Z")

</div>

Can you clarify whether your question is about (a) altering the return value of `random_agent` or (b) using the current return value in `add_agent!`? Sounds like different questions to me. If your question is both that’s okay as well 😃

---

<div class="post-metadata">

**Author:** ![filipe](https://avatars.discourse-cdn.com/v4/letter/f/35a633/32.png) [@filipe](https://discourse.julialang.org/u/filipe)\
**Post date:** [February 16, 2026, 10:25am UTC](https://discourse.julialang.org/t/how-to-narrow-the-variants-of-agents-returned-by-random-agent/135674/3 "2026-02-16T10:25:23Z")

</div>

Hey! Thanks for the help 🙂

Well, I think it’s both. So, more specifically, I’d ideally like to:

(a) be able to narrow the returned value’s type, based on the condition function passed to `random_agent`  
or (b) narrow it later, after it’s been returned as the more generic `@multiagent`

Does this make sense? I’m new to this 😛

---

<div class="post-metadata">

**Author:** ![Datseris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/datseris/32/13406_2.png) [@Datseris](https://discourse.julialang.org/u/Datseris)\
**Post date:** [February 16, 2026, 10:30am UTC](https://discourse.julialang.org/t/how-to-narrow-the-variants-of-agents-returned-by-random-agent/135674/4 "2026-02-16T10:30:54Z")

</div>

Well, I can asnwer (a) easily: since you use `@multiagent`, all agents are of type `MarketActor`. Your condtion is correct, you have specified the variant, so the `MarketActor` you found is of variant `Supplier`. You cannot narrow the type `MarketActor` more, as there is no narrower type. That’s how `@multiagetn` works.

FOr question (b) this is just about how you add an agent of a specific variant to the model? You can extract the variant of an agent with `variantof`, you have done so already. If so I’d recommend reading again the usage of `@multiagent` in the tutorial. (Idon’t remmeber the answer)

---

<div class="post-metadata">

**Author:** ![filipe](https://avatars.discourse-cdn.com/v4/letter/f/35a633/32.png) [@filipe](https://discourse.julialang.org/u/filipe)\
**Post date:** [February 16, 2026, 10:39am UTC](https://discourse.julialang.org/t/how-to-narrow-the-variants-of-agents-returned-by-random-agent/135674/5 "2026-02-16T10:39:58Z")

</div>

Most of that makes sense to me!

My confusion, still, is: how do I access properties that are specific to a given variant, if I have no way of narrowing it down?

For example, to calculate the minimum price at a given time step, I’d love to do something like:

```julia
suppliers = filter(a -> variantof(a) == Supplier, allagents(model))
min_price = reduce((a, b) -> minimum(a.selling_price, b.selling_price))

```

But I don’t think I can do this, since `suppliers` is the a more generic typed array, and thus I cannot access its elements’ `selling_price` property.

Again, I hope this is not completely wrong!

---

<div class="post-metadata">

**Author:** ![Datseris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/datseris/32/13406_2.png) [@Datseris](https://discourse.julialang.org/u/Datseris)\
**Post date:** [February 16, 2026, 10:47am UTC](https://discourse.julialang.org/t/how-to-narrow-the-variants-of-agents-returned-by-random-agent/135674/6 "2026-02-16T10:47:29Z")

</div>

> [@filipe](#):
>
> My confusion, still, is: how do I access properties that are specific to a given variant, if I have no way of narrowing it down?

I see. Yes, there is no documentation about this in the tutorial. It kinda assummes that you know the properties of each variant, which you must, since you defined them.

I am not sure if there is an automated way to do what you want to do, perhaps @Tortar knows?

And if you do find such a way please consider contributing it to Agents.jl!

---

<div class="post-metadata">

**Author:** ![Tortar](https://avatars.discourse-cdn.com/v4/letter/t/6bbea6/32.png) [@Tortar](https://discourse.julialang.org/u/Tortar)\
**Post date:** [February 16, 2026, 1:51pm UTC](https://discourse.julialang.org/t/how-to-narrow-the-variants-of-agents-returned-by-random-agent/135674/7 "2026-02-16T13:51:07Z")

</div>

I’m not really getting what is the problem, this seems to work fine (on the `dev` version)?

```julia-auto
julia> using Agents

julia> @agent struct Supplier(NoSpaceAgent)
           sellingPrice::Float64 = 1
       end

julia> @agent struct Buyer(NoSpaceAgent)
           supplier::Supplier
       end

julia> @multiagent MarketActor(Buyer, Supplier)

julia> model = StandardABM(MarketActor)
StandardABM with 0 agents of type MarketActor
 agents container: Dict
 space: nothing (no spatial structure)
 scheduler: fastest

julia> supplier = random_agent(model, a -> variantof(a) <: Supplier)

julia> supplier = Supplier(1, 1.)
Supplier(1, 1.0)

julia> add_agent!(MarketActor ∘ Buyer, model; supplier)
MarketActor(Buyer(1, Supplier(1, 1.0)))

```

---

<div class="post-metadata">

**Author:** ![filipe](https://avatars.discourse-cdn.com/v4/letter/f/35a633/32.png) [@filipe](https://discourse.julialang.org/u/filipe)\
**Post date:** [February 16, 2026, 2:13pm UTC](https://discourse.julialang.org/t/how-to-narrow-the-variants-of-agents-returned-by-random-agent/135674/8 "2026-02-16T14:13:11Z")

</div>

> [@Datseris](#):
>
> And if you do find such a way please consider contributing it to [Agents.jl](https://juliaregistries.github.io/General/packages/redirect_to_repo/Agents)!

Of course! To code? I don’t have the skill for that in Julia… ☹ But to documentation, yeah 🙂

---

<div class="post-metadata">

**Author:** ![filipe](https://avatars.discourse-cdn.com/v4/letter/f/35a633/32.png) [@filipe](https://discourse.julialang.org/u/filipe)\
**Post date:** [February 16, 2026, 2:14pm UTC](https://discourse.julialang.org/t/how-to-narrow-the-variants-of-agents-returned-by-random-agent/135674/9 "2026-02-16T14:14:19Z")

</div>

I don’t understand, exactly.

> [@Tortar](#):
>
> ```julia-auto
> julia> supplier = Supplier(1, 1.)
> Supplier(1, 1.0)
> 
> ```

You just created a new Supplier, overwriting the one returned by `random_agent`, no?

Without that, I get the type error:

```julia-auto
ERROR: MethodError: Cannot `convert` an object of type MarketActor to an object of type Supplier
The function `convert` exists, but no method is defined for this combination of argument types.

```

EDIT: but your code gave me an idea. It’s not very pretty, but it’s possible to do this:

```julia-auto
julia> supplier = random_agent(model, a -> variantof(a) <: Supplier)
julia> supplier = Supplier(id = supplier.id, sellingPrice = supplier.sellingPrice)

```

Basically, creating a new Supplier struct with the random `MarketActor` taken. This should be fine, no?

---

<div class="post-metadata">

**Author:** ![Tortar](https://avatars.discourse-cdn.com/v4/letter/t/6bbea6/32.png) [@Tortar](https://discourse.julialang.org/u/Tortar)\
**Post date:** [February 16, 2026, 3:27pm UTC](https://discourse.julialang.org/t/how-to-narrow-the-variants-of-agents-returned-by-random-agent/135674/10 "2026-02-16T15:27:36Z")

</div>

I’m still a bit confused, but I understand that my previous code could be somewhat difficult to interpret, maybe this is what you need:

```julia-auto
julia> using Agents

julia> @agent struct Supplier(NoSpaceAgent)
           sellingPrice::Float64 = 1
       end

julia> @agent struct Buyer(NoSpaceAgent)
           supplier::Supplier
       end

julia> @multiagent MarketActor(Buyer, Supplier)

julia> model = StandardABM(MarketActor)
StandardABM with 0 agents of type MarketActor
 agents container: Dict
 space: nothing (no spatial structure)
 scheduler: fastest

julia> add_agent!(MarketActor ∘ Supplier, model; sellingPrice=1.)
MarketActor(Supplier(1, 1.0))

julia> supplier = random_agent(model, a -> variantof(a) <: Supplier)
MarketActor(Supplier(1, 1.0))

julia> add_agent!(MarketActor ∘ Buyer, model; supplier=variant(supplier))
MarketActor(Buyer(2, Supplier(1, 1.0)))

```

this is the way to add both a `Buyer` (with a random supplier) and a `Supplier` to the model, given your definition of agent types.

---

<div class="post-metadata">

**Author:** ![Datseris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/datseris/32/13406_2.png) [@Datseris](https://discourse.julialang.org/u/Datseris)\
**Post date:** [February 16, 2026, 3:46pm UTC](https://discourse.julialang.org/t/how-to-narrow-the-variants-of-agents-returned-by-random-agent/135674/11 "2026-02-16T15:46:22Z")

</div>

this to me seems like the solution!

Furthermore, to comment:

> [@filipe](#):
>
> I guess I could just store IDs instead of an actual pointer to the supplier, but that seems… less clean? I don’t know.

I think in your specific setup that is a better, and cleaner solution actually. Referencing the ID instead of the agent.

---

<div class="post-metadata">

**Author:** ![filipe](https://avatars.discourse-cdn.com/v4/letter/f/35a633/32.png) [@filipe](https://discourse.julialang.org/u/filipe)\
**Post date:** [February 16, 2026, 8:14pm UTC](https://discourse.julialang.org/t/how-to-narrow-the-variants-of-agents-returned-by-random-agent/135674/12 "2026-02-16T20:14:03Z")

</div>

Yes!! Thank you! The `variant` function returns the “narrower” variant of the agent. Nice 🙂
