Haley AI Dialog Demo Video

Here is a quick 3 minute video of some features of Haley AI, focusing on our visual dialog designer tool.

The video highlights:

  • Quickly creating a chatbot dialog using a visual design tool
  • Deploying the dialog in a web application or on Facebook
  • Using a dialog in a conversational e-commerce application
  • Using a form instead of a chat interface
  • Adding Haley AI to teams for collaboration

 

Hope you enjoyed the demonstration.

Please contact us today to learn about using Haley AI in your organization!

info@vital.ai

http://haley.ai/#contact

 

NY Tech Day ’17

Thank you everyone who popped by our booth at Tech Day 2017! We’re proud to have received an overwhelming interest in our new AI platform, Haley AI!

power_vital_ai

 

We are excited to keep in touch with all whom we met yesterday! Feel free to hit us up at info@vital.ai should you have any question about Vital AI!

 

IMG_5308

Marc introduced Haley AI to one of the many interested attendees.

And a 360-degree view from our booth!

 

It was a busy day but we sure had a blast!

For those who did not get a chance to speak to us yesterday, connect with us at info@vital.ai and we’d love to speak to you more about Vital!

Once again, thank you to all organizers for this amazing event! And kudos to 575 other innovative startups for the great job!

See you guys again at Tech Day in 2018!

Vital.AI @ NY TechDay on Tuesday, April 18th!

c1b4f38d2d

We’re excited for TechDay coming up next Tuesday! (April 18th)

Join 35,000 other tech lovers and check out the booths of 574 startups + 1 very special startup (us!).

When you stop by our booth, we can show you a sneak preview of our A.I. platform Haley.ai, including a visual designer tool to quickly build A.I. Agents for your business.

Here are the TechDay details:

Cost: Free!
When: April 18th, 10am to 5pm
Where: Pier94 @ 711 12th Avenue New York, NY
More details: https://techdayhq.com/new-york

See you there!

 

Season’s Greetings from the team at Vital A.I.

christmas1-copy

It’s been an exciting time in the data and artificial intelligence world!

Global interest in A.I. has never been higher, and new algorithms, APIs, and applications are appearing on a near daily basis. We’ve had a busy year building artificial intelligence applications for our customers, as well as implementing our A.I. agent platform Haley A.I. to be released this upcoming year.

We have had the pleasure of collaborating with many of you throughout the year, and we are so excited for all we can do together next year. Here are a few milestones from the past year, and some things to look forward to next year!

To All, Happy Holidays and have a Happy, Healthy and Prosperous New Year!

— Marc Hadfield, Founder of Vital AI

haley-02 Pre-release of Haley A.I.

During the year, we created the pre-release version of our Haley A.I. intelligent agent platform including chatbot functionality, recommendations & predictions via machine learning, dialog management, and integrations with numerous APIs and devices such as the Amazon Echo and the Jibo robot. Haley A.I. is now available to customers and partners to create intelligent agent applications.

 

insur3

  Upcoming Launch of Insurance-aaS managed by Haley A.I. in early 2017

In collaboration with our Insurance Broker firm, we are proud to announce the launch of an Insurance-as-a-Service A.I. platform in early 2017! Our intelligent agent Haley A.I. will manage all interactions among insurance companies, customers, and brokers, with a focus on commercial insurance.

haley_copy_720

        Upcoming Launch of Haley SaaS

In the new year, we are looking forward to the launch of our Haley A.I. intelligent agent platform. Using the Haley A.I. service, you can hire Haley to automate business processes with applications across industries like Financial Services, Healthcare, and IT Management.

img_0803

Welcome our new intern, Xin Yee

In August, Xin Yee joined us from the National University of Singapore (NUS).  As the marketing intern at Vital.AI, she is driven by her passion in marketing to promote the power of artificial intelligence to the world. She is excited to run marketing campaigns to promote Haley SDK and Haley SaaS in the new year!

IMG_3860

Tech Day 2017

In the upcoming year, Vital A.I. will again be participating in one of the largest tech event in NYC – NY Tech Day. With over 30,000 attendees and over 500 startups presenting, it will be an exciting day. Mark your calendar for April 18th! Stop by our booth to check out our software and meet Haley!

Best wishes from the team at Vital AI

christmas4

VDK Release 0.2.304, VitalService ASync with Kafka

We released VDK 0.2.304 a couple weeks back, and it contains many new features.

One of the most significant is the asynchronous version of the VitalService API, which uses an underlying realtime distributed messaging system in its implementation.

Quick aside for some definitions: In synchronous systems, one component sends a request and waits for an answer.  This usually involves “blocking” — holding on to system resources while waiting.   In asynchronous systems, one component sends a request and moves on to other things, and processes the answer when it arrives.  This is usually “non-blocking” with no or limited resources being held while a response is pending.  Applications usually combine both methods — there are advantages and disadvantages of each.  Generally, asynchronous requests require more overhead but can scale up to large numbers, and synchronous requests can get individual answers much quicker.  Most modern websites include asynchronous communication with the server, whereas microservices ( https://en.wikipedia.org/wiki/Microservices ) are synchronous.

kafka-integration
Architecture of an application using VitalService API Client with an underlying asynchronous implementation using a Kafka cluster and set of Workers to process messages.

While we have often combined VitalService with a realtime messaging systems in Big Data applications for fully “reactive” applications ( http://www.reactivemanifesto.org/ ), this deeper integration enables a much simpler realtime application implementation and a seamless flow across synchronous and asynchronous software components.

So, the advantage in the 0.2.304 release is a simplification and streamlining of development processes via a unification of APIs — resulting in fewer lines of code, quicker development, fewer bugs, lower cost, and less technical debt.

Using the updated API, a developer works with a single API and chooses which calls to be synchronous or asynchronous based on the parameters of the API call.

For our messaging implementation we use Kafka ( http://kafka.apache.org/ ) , however we could also use alternatives, such as Amazon Kinesis ( https://aws.amazon.com/kinesis/ ).

In the above diagram, we have an application using the VitalService API client.  The application may be processing messages from a user, requesting realtime predictions from a predictive model, querying a database, or any other VitalService API function.

This VitalService API client is using Vital Prime as the underlying implementation.  See: https://console.vital.ai/productdetails/vital-prime-021 and http://www.vital.ai/tech.html for more information about Vital Prime.

Vital Prime acts as both a REST server as well as a message producer/consumer (publisher/subscriber).

When VitalService API client authenticates with Prime, it internally learns the details of the distributed messaging cluster (Kafka cluster), including the connection details and the current set of “topics”(essentially, queues) with their statuses .  Prime coordinates with the Kafka Cluster using Zookeeper ( https://zookeeper.apache.org/ ) to track the available brokers and the status of topics. The VitalService API Client can then seamlessly direct incoming API calls into messages, and direct incoming messages to callback functions.

Thus, an API call like a Query has a synchronous version and an asynchronous version which is the same except for the callback function parameter (the callback function can be empty for “fire-and-forget” API calls).  If the synchronous version is used, a blocking REST call is made to Prime to fulfill the request.  If the asynchronous version is used, the call is directed into the messaging system.

In our example application, we have three pictured “workers” which are processing messages consumed from Kafka, coordinating with Prime as needed.  By this method, work can be distributed across the cluster according to whatever scale is needed.  Such workers can be implemented with instances of Prime, a Spark Cluster ( http://spark.apache.org/ with http://aspen.vital.ai/ ), or any scalable compute service such as Amazon’s Lambda ( https://aws.amazon.com/lambda/ ).

This deeper integration with realtime messaging systems, especially Kafka, has been spurred on by the upcoming release of our Haley AI Assistant service, which can be used to implement AI Assistants for different domains, as well as related “chatbot” services.

More information on Haley AI to come!

 

 

Welcome Xin Yee, our new intern from Singapore!

The Vital AI team is excited to welcome Xin Yee Wong as a new Sales and Marketing intern!

Processed with VSCO with b1 preset
Xin Yee Wong

Xin Yee is a marketing major at the National University of Singapore and is participating in the NUS Enterprise program, helping to train Singapore’s next generation of entrepreneurs.  An important part of NUS Enterprise is the NUS Overseas Colleges Programme, which arranges for internships at innovative start-up companies around the world.  We at Vital AI are proud to participate and have Xin Yee join us for the next year!

Xin Yee will be focused on interesting and effective marketing ideas for Vital AI to increase customer outreach so that more people can benefit from Vital AI’s software and services.  Of particular focus will be Vital AI’s upcoming launch of the Haley AI assistant service.

In addition to her sales and marketing activities, Xin Yee, as a budding entrepreneur, will be assisting with Vital AI’s strategic business goals including fundraising, product development, and partnerships.  She will also be taking over Vital AI’s social media outreach efforts.  So do keep a lookout on Vital AI’s social media channels for Xin Yee, and say hello!

Once more, we welcome Xin Yee to the United States, to New York City, and to Vital AI!

 

NY Tech Day 2016

We had a great time at NY Tech Day and we hope you did too!

IMG_3879

Here is Marc discussing some new Artificial Intelligence Apps with some guests at our booth.

And some other photos from the day:

IMG_3893.png

IMG_3883.png

IMG_3870.png

Thanks to everyone for dropping by our booth to learn more about building artificial intelligence applications using the Vital AI Development Kit!

We look forward to keeping in touch with all the awesome people we met yesterday.

Also, many thanks to the organizers for such a wonderful event!  Great job again, and looking forward to next time!

Updating the “If” statement in the JVM for Truth Value Logic

The Vital Development Kit (VDK) provides development tools and an API for Artificial Intelligence (AI) applications and data processing.  This includes a “Domain Specific Language” (DSL) for working with data.

To this DSL we’ve recently added an extension to the venerable “If” statement in the JVM to handle Truth Values. (Truth Values, see: Beyond True and False: Introducing Truth to the JVM )

The “If” statement is the workhorse of computer programming.  If this, do that.  If something is so, then do some action.  The “If” statement evaluates if some condition is “True”, and if so, takes some action.  If the condition is “False”, then it may take some other action.

The condition of an “If” statement yields a Boolean True or False and typically involves tests of variables, such as:  height > 72, speed < 50, name == “John”.

The “If” statement is a special case of the “switch” statement, such that:

if(name == "John") { do something }
else { do something different }

is the same as:

switch (name == "John") {
case true: { do something; break }
case false: { do something different; break }
}

In the VDK we have an extension of Boolean in the JVM called Truth.  Truth may take four values: YES, NO, UNKNOWN, or MU compared to the Boolean TRUE or FALSE.  YES and NO are the familiar TRUE and FALSE, with UNKNOWN providing a value for when a condition cannot be determined because of unknown inputs, and MU providing a value for when a condition is unknowable because it contains a false premise.

For example, for UNKNOWN, the color of a traffic light might be red, green, or yellow but its value is currently UNKNOWN.  And for MU, the favorite color of a traffic light is MU because inanimate objects don’t have favorite colors.

UNKNOWN and MU are part of the familiar Boolean Truth Tables.  For instance True AND True yields True, whereas True AND Unknown yields Unknown.

Details of the Truth implementation in the JVM can be found in the blog post: Beyond True and False: Introducing Truth to the JVM

Because Truth has four values, we need a way to handle four cases when we test a condition.

As above, we could use a “switch” statement like so:

switch (Truth Condition) {
case YES: { handle YES; break }
case NO: { handle NO; break }
case UNKNOWN: { handle UNKNOWN; break }
case MU: { handle MU; break }
} 

This is a little verbose, so we’ve introduced a friendlier statement: consider.

consider (Truth Condition) {
YES: { handle YES }
NO: { handle NO }
UNKNOWN: { handle UNKNOWN }
MU: { handle MU }
} 

So we can have code like:

consider (trafficlight.color == GREEN) {
YES: { car.drive() }
NO: { car.stop() }
UNKNOWN: { car.stop() } // better be safe and look around
MU: { car.stop(); runDiagnostics(); } // error! error!
} 

In the above code, if evaluating our truth condition results in an UNKNOWN value (perhaps a sensor cannot “see” the Traffic Light), we can take some safe action.  If we get a MU value, then we have some significant error, such the “trafficlight” object not actually being a trafficlight — perhaps some variable mixup.  We can also take some defensive measures in this case.

We can also stick with using “If” and use exceptions for the cases of UNKNOWN and MU:

try {
if(trafficlight.color == GREEN) { car.drive() }
else { car.stop() }
} catch(Exception ex) {
// handle UNKNOWN and MU
}

This works because Truth values are coerced to Boolean True or False for the cases of YES or NO.  This coercion throws an exception for the cases of UNKNOWN or MU.  JVM exceptions are a bit ugly and should not be used for normal program control flow (exceptions as flow control is often an anti-pattern), so the consider statement is much preferred.

The logic of Truth is very helpful in defining Rules to process realtime dynamic data, and answer dynamic data queries.  The consider statement allows such rules to be quite succinct and explicitly handle unknown data or queries with non-applicable conditions.

For instance, if we query an API for the status of traffic lights and ask how many are currently yellow, we might get back a reply of 0 (zero).  We might wonder are there really zero traffic lights yellow presently, or is the API not functioning and always returning zero, or does it not track yellow lights?  It would be better to get a reply of UNKNOWN if the API was not functioning.  If we asked how many traffic lights were displaying Purple, a reply of zero would be correct but it would be better to get a reply of MU –  there are no such thing as Purple traffic lights in a world of Red/Yellow/Green lights.

As AI and data-driven applications incorporate more dynamic data models and data sources, instances of missing or incorrect knowledge are more the rule rather than the exception, so the software flow should treat these as normal cases to consider rather than exceptions.

Hope you have enjoyed learning about how the Vital Development Kit has extended “If” to handle Truth Values.  Please post and questions or comments below, or get in touch with us at info@vital.ai.

Beyond True and False: Introducing Truth to the JVM

In this post we introduce a new type for “Truth” to the JVM in the Vital Development Kit (VDK), to include cases that don’t fit into Boolean True and False — in particular a value for Unknown and Mu (nonexistence).  We use this new Truth type in the VDK for logical and conditional expressions, especially in rules and inference.

Computer hardware has binary — ones and zeros.
Computer software has boolean — true and false.
This seems a perfect match, immutable, a Platonic Ideal.
But there are some wrinkles.

Programming languages deeply use booleans to control the flow of a program:

if this is true, then do that
if this is false, then do something else

What if the software doesn’t know a particular value at that moment?

What if the value doesn’t make sense in the current context?

For instance, in the code:

if(TrafficLight.color == RED) then { Stop() }
else { Go() }

What if the TrafficLight color is unknown?  The software would drive through the traffic intersection.  (Hope for the best!)

Or, what if we had code like:

if(Penguin.flightspeed < 10) then { ThrowAFish() }

Should this code work, even if penguins don’t have a flight speed?

In programming languages like Java, these problems lead to a lot of custom workarounds and error checking, so much so that you can no longer use “normal” boolean expressions without a bunch of checks to ensure that it is “safe”.

In rule-based systems or logic languages, often “unknown” is treated as False — this is because a rule like isTall(John) tries to prove that John is tall, and if it can’t it returns “false” or “no”, meaning “I can not prove that”.

But, if the code re-uses that result like:

isShort(X) := NOT isTall(X)

then it is incorrectly combining the Is-Tall case with the I-Don’t-Know case, causing software errors — that is, if the height is unknown, then the person is short, which is quite a leap of logic to be sure.

Three Value Logic

This is not a new problem.  SQL tries to solve this with a third logic value called NULL to mean “UNKNOWN”.  A description of this is here: https://en.wikipedia.org/wiki/Null_(SQL)

Three value logic (3VL) for True/False/Unknown is well established, with a full description here: https://en.wikipedia.org/wiki/Three-valued_logic

Unfortunately 3VL is not built into languages like Java.  And, it gets worse.

Java has low level base types that are efficient like int for integers and object-oriented classes like Integer which have some additional Object overhead but are more “friendly”, and there are ways to convert between Objects and base types.  So far, so good.

All objects (instances of classes) may be set to the value of “null”.  There is a class for Boolean which may be set to True, False, or Null.  And, there is the low-level type “boolean” which may only have the values of true and false.  So a Boolean object has a value (“null”) which can not be set in the base type boolean.  It is like having a base type for integer that you can’t set to zero.

(Mis)Using Null as a Value

In Java, “null” means uninitialized and is not a true distinct “value”.   Some code uses (abuses) “null” to mean “unknown”, but this means we then can’t tell apart an uninitialized value from a initialized “unknown” value — similar to confusing “I-can’t-prove-it” with “false”.  Moreover, we can’t store “null” in the low level boolean type anyway, which again can only be true or false.

1aab4d13e65d4c245d46c0ab4679ffa7
“If that is okay, please give me absolutely no sign.”

The value of “null” also occurs in lots of error situations — the network connection failed, the database connection timed out, the password is incorrect, no memory is available, and on and on.

Using “null” as a value reminds me of this Simpon’s line with Homer interpreting the absence of a message (“null”) as a message.

So, the addition of “null” to Java’s Boolean doesn’t provide a way to represent “unknown” unambiguously, and it causes even more confusion with uninitialized objects and various error conditions.

A Value for Nonexistence

Besides the “unknown” case there is also the case above of: Penguin.flightspeed < 10.

Since we know that a penguin can’t have a flightspeed, this isn’t a case of “unknown.”  We could argue that this statement of less than 10 is “true” since “0” is the absence of a speed and 0 is less than 10, but that requires embedding domain knowledge about how speeds work, i.e. Is the temperature of a song absolute zero? (-459.67F)  Is the color of an integer black?  There isn’t a universal way to assign these True or False when the question doesn’t make sense.

500px-無-still.svg
Mu

And so, we need a fourth value to handle the case of “nonexistence” or “non-applicable”.

We’ve chosen to use the symbol Mu for this as it has been popularly been used in this sense.  One notable example of its use is in Douglas R. Hofstadter’s wonderful book:

Gödel, Escher, Bach: An Eternal Golden Braid.  (http://www.amazon.com/G%C3%B6del-Escher-Bach-Eternal-Golden/dp/0465026567)

Some more details regarding Mu are in its wikipedia article here: https://en.wikipedia.org/wiki/Mu_(negative)

 

Truth implementation in the VDK

In the VDK, we use the Groovy language for scripting on the JVM.  Truth was added as a new type to Groovy with the values: YES, NO, UNKNOWN, and MU.  We use YES and NO instead of True and False to avoid confusion with the existing Boolean values and reserved words.

We follow the truth tables as specified here for 3VL: https://en.wikipedia.org/wiki/Three-valued_logic#Kleene_and_Priest_logics

Some example logic statements using AND, OR, and NOT with Truth:

  • YES AND UNKNOWN := UNKNOWN
  • YES OR UNKNOWN := YES
  • NO OR UNKNOWN := UNKNOWN
  • NOT UNKNOWN := UNKNOWN

For Mu, any logic expression with Mu yields MU:

  • NOT MU := MU
  • YES OR MU := MU

Using our new Truth definition, we can now write or generate code that handles the cases of Unknown or Mu without any ambiguity.

For example:


Truth isTall(Person p) {
if( p.height == UNKNOWN ) { return UNKNOWN }
if  ( p.height > 72.0)  { return YES }
else { return NO }
}

Truth isShort(Person p) {
if( p.height == UNKNOWN ) { return UNKNOWN }
if  ( p.height < 60.0)  { return YES }
else { return NO }
}

Truth averageHeight(Person p) {
return ! ( isTall(p) || isShort(p) )
}

In the above code, the “averageHeight()” function returns a Truth value, and is completely defined by boolean NOT and the isShort() and isTall() functions, and it returns UNKNOWN if either of these functions is UNKNOWN.  The NOT (!) works properly now instead of the previous definition which mistakenly combined the “I can’t prove it” case with the “false” case.

Instead of a “if..then” statement in code, we can use a “switch” statement to handle YES, NO, UNKNOWN, and MU, like so:

switch(averageHeight(p) || isShort(p) ) {
case YES:
println "YES" ; break;
case NO:
println "NO" ; break;
case UNKNOWN:
println "UNKNOWN" ; break;
case MU:
println "MU" ; break;
}

We’d like to add a little DSL syntactic sugar to the switch statement, so the above could be written a bit more succinctly, something along the lines of:

/* idea for improvement to Truth DSL */
if (averageHeight(p) || isShort(p) ) {

YES: { println "YES" }
NO:  {println "NO" }
UNKNOWN: { println "UNKNOWN" }
MU: { println "MU" }
}

which would try to follow the pattern of if()…then()…else() but be: if…yes()..no()…unknown()…mu() with any of the blocks optional.

Please comment if you like this proposed addition to the DSL, or have any suggestions!

Feedback

I hope you have enjoyed learning about how Truth is implemented in the VDK to provide a richer logic representation than the Boolean True/False.

Please post any comments or questions in the comment section, or contact Vital AI directly at info@vital.ai