I suppose you meant this to be __MODULE__.example_func(id, path)?
This calls the function and then passes the result (:ok because of IO.puts) to Agen.start_link/2, such this becomes: Agent.start_link(:ok, name: __MODULE__).
Agent.start_link/2 expects its first argument to be 2 function though, not an atom. What you probably want to do is Agent.start_link(fn -> example_func(id, poth) end, name: __MODULE__).
Agents and GenServers compare like apple and oranges. I see agents as a “conceptual study” of Clojure’s Agent’s as it is implemented with a BEAM (the Erlang virtual machine) process.
The Agent is essentially a container of state that organizes access to that state in an orderly manner, which in Elixir takes advantage of
the process mailbox
strictly sequential execution of code within a single process.
But given that those properties are part to every process running within the BEAM makes Agents not all that important in Elixir.
What you are likely looking for is Tasks which is just a thin wrapper around BEAM processes that are usually managed on the lowest level with the concurrency primitives of spawn/1, or spawn_link/1, send/2 and receive/1 (11. Processes).
GenServer is then simply the OTP level abstraction of the generic building block for building a process that adheres to the established OTP interaction protocols - and a “system” is composed of many such processes interacting with one another.
The reason Agents keep attracting attention is because they are an easy emulation of mutable state. But again the fundamental mechanism by which state evolves in BEAM processes is through an infinitely recursing function which keeps passing the updated state to itself (see State).