Conversation With Things is a fascinating journey into the world of conversational design. Authors Diana Deibel and Rebecca Evanhoe have gone to great lengths to produce the introduction they wish they'd had when they started. Two chapters, 'Talking like a Person' and 'Complex Conversations', truly demonstrate an understanding of the subject and convey the feeling that they are grounded in many years of practice and analysis.
Although the book was written before generative AI burst into the world, it remains relevant. The chapters on defining intents and documenting conversational pathways could easily be seen now as methods of evaluation and testing for human alignment with LLM-based conversational tools. I hope the authors will one day consider a second edition that encompasses practices in the age of generative AI.
ISBN: 978-1933820-26-2
Published: April 2021
https://rosenfeldmedia.com/books/conversations-with-things/
Reading notes:
The second chapter, titled "Talking Like a Person," explores various layers of complexity in human conversation. These themes interweave like the conversation structures they describe:
Conversation is co-created: Participants collaborate to achieve a shared goal or outcome.
Prosody and intonation are fundamental to spoken language, forming part of its structure rather than merely being add-ons in dialogue construction.
Turn-taking is the interplay through which conversation forms, encapsulating power structures and much more than its mechanics initially suggest.
Conversation unfolds in a messy manner; it is structured but not always in a formal exchange of turn-taking.
Repair: We are constantly repairing our conversations, bringing them back to a point where the process of co-creation works. According to Nick Enfield, this occurs approximately every 84 seconds when two people speak.
Accommodation involves a chain reaction of adjustments in response to each other and the situation during conversation.
Mirroring, or "limbic synchrony," entails matching posture, expressions, and gestures, as well as speech elements like pace, vocabulary, pronunciation, and accents; this process is called convergence.
Code-switching requires presenting different identities to elicit an outcome.
Politeness goes beyond a list of social constraints such as not licking a bowl in a restaurant; in conversation, it serves as a contract between parties. When considered alongside the concept of repairing, it leads to more dynamic and fluid ideas, as expressed by Onuigbo G. Nwoye:
"It’s a series of verbal strategies for keeping social interactions friction-free."
The authors regard Grice's Maxims as a somewhat simplistic foundation for conversation, covering cooperative principles but missing some important elements of conversational theory and design addressed in the points above.
I read this book as part of my research into linguistic user interfaces being built around LLMs and AI chat. While other chapters in the book contain a wealth of valuable material, I am only pulling out a few subjects that have specific interest to me at this time.
In the section dealing with scripted flows, the author identifies some of the most common question types posed to users. The book outlines six common question types which form the construction of turn-taking in older conversational tools:
Open-ended
Menu
Yes-or-no
Location
Quantifying
Instructional
There are a couple of useful UI elements that work with these questions: a conformational component and repeating request.
Ordering tasks is crucial for reducing cognitive load. This seems to be most related to the sequencing of instructions.
Spoken lists significantly increase cognitive load for users. The authors delve into detail on reducing complexity to enhance recall, which greatly impacts menu structures.
The absence of prosody in the simple conversion of written text to TTS (Text-to-Speech) significantly increases cognitive load. In the past, SSML (Speech Synthesis Markup Language) has been utilized and text has been scripted in a dialogue style.
Human conversation is multimodal. This simple statement was one of the strongest messages I took away from the book. We operate by blending all our senses simultaneously to facilitate conversation flow. We employ visual body language along with prosody and the content of our words to communicate effectively.
Lisa Falkson of the Alexa team found that when users are presented with visual and audio information together, they often mute the audio to focus on the visual information.
You can still utilize visual and audio information if you are employing strong visualization reinforced by audio. Lisa uses Alexa’s weather as an example. If you do this, the elements need to be synced. Lisa refers to this as the "temporal binding window" of 400 milliseconds.
https://www.cambridge.org/core/books/using-language/4E7EBC4EC742C26436F6CF187C43F239
https://www.researchgate.net/publication/231870679
https://onlinelibrary.wiley.com/doi/book/10.1002/9781118247273
https://en.wikipedia.org/wiki/Turn-taking
https://en.wikipedia.org/wiki/Conversation_analysis
https://www.hachettebookgroup.com/titles/n-j-enfield/how-we-talk/9780465059942/?lens=basic-books
Conversational Design could have been a straightforward view on the emergence of voice interfaces such as Alexa or the UI of customer service bots that live in the bottom right-hand corner of many sites. Instead, Erika Hall explores the rich possibilities of conversational language in UX from a more holistic and inquisitive standpoint. It's a much better book because of that.
ISBN: 978-1-952616-30-3
Published: March 6, 2018
https://abookapart.com/products/conversational-design
Reading notes:
The first section of the book really sings with its take on the history of spoken language at the centre of human interaction. Burned in my mind are two important insights it brings to the forefront.
In oral culture – “All knowledge is social and lives in memory”
A written culture – “Promotes authority and ownership”
“These conditions may seem strange to us now (oral culture). Yet, viewed from a small distance, they’re our default state. Because our present dominate culture and the technology that defines it depends upon advanced literacy, we’ve become ignorant of the depths of our legacy and blind to the signs of its persistence.”
The contrast in power dynamics is pronounced, transitioning from the shared ownership of knowledge in oral traditions to the individual possession we see today. Our current written and digital culture is held to together with concepts of individualism, intellectual property, single sources of authority and ownership at its heart.
The book outlines the key material properties of oral culture as:
Spoken words are events that exist in time.
It’s impossible to step back and examine a spoken word or phrase. While the speaker can try to repeat, there’s no way to capture or replay an utterance.
All knowledge is social and lives in memory.
Formulas and patterns are essential to transmitting and retaining knowledge. When the knowledge stops being interesting to the audience, it stops existing.
Individuals need to be present to exchange knowledge or communicate.
All communication is participatory and immediate. The speaker can adjust the message to the context. Conversation, contention, and struggle help to retain this new knowledge.
The community owns knowledge, not the individuals.
Everyone draws on the same themes, so not only is originality not helpful, it is nonsensical to claim an idea as your own
There are no dictionaries or authoritative sources.
The right use of a word is determined by how it’s being used right now
I am now reading Walter Ong “In Orality and Literacy: The Technologizing of the Word” which is reference in this part of the book.
The 'Principles of Conversational Design' chapter begins by defining an interface as 'a boundary across which two systems exchange information.' It quickly moves to argue that conversation is the original interface and remains the most widely understood and utilized.
Hall then explores the language philosopher Paul Grice's work on the four conversational maxims, and Robin Lakoff's work on 'The Logic of Politeness,' which introduces a fifth maxim.
The conversational maxims are the cooperative foundation or rules by which humans communicate effectively through conversation, referred to by Grice as the 'Cooperative Principle.
Maxim of Quantity: Information
Make your contribution as informative as is required for the current purposes of the exchange.
Do not make your contribution more informative than is required.
Maxim of Quality: Truth (supermaxim: "Try to make your contribution one that is true")
Do not say what you believe to be false.
Do not say that for which you lack adequate evidence.
Maxim of Relation: Relevance
Be relevant.
Maxim of Manner: Clarity (supermaxim: "Be perspicuous")
Avoid obscurity of expression.
Avoid ambiguity.
Be brief (avoid prolixity).
Be orderly.
Maxim of Politeness (Robin Lakoff)
Don’t impose
Give options
Make the listener feel good
The remainder of the book explores the practice of implementing Conversational Design within UX. It is well-written and contains a wealth of valuable material. At this point in time, my interest lies in researching the new linguistic user interfaces being built around LLMs (large language models) and AI chat. The first half of the book delivered that for me.
There are a number of points to extract from the rest of the book:
When confronting a new system, the potential user will have these unspoken questions.
Who are you?
What can you do for me?
Why should I care?
How should I feel about you?
What do you want me to do?”
The last questions “What do you want me to do?”. is reflected on later in the book by quoting Jim Kalbach’s work with navigation
Expectation setting: “Will I find what I need here?”
Orientation: “Where am I in this site?”
Topic switching: “I want to start over”
Reminding: “My session got interrupted. What was I doing?”
Boundaries: “What is the scope of this site”
https://abookapart.com/products/conversational-design
https://en.wikipedia.org/wiki/Walter_J._Ong
https://en.wikipedia.org/wiki/Paul_Grice
https://en.wikipedia.org/wiki/Robin_Lakoff
https://en.wikipedia.org/wiki/Cooperative_principle
https://experiencinginformation.com/
Two years ago I wrote a blog post about hosting Node.js servers on Scaleway. I have now started using Nginx to allow me to host multiple sites on one €2.99 a month server.
This tutorial will help you build a multi site hosting environment for Node.js servers. We are going to use a pre-built Ubuntu server image from Scaleway and configure Nginx as a proxy. SSL support will be added by using the free letsencrypt service. I have written this post to remind myself, but hopefully it will be useful to others.
Scaleway provides a number of server images ready for you to use. There is Node.js image but we will use the latest Ubuntu image and add Node.js later. At the moment I am using VC1S servers which is a dual core x86.
It takes a couple of minutes to build a barebones Ubuntu server for you.
$ ssh root@212.47.246.30
If, for any reason you changed the SSH key name from id_rsa remember to provide the path to it.
$ ssh root@212.47.246.30 -i /Users/username/.ssh/scaleway_rsa.pub
We first need to get the Node.js servers working. The Ubuntu OS does not have all the software we need so we start by installing Git, Node.js and PM2.
$ apt-get install git
curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash -
sudo apt-get install -y nodejs
$ npm install pm2 -g
$ cd /
$ md apps
$ cd /apps
$ md app1
$ md app2
const http = require("http");
const port = 3000; //3000 for app1 and 3001 for app2
const hostname = '0.0.0.0'
http.createServer(function(reqst, resp) {
resp.writeHead(200, {'Content-Type': 'text/plain'});
resp.end('Hello World! ' + port);
}).listen(port,hostname);
console.log('Load on: ' + hostname + ':' + port);
NOTE You can use command line tools like VIM to create and edit files on your remote server, but I like to use Transmit which supports SFTP and can be used to view and edit files on your remote server. I use Transmit "Open with" feature to edit remote files in VS Code on my local machine.
Rather than running Node directly we will use PM2. It has two major advantages to running Node.js directly, first is PM2 daemon that keeps your app alive forever, reloading it when required. The second is that PM2 will manage Node's cluster features, running a Node instance on multiple cores, bringing them together to act as one service.
Within each of the app directories run
$ pm2 start app.js
The PM2 cheatsheet is useful to find other commands.
Once you have started both apps you can check they are running correctly by using the following command:
$ pm2 list
The result should look like this:
At this point your Node.js servers should be visible to the world. Try http://x.x.x.x:3000 and http://x.x.x.x:3001 in your web browser, replacing x.x.x.x with your servers public IP address.
At this stage we need to register our web domains to using the public IP address provided for the Scaleway server. For this blog post I am going to use the examples alpha.glennjones.net and beta.glennjones.net
Install Nginx
$ apt-get install nginx
Once installed find the file ./etc/nginx/sites-available/default on the remote server and change its contents to match the code below. Swap out the server_name to match the domain names you wish to use.
server {
server_name alpha.glennjones.net;
location / {
# Proxy_pass configuration
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_max_temp_file_size 0;
proxy_pass http://0.0.0.0:3000;
proxy_redirect off;
proxy_read_timeout 240s;
}
}
server {
server_name beta.glennjones.net;
location / {
# Proxy_pass configuration
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_max_temp_file_size 0;
proxy_pass http://0.0.0.0:3001;
proxy_redirect off;
proxy_read_timeout 240s;
}
}
Test that Nginx config has no errors by running:
$ nginx -t
Then start the Nginx proxy with:
$ systemctl start nginx
$ systemctl enable nginx
Nginx should now proxy your domains so in my case both http://alpha.glennjones.net and http://beta.glennjones.net would display the Hello world page of apps 1 and 2.
We are going to install letsencrypt and enforcing SSL using Nginx rather than Node.js.
We start by installing letsencrypt:
$ apt-get install letsencrypt
We need to stop Nginx while we configure letsencrypt:
$ systemctl stop nginx
Then we create the SSL certificates. You will need to do this for each server, so twice for our example:
$ letsencrypt certonly --standalone
Once the SSL certificates are created. You should be able to find them in ./etc/letsencrypt/live/
We then need to update the file ./etc/nginx/sites-available/default to point at our new certificates
server {
listen 80;
listen [::]:80 default_server ipv6only=on;
return 301 https://$host$request_uri;
}
server {
listen 443;
server_name alpha.glennjones.net;
ssl on;
# Use certificate and key provided by Let's Encrypt:
ssl_certificate /etc/letsencrypt/live/alpha.glennjones.net/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/alpha.glennjones.net/privkey.pem;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
location / {
# Proxy_pass configuration
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_max_temp_file_size 0;
proxy_pass http://0.0.0.0:3000;
proxy_redirect off;
proxy_read_timeout 240s;
}
}
server {
listen 443;
server_name beta.glennjones.net;
ssl on;
# Use certificate and key provided by Let's Encrypt:
ssl_certificate /etc/letsencrypt/live/beta.glennjones.net/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/beta.glennjones.net/privkey.pem;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
location / {
# Proxy_pass configuration
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_max_temp_file_size 0;
proxy_pass http://0.0.0.0:3001;
proxy_redirect off;
proxy_read_timeout 240s;
}
}
Finally let's restart Nginx:
$ systemctl restart nginx
Nginx should now proxy your domains and enforce SSL so https://alpha.glennjones.net and https://beta.glennjones.net would display the Hello world page of apps 1 and 2.
Let’s Encrypt certificates are valid for 90 days, but it’s recommended that you renew the certificates every 60 days to allow a margin of error.
You can trigger a renewal by using the following command:
$ letsencrypt renew
To create an auto renewal
Edit the crontab, the following command will give editing options
$ crontab -e
Add the following two lines
30 2 * * 1 /usr/bin/letsencrypt renew >> /var/log/le-renew.log
35 2 * * 1 /bin/systemctl reload nginx
Some useful posts on this subject I used