This month's update is all about the Conversation Engine upgrades. There are still a lot of "pardon our dust" signs all over that module, but it's what I've been putting a lot of time into recently, so I'd better talk about where it's going.
The goal here has been to start enhancing conversation beyond the "ask a question, get an answer" or "make a request, get a response" interactions that have been the bread and butter of the thing for a while. I worked in two different directions: first, expanding the repertoire of things Acuitas can say spontaneously, and second, adding responses to personal states reported by the conversation partner.
One of Acuitas' particular features - which doesn't seem to be terribly common among chatbots - is that he doesn't just sit around waiting for a user input or prompt, and then respond to it. The human isn't the only one driving the conversation; if allowed to idle for a bit, Acuitas will come up with his own things to say. This is a very old feature. Originally, Acuitas would only spit out questions generated while "thinking" about the contents of his own semantic memory, hoping for new knowledge from the human speaker. I eventually added commentary about Acuitas' own recent activities and current internal states. Whether all of this worked at any given time varied as I continued to modify the Conversation Engine.
In recent work, I used this as a springboard to come up with more spontaneous conversation starters and add a bit more sophistication to how Acuitas selects his next topic. For one thing, I made a point of having a "self-facing" and "speaker-facing" version of each option. The final list looks something like this:
States:
Self: convey internal state
Speaker: ask how speaker is
Actions:
Self: say what I've done recently
Speaker: ask what speaker has done recently
Knowledge:
Self: offer a random fact from semantic memory
Speaker: ask if the speaker knows anything new
Queries:
Self: ask a question
Speaker: find out whether speaker has any questions
Selection of a new topic takes place when Acuitas gets the chance to say something, and has exhausted all his previous conversation goals. The selection of the next topic from these options is weighted random. The weighting encourages Acuitas to rotate among the four topics so that no one of them is covered excessivly, and to alternate between self-facing and speaker-facing options. A planned future feature is some "filtering" by the reasoning tools. Although selection of a new topic is random and in that sense uncontrolled, the Executive should be able to apply criteria (such as knowledge of the speaker) to decide whether to roll with the topic or pick a different one. Imagine thinking "what should I say next" and waiting for ideas to form, then asking yourself "do I really want to take the conversation there?" as you examine each one and either speak it or discard it. To be clear, this isn't implemented yet. But I imagine that eventually, the Conversation Engine's decision loop will call the topic selection function, receive a topic, then either accept it or call topic selection again. (For now, whichever topic gets generated on the first try is accepted immediately.)
Each of these topics opens up further chains of conversation. I decided to focus on responses to being told how the speaker is. These would be personal states like "I'm tired," "I'm happy," etc. There are now a variety of things Acuitas can do when presented with a statement like this:
*Gather more information - ask how the speaker came to be in that state.
*Demonstrate comprehension of what the speaker thinks of being in that state. If unaware whether the state is positive or negative, ask.
*Give his opinion of the speaker being in that state (attempt sympathy).
*Describe how he would feel if in a similar state (attempt empathy).
*Give advice on how to either maintain or get out of the state.
Attempts at information-gathering, if successful, will see more knowledge about the speaker's pleasure or problem loaded into the conversation's scratchboard. None of the other responses are "canned"; they all call reasoning code to determine an appropriate reply based on Acuitas' knowledge and nature, and whatever the speaker actually expressed. For instance, the "give advice" response calls the problem-solving function.
Lastly, I began to rework short-term memory. You might recall this feature from a long time ago. There are certain pieces of information (such as a speaker's internal states) that should be stored for the duration of a conversation or at least a few days, but don't belong in the permanent semantic memory because they're unlikely to be true for long. I built a system that used a separate database file as a catch-all for storing these. Now that I'm using narrative scratchboards for both the Executive's working memory and conversation tracking, it occurred to me that the scratchboard provides short-term memory, and there's no need for the other system! Retrieving info from a dictionary in the computer's RAM is also generally faster than doing file accesses. So I started revising the knowledge-storing and question-answering code to use the scratchboards. I also created a function that will copy important information from a conversation scratchboard up to the main executive scratchboard after a conversation closes.
I'm still debugging all this, but it's quite a bit of stuff, and I'm really looking forward to seeing how it all works once I get it nailed down more thoroughly.
Blog version has hyperlinks to past articles:
https://writerofminds.blogspot.com/2024/09/acuitas-diary-76-september-2024.html