SlideShare a Scribd company logo
Control your Voice
like a Bene Gesserit
Jorge D. Ortiz Fuentes
@jdortiz
A Canonical
Examples
Production
@jdortiz
Agenda
★ Context
★ Voice User Interfaces 101
★ Advanced Architecture Brief
★ VUI + Adv. Architecture
★ Lessons Learned
Warning
Sorry!
Put all your devices
in non listening
mode
Some
Context
Living like a 3rd
Stage Guild Navigator
@jdortiz
The Request
★ Existing App
★ Refactored to an Advanced Architecture
★ Wanted to explore VUI
★ Prototype with minimum cost
Voice User
Interfaces
101
Welcome to the
Future
@jdortiz
Maybe not as good as we
wished (YET)
★ “Sorry. I don’t know that one” “Sorry about
that. I’m still learning”
★ English, German, French, Japanese (Voice
interaction)
★ Private actions
The Contenders
Alexa Google Home SiriCortana
– Bene Genesserit
“I must not fear. Fear is the mind-killer.
Fear is the little-death that brings total
obliteration. I will face my fear.”
The Guts
Domain 1
Domain 2
Domain 3
Domain n
Routing
Natural
Language
Processing
Automatic
Speech
Recognition
Text to
Speech
Voice ➡
Voice
Text
Domain &
Intent &
Parameters
Text
Domain nDomain n
Extend the System
JSON ➡
JSON
HTTPS
Parse
Request
Do Your
Stuff
Build
Response
@jdortiz
Development
★ Node JS library (Alexa Skills & Google
Actions)
★ Also Alexa SDK for Java(/Kotlin)
★ Several unofficial ones
@jdortiz
var routes = Routes()
routes.add(method: .post, uri: “/") { request, response in
defer {
response.completed()
}
if let postString = request.postBodyString,
let data = postString.data(using:.utf8) {
let reply = AlexaServiceResponse(version: "1.0",
response: AlexaResponse(outputSpeech:
OutputSpeech(text: "Hello. I am your Genie. How can I help
you?",
type: .plaintext)))
let encoder = JSONEncoder()
let responseData = try! encoder.encode(reply)
let responseString = String(bytes: responseData, encoding: .utf8) !?? ""
response.setHeader(.contentType, value: "application/json")
response.setBody(string: responseString)
} else {
response.badRequest(message: "No request data found.")
}
}
@jdortiz
var routes = Routes()
routes.add(method: .post, uri: “/") { request, response in
defer {
response.completed()
}
if let postString = request.postBodyString,
let data = postString.data(using:.utf8) {
let reply = GAV1ServiceResponse(speech:
"Hello. I am your Genie. How can I help you?",
data:
gaServiceRequest.originalRequest.data)
let encoder = JSONEncoder()
let responseData = try! encoder.encode(reply)
let responseString = String(bytes: responseData, encoding: .utf8) !??
""
response.setHeader(.contentType, value: "application/json")
response.setBody(string: responseString)
} else {
response.badRequest(message: "No request data found.")
}
}
OK
But

Why do I need a
good architecture?
Advanced
Architecture
@jdortiz
Persistance FW
View
Network
LocationFW
Presenter
Entity Gateway
Clean Architecture
Interactor
Entity
Advanced Architecture:
Mobile
App
Delegate /
Application
View (VC)
/ Activity
Presenter Use Case
Entity
Gateway
Connector
Tap on
phone button
User wants
to talk to
contact
Start call
if

Get
contact
details
@jdortiz
Injecting Dependencies
View
Presenter
UseCaseFactory
Entity
Gateway
Connector
VUI +
Advanced
Architecture
Kwisatz Haderach
Advanced Architecture
VUI
Server
UI Presenter Use Case
Entity
Gateway
Connector
Reuse
Domain
Logic
Intent
StartCall
User wants
to talk to
contact
Start call
if

Get
contact
details
Lessons
Learned
– Dune, Frank Herbert
“Muad'Dib learned rapidly because his first
training was in how to learn. And the first
lesson of all was the basic trust that he
could learn
 Muad'Dib knew that
every experience carries its lesson.”
The not-so-relevant
Technical Stuff
@jdortiz
Implementation Details
★ Rebuild your Model (Alexa Skills)
★ Lots of corner cases in Codable
★ Documentation of the JSON requests /
responses could be better
@jdortiz
var routes = Routes()
routes.add(method: .post,
uri: “/alexa/“,
handler: alexaRequestHandler)
routes.add(method: .post,
uri: “/gaction/“,
handler: gactionRequestHandler)
let server = HTTPServer()
server.addRoutes(routes)
server.serverPort = UInt16(httpPort)
do {
try server.start()
} catch PerfectError.networkError(let err, let msg) {
LogFile.debug("Network error thrown: (err) (msg)")
}
@jdortiz
func gactionRequestHander(request: HTTPRequest, response: HTTPResponse) {
defer {
response.completed()
}
LogFile.info("!>> Google Action Service Request received !>>")
if let postString = request.postBodyString,
let data = postString.data(using:.utf8) {
do {
let decoder = JSONDecoder()
let gaRequest = try decoder.decode(GAV1ServiceRequest.self, from: data)
let reply = try gaction.process(serviceRequest: gaRequest)
let encoder = JSONEncoder()
let responseData = try! encoder.encode(reply)
let responseString = String(bytes: responseData, encoding: .utf8) !?? ""
LogFile.debug("Response: (responseString)")
response.appendBody(string: responseString)
response.setHeader(.contentType, value: "application/json")
} catch let error as GActionError {
response.append(error: error)
LogFile.error("Google Action error: (error)”)
} catch let error {
response.badRequest(message: "Request data is wrong.")
LogFile.error("Error decoding request: (error)")
}
} else {
response.badRequest(message: "No request data found.")
LogFile.error("No request data found.")
}
}
@jdortiz
let skill = AlexaSkill(id: appId,
welcomeMessage: "Welcome to Family Chores.
How can I help you?",
logger: GenericLogger())
skill.register(controller: RecordTaskAlexaUIController(),
forIntent: "RecordTask")
let connector = PersonReportAlexaConnector()
skill.register(controller: PersonReportAlexaController(),
forIntent: "PersonReport")
@jdortiz
protocol AlexaUIController {
func process(serviceRequest: ASServiceRequest) throws !-> ASServiceResponse
}
class AlexaSkill { !//

func process(serviceRequest: ASServiceRequest) throws !-> ASServiceResponse {
guard serviceRequest.safetyCheck(id: id) else {
throw SkillError.wrongSkillId
}
switch serviceRequest.request.type {
case .launch:
return serviceRequest.reply(message: welcomeMessage)
case let ASRequestType.intent(data: intentData):
if let controller = controllerMap[intentData.name] {
return try controller.process(serviceRequest: serviceRequest)
} else {
throw SkillError.undefinedIntent
}
case .sessionEnd:
return serviceRequest.end()
}
}
}
Identity & Flow
@jdortiz
Flow
★ Don’t make your users talk their way
through
★ Straight from A -> B
But wait!
There is concurrency
@jdortiz
skill.register(controller: PersonReportAlexaController(),
forIntent: "PersonReport")
@jdortiz
skill.register(connector = PersonReportAlexaConnector(),
forIntent: "PersonReport")
Fast Prototyping
@jdortiz
Quality Time
★ Avoid duplication to address both platforms
★ Ignore the DB
★ Reuse and extend use cases
Recap
@jdortiz
Key Takeaways
★ Having (/Going to) an Advanced
Architecture is key
★ Pros & Cons of own API interface
★ Easy Prototyping
★ Speak what you wish /Use what you wish
Bedankt!
Thank
You!
@jdortiz

More Related Content

PDF
Natural Language Toolkit (NLTK), Basics
KEY
NLTK in 20 minutes
PDF
Text analysis using python
PDF
Querydsl fin jug - june 2012
PDF
Nltk:a tool for_nlp - py_con-dhaka-2014
PPTX
Natural Language Processing and Python
 
PDF
Querydsl overview 2014
PDF
Basic NLP with Python and NLTK
Natural Language Toolkit (NLTK), Basics
NLTK in 20 minutes
Text analysis using python
Querydsl fin jug - june 2012
Nltk:a tool for_nlp - py_con-dhaka-2014
Natural Language Processing and Python
 
Querydsl overview 2014
Basic NLP with Python and NLTK

What's hot (20)

PPTX
Java Development with MongoDB
PPTX
Access Control
PDF
The Ring programming language version 1.7 book - Part 14 of 196
PDF
Procesamiento del lenguaje natural con python
PDF
JNI - Java & C in the same project
PDF
What do you mean, Backwards Compatibility?
PDF
Jsonsaga 100605143125-phpapp02
PDF
Introduction to Python
 
PDF
Automatically generating-json-from-java-objects-java-objects268
PDF
Cpp lab 13_pres
PDF
Json the-x-in-ajax1588
PPTX
Alexander Mostovenko "Modern approach to localization in javascript with the ...
PPT
J s-o-n-120219575328402-3
PDF
Simple fuzzy Name Matching in Elasticsearch - Graham Morehead
PDF
RESTing with the new Yandex.Disk API, Clemens Аuer
 
PDF
Building a Gigaword Corpus (PyCon 2017)
ODP
GPars (Groovy Parallel Systems)
PDF
Groovy.pptx
PDF
Spring Data JPA from 0-100 in 60 minutes
PPSX
Logging your node.js application
Java Development with MongoDB
Access Control
The Ring programming language version 1.7 book - Part 14 of 196
Procesamiento del lenguaje natural con python
JNI - Java & C in the same project
What do you mean, Backwards Compatibility?
Jsonsaga 100605143125-phpapp02
Introduction to Python
 
Automatically generating-json-from-java-objects-java-objects268
Cpp lab 13_pres
Json the-x-in-ajax1588
Alexander Mostovenko "Modern approach to localization in javascript with the ...
J s-o-n-120219575328402-3
Simple fuzzy Name Matching in Elasticsearch - Graham Morehead
RESTing with the new Yandex.Disk API, Clemens Аuer
 
Building a Gigaword Corpus (PyCon 2017)
GPars (Groovy Parallel Systems)
Groovy.pptx
Spring Data JPA from 0-100 in 60 minutes
Logging your node.js application
Ad

Similar to Control your Voice like a Bene Gesserit (20)

PDF
How to develop Alexa Skill Kit based on Serverless Architecture
PDF
Google Assistant Revolution
PDF
The Voice Interface Revolution
PDF
Building Conversational Experiences with Actions on Google
PDF
Actions On Google - How? Why?
PDF
PDF
Learn about iOS10 Siri Kit
PDF
Esplorando Google Assistant e Dialogflow
PDF
Building Conversational Experiences for Google Assistant
PDF
Create An Amazing Apps For The Google Assistant!
PDF
Design and Develop Alexa Skills - Codemotion Rome 2019
PPTX
NUS-ISS Learning Day 2017 - Voice Computing - The Next Digital Disruption!
PPTX
Voice enable all the things with Alexa
PDF
Building conversational experiences with Actions on Google
PPTX
Building custom skills with Amazon Alexa
PDF
Building Conversational Experiences for Google Assistant '18
PDF
Google assistant basics
PDF
Google vs Alexa: Battle of the Bots
PDF
Creating Voice User interfaces from scratch
PDF
HAMBURG Voice MEETUP #4 LEARN voice user interface design!
How to develop Alexa Skill Kit based on Serverless Architecture
Google Assistant Revolution
The Voice Interface Revolution
Building Conversational Experiences with Actions on Google
Actions On Google - How? Why?
Learn about iOS10 Siri Kit
Esplorando Google Assistant e Dialogflow
Building Conversational Experiences for Google Assistant
Create An Amazing Apps For The Google Assistant!
Design and Develop Alexa Skills - Codemotion Rome 2019
NUS-ISS Learning Day 2017 - Voice Computing - The Next Digital Disruption!
Voice enable all the things with Alexa
Building conversational experiences with Actions on Google
Building custom skills with Amazon Alexa
Building Conversational Experiences for Google Assistant '18
Google assistant basics
Google vs Alexa: Battle of the Bots
Creating Voice User interfaces from scratch
HAMBURG Voice MEETUP #4 LEARN voice user interface design!
Ad

More from Jorge Ortiz (20)

PDF
Tell Me Quando - Implementing Feature Flags
PDF
Unit Test your Views
PDF
Kata gilded rose en Golang
PDF
CYA: Cover Your App
PDF
Refactor your way forward
PDF
201710 Fly Me to the View - iOS Conf SG
PDF
Home Improvement: Architecture & Kotlin
PDF
Architectural superpowers
PDF
Architecting Alive Apps
PDF
iOS advanced architecture workshop 3h edition
PDF
Android clean architecture workshop 3h edition
PDF
To Protect & To Serve
PDF
Clean architecture workshop
PDF
Escape from Mars
PDF
Why the Dark Side should use Swift and a SOLID Architecture
PDF
Dependence day insurgence
PDF
Architectural superpowers
PDF
TDD for the masses
PDF
7 Stages of Unit Testing in iOS
PDF
Building for perfection
Tell Me Quando - Implementing Feature Flags
Unit Test your Views
Kata gilded rose en Golang
CYA: Cover Your App
Refactor your way forward
201710 Fly Me to the View - iOS Conf SG
Home Improvement: Architecture & Kotlin
Architectural superpowers
Architecting Alive Apps
iOS advanced architecture workshop 3h edition
Android clean architecture workshop 3h edition
To Protect & To Serve
Clean architecture workshop
Escape from Mars
Why the Dark Side should use Swift and a SOLID Architecture
Dependence day insurgence
Architectural superpowers
TDD for the masses
7 Stages of Unit Testing in iOS
Building for perfection

Recently uploaded (20)

PPTX
Odoo POS Development Services by CandidRoot Solutions
PDF
Design an Analysis of Algorithms I-SECS-1021-03
PDF
How to Migrate SBCGlobal Email to Yahoo Easily
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 41
PDF
Which alternative to Crystal Reports is best for small or large businesses.pdf
PPTX
Essential Infomation Tech presentation.pptx
PDF
Addressing The Cult of Project Management Tools-Why Disconnected Work is Hold...
PPTX
CHAPTER 2 - PM Management and IT Context
PDF
Adobe Illustrator 28.6 Crack My Vision of Vector Design
PDF
SAP S4 Hana Brochure 3 (PTS SYSTEMS AND SOLUTIONS)
PDF
System and Network Administraation Chapter 3
PDF
Navsoft: AI-Powered Business Solutions & Custom Software Development
PDF
How to Choose the Right IT Partner for Your Business in Malaysia
PDF
Flood Susceptibility Mapping Using Image-Based 2D-CNN Deep Learnin. Overview ...
PPTX
Agentic AI Use Case- Contract Lifecycle Management (CLM).pptx
PPTX
Reimagine Home Health with the Power of Agentic AI​
PDF
Digital Strategies for Manufacturing Companies
PDF
EN-Survey-Report-SAP-LeanIX-EA-Insights-2025.pdf
PPTX
ai tools demonstartion for schools and inter college
PDF
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
Odoo POS Development Services by CandidRoot Solutions
Design an Analysis of Algorithms I-SECS-1021-03
How to Migrate SBCGlobal Email to Yahoo Easily
Internet Downloader Manager (IDM) Crack 6.42 Build 41
Which alternative to Crystal Reports is best for small or large businesses.pdf
Essential Infomation Tech presentation.pptx
Addressing The Cult of Project Management Tools-Why Disconnected Work is Hold...
CHAPTER 2 - PM Management and IT Context
Adobe Illustrator 28.6 Crack My Vision of Vector Design
SAP S4 Hana Brochure 3 (PTS SYSTEMS AND SOLUTIONS)
System and Network Administraation Chapter 3
Navsoft: AI-Powered Business Solutions & Custom Software Development
How to Choose the Right IT Partner for Your Business in Malaysia
Flood Susceptibility Mapping Using Image-Based 2D-CNN Deep Learnin. Overview ...
Agentic AI Use Case- Contract Lifecycle Management (CLM).pptx
Reimagine Home Health with the Power of Agentic AI​
Digital Strategies for Manufacturing Companies
EN-Survey-Report-SAP-LeanIX-EA-Insights-2025.pdf
ai tools demonstartion for schools and inter college
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool

Control your Voice like a Bene Gesserit

  • 1. Control your Voice like a Bene Gesserit Jorge D. Ortiz Fuentes @jdortiz
  • 3. @jdortiz Agenda ★ Context ★ Voice User Interfaces 101 ★ Advanced Architecture Brief ★ VUI + Adv. Architecture ★ Lessons Learned
  • 6. Put all your devices in non listening mode
  • 8. Living like a 3rd Stage Guild Navigator
  • 9. @jdortiz The Request ★ Existing App ★ Refactored to an Advanced Architecture ★ Wanted to explore VUI ★ Prototype with minimum cost
  • 12. @jdortiz Maybe not as good as we wished (YET) ★ “Sorry. I don’t know that one” “Sorry about that. I’m still learning” ★ English, German, French, Japanese (Voice interaction) ★ Private actions
  • 13. The Contenders Alexa Google Home SiriCortana
  • 14. – Bene Genesserit “I must not fear. Fear is the mind-killer. Fear is the little-death that brings total obliteration. I will face my fear.”
  • 15. The Guts Domain 1 Domain 2 Domain 3 Domain n Routing Natural Language Processing Automatic Speech Recognition Text to Speech Voice ➡ Voice Text Domain & Intent & Parameters Text
  • 16. Domain nDomain n Extend the System JSON ➡ JSON HTTPS Parse Request Do Your Stuff Build Response
  • 17. @jdortiz Development ★ Node JS library (Alexa Skills & Google Actions) ★ Also Alexa SDK for Java(/Kotlin) ★ Several unofficial ones
  • 18. @jdortiz var routes = Routes() routes.add(method: .post, uri: “/") { request, response in defer { response.completed() } if let postString = request.postBodyString, let data = postString.data(using:.utf8) { let reply = AlexaServiceResponse(version: "1.0", response: AlexaResponse(outputSpeech: OutputSpeech(text: "Hello. I am your Genie. How can I help you?", type: .plaintext))) let encoder = JSONEncoder() let responseData = try! encoder.encode(reply) let responseString = String(bytes: responseData, encoding: .utf8) !?? "" response.setHeader(.contentType, value: "application/json") response.setBody(string: responseString) } else { response.badRequest(message: "No request data found.") } }
  • 19. @jdortiz var routes = Routes() routes.add(method: .post, uri: “/") { request, response in defer { response.completed() } if let postString = request.postBodyString, let data = postString.data(using:.utf8) { let reply = GAV1ServiceResponse(speech: "Hello. I am your Genie. How can I help you?", data: gaServiceRequest.originalRequest.data) let encoder = JSONEncoder() let responseData = try! encoder.encode(reply) let responseString = String(bytes: responseData, encoding: .utf8) !?? "" response.setHeader(.contentType, value: "application/json") response.setBody(string: responseString) } else { response.badRequest(message: "No request data found.") } }
  • 20. OK But
 Why do I need a good architecture?
  • 23. Advanced Architecture: Mobile App Delegate / Application View (VC) / Activity Presenter Use Case Entity Gateway Connector Tap on phone button User wants to talk to contact Start call if
 Get contact details
  • 27. Advanced Architecture VUI Server UI Presenter Use Case Entity Gateway Connector Reuse Domain Logic Intent StartCall User wants to talk to contact Start call if
 Get contact details
  • 29. – Dune, Frank Herbert “Muad'Dib learned rapidly because his first training was in how to learn. And the first lesson of all was the basic trust that he could learn
 Muad'Dib knew that every experience carries its lesson.”
  • 31. @jdortiz Implementation Details ★ Rebuild your Model (Alexa Skills) ★ Lots of corner cases in Codable ★ Documentation of the JSON requests / responses could be better
  • 32. @jdortiz var routes = Routes() routes.add(method: .post, uri: “/alexa/“, handler: alexaRequestHandler) routes.add(method: .post, uri: “/gaction/“, handler: gactionRequestHandler) let server = HTTPServer() server.addRoutes(routes) server.serverPort = UInt16(httpPort) do { try server.start() } catch PerfectError.networkError(let err, let msg) { LogFile.debug("Network error thrown: (err) (msg)") }
  • 33. @jdortiz func gactionRequestHander(request: HTTPRequest, response: HTTPResponse) { defer { response.completed() } LogFile.info("!>> Google Action Service Request received !>>") if let postString = request.postBodyString, let data = postString.data(using:.utf8) { do { let decoder = JSONDecoder() let gaRequest = try decoder.decode(GAV1ServiceRequest.self, from: data) let reply = try gaction.process(serviceRequest: gaRequest) let encoder = JSONEncoder() let responseData = try! encoder.encode(reply) let responseString = String(bytes: responseData, encoding: .utf8) !?? "" LogFile.debug("Response: (responseString)") response.appendBody(string: responseString) response.setHeader(.contentType, value: "application/json") } catch let error as GActionError { response.append(error: error) LogFile.error("Google Action error: (error)”) } catch let error { response.badRequest(message: "Request data is wrong.") LogFile.error("Error decoding request: (error)") } } else { response.badRequest(message: "No request data found.") LogFile.error("No request data found.") } }
  • 34. @jdortiz let skill = AlexaSkill(id: appId, welcomeMessage: "Welcome to Family Chores. How can I help you?", logger: GenericLogger()) skill.register(controller: RecordTaskAlexaUIController(), forIntent: "RecordTask") let connector = PersonReportAlexaConnector() skill.register(controller: PersonReportAlexaController(), forIntent: "PersonReport")
  • 35. @jdortiz protocol AlexaUIController { func process(serviceRequest: ASServiceRequest) throws !-> ASServiceResponse } class AlexaSkill { !//
 func process(serviceRequest: ASServiceRequest) throws !-> ASServiceResponse { guard serviceRequest.safetyCheck(id: id) else { throw SkillError.wrongSkillId } switch serviceRequest.request.type { case .launch: return serviceRequest.reply(message: welcomeMessage) case let ASRequestType.intent(data: intentData): if let controller = controllerMap[intentData.name] { return try controller.process(serviceRequest: serviceRequest) } else { throw SkillError.undefinedIntent } case .sessionEnd: return serviceRequest.end() } } }
  • 37. @jdortiz Flow ★ Don’t make your users talk their way through ★ Straight from A -> B
  • 38. But wait! There is concurrency
  • 42. @jdortiz Quality Time ★ Avoid duplication to address both platforms ★ Ignore the DB ★ Reuse and extend use cases
  • 43. Recap
  • 44. @jdortiz Key Takeaways ★ Having (/Going to) an Advanced Architecture is key ★ Pros & Cons of own API interface ★ Easy Prototyping ★ Speak what you wish /Use what you wish