This was originally a comment, because it was small. However, I do believe that Guy Steele has done the thing you describe, and recorded it on film.
Check out Growing a Language or read its transcript. He goes through how to go about developing such a language in a completely unambiguous manner. He has a particular trick to making it happen, which is pure brilliance to watch (if you're a language geek like myself. It might be a bit slow and pedantic at first if you aren't).
Just to make this into more of an answer instead of a comment, here's a bit on semantic networks which may be useful for you.
Another useful thing I have found along these lines is semantic networks. In particular, languages like RDF and OWL concentrate on how to express semantic meaning of words unambiguously. They do so by creating exorbitantly long words in the form of a IRI (an internationalized URL). While your speakers likely do not use such a mouthful explicitly, its very useful to see what tools we, as humans, have had to use in order to create unambiguous grammars. In particular, OWL permits inference about words, so if you know the word "blue" and come across "cyan," you can start inferring some of the meanings of "cyan" from the words you already know.
Beyond that, I would recommend at looking at Jakobson's functions of language. Its a really useful framework for thinking about language. He defined six functions of language, which can be used to describe how language works: Sender, Reciever, Context, Message, Channel, and Code. Let's use these with a very concrete example. In the above semantic languages like RDF one might write
<http://example.org/bob#me> <http://xmlns.com/foaf/0.1/knows> <http://example.org/alice#me> .
That's a really specific way of saying "Bob knows Alice" in a way which is completely unambiguous. There's no way a listener misinterprets "knows" in the biblical sense, because http://xmlns.com/foaf/0.1/knows
does not mean that kind of "knows." If you don't believe me, you can look at the documentation for Friend of a Friend (foaf) and see the precise meaning of "knows." Or you can look at the OWL ontology for foaf and have a computer construct inferences about these words based on thing you already know. It is a word that is completely defined by the Code (to use one of Jakobson's functions) that I am speaking with.
So this works, but it is messy. If we had to speak that precisely all the time, we'd be doomed. This is where Jakobson's functions help. What we can say is that the content is all in the Message, one of his six functions. It's all in the text, right there. To be more efficient, we have to move it somewhere else. We can't get rid of it (or we could introduce ambiguity), but we can move it. We can move it into the Channel:
@PREFIX alice: <http://example.org/alice#> .
@PREFIX bob: <http://example.org/bob#> .
@PREFIX foaf: <http://xmlns.com/foaf/0.1/> .
bob:me foaf:knows alice:me .
Technically this is a language related to RDF called Turtle... in the name of being unambiguous in my language.
In this example, we've defined 3 "prefixes," as the language calls them, which let us do simple substitutions. Now the line bob:me foaf:knows alice:me .
is still unambiguous, but its a heck of a lot shorter because we stuffed all that extra disambiguation into the message. The whole thing is longer now, but its easy to see that if we were to talk a lot about Bob and Alice, this would help quite a lot!
Or, we can stuff that extra stuff into the Context, another one of Jakobson's functions. The Context is something humans rely on very often to ensure unambiguous communication without saying too much. Once our context can specify which people and verbs we are using, we can drop even more complexity.
:bob :knows :alice .
Wow, that was simple! And still unambiguous. Of course, if we don't agree on the context, ambiguity can remain. But we can talk about things in the Context using the Message (assuming the above prefixes are still in the Channel):
@PREFIX owl: <http://www.w3.org/2002/07/owl#> .
:alice owl:sameAs alice:me .
:bob owl:sameAs bob:me .
:knows owl:sameAs foaf:knows .
Here I am using owl:sameAs
which is another one of those excruciatingly unambiguous terms, defined in the language OWL. You are free to disambiguate it as much as you please -- it can be taken all the way down to mathematical logic if one desires.
What is interesting here is that, if you have a means for detecting ambiguity in the Context, you don't have to say it. Only when you detect ambiguity would you have to query the speaker, asking them to put the Context into the Message.
This process is a very human process. When we lament how hard it is to get someone to understand what we mean in text, when its easy to communicate in speech, its partly because speech is a two way street. If there's ambiguity, the Receiver can communicate back to the Sender, asking for clarification and adjustment of the Channel or the Context. Take away that two-way communication, such as in writing or in a televised speech, and we have to be much more careful, relying heavily on the Message, Code, and Receiver.
Do I think any species would ever speak a dialect of RDF or Turtle. Heck no. They'll have a much smarter system, just like we do with natural language today. But, if you seek the unambiguous communication you ask for in your question, its worth looking at the constructed languages that humans have made in an attempt to be unambiguous.