I'm sure your question is showing a simplified case relative to what you really need to accomplish. For the general solution, I concur that protocols are a decent approach.
You asked about multimethods, but the trouble you'll run into is with the dispatch function. defmulti takes a dispatch function which will be called on the arguments to the real function. The dispatch function must return a value that can then be used to select which method implementation will be invoked.
The trouble is, what do you dispatch on? To discriminate between collection types, you'd end up with something like this:
(defmulti stringify class)
(defmethod stringify clojure.lang.PersistentVector [v] ...)
(defmethod stringify clojure.lang.PersistentArrayMap [m] ...)
;;; More dispatching on concrete class names
Well, as soon as you see specific clojure.lang class names appearing in your code, all kinds of alarm bells should be going off. These are way too specific... they'll break if the Clojure core library changes, they won't work very cleanly with Java interop, they don't cover user-defined types that happen to implement Seqable... in short, they are a breakdown of abstraction.
Any time you would be tempted to dispatch on class names, whether from Clojure, Java, or 3rd party libraries, you should always reach for extend-type instead.