I think there's some confusion here between the keyword and its textual representation.
The root issue is that the keyword function is, in a way, too lenient in its error checking: it will allow you to create keywords that are not valid according to the language definition. The Clojure reader is a bit more restrictive, though it too will allow a number of exceptions to the official definition on the main Clojure website.
For example, the reader will accept keywords with # or . in their name, which is used by some libraries to represent css ids and classes. These two characters are not valid in the name of a keyword as per the language definition.
The keyword function will let you create a keyword whose name starts with a colon, or whose name contains a space. These are not accepted by the reader and definitely do not match the language definition.
When you manually write ::hello in a Clojure file, the reader will interpret that as :user/hello, i.e. a keyword with user as its namespace and hello as its name. Neither the slash nor the colon are part of the keyword itself; they are just part of the syntax Clojure uses to represent keywords in a textual form.
With the keyword function, if you call (keyword ":hello"), you get a keyword that has ":hello" as a name. That is not valid data for that function, but it can be created in memory. There is, however, no syntax in Clojure that can correctly represent that keyword textually. If you try to print it, you will see ::hello, but that is fundamentally different from you writing ::hello. In other words you have created a keyword that does not roundtrip: if you print it and then read it, you will not get the same value again.
Similarly if you use the keyword function to create a keyword with a space, you will not be able to read it back as its textual representation will look like a keyword and a symbol.