Noah Petherbridge
and 1 contributors


Chatbot::Alpha - A simple chatterbot brain.


  use Chatbot::Alpha;
  # Create a new Alpha instance.
  my $alpha = new Chatbot::Alpha();
  # Load replies from a directory.
  $alpha->loadFolder ("./replies");
  # Load an additional response file.
  $alpha->loadFile ("./more_replies.txt");
  # Input even more replies directly from Perl.
  $alpha->stream ("+ what is alpha\n"
                . "- Alpha, aka Chatbot::Alpha, is a chatterbot brain created by AiChaos Inc.\n\n"
                . "+ who created alpha\n"
                . "- Chatbot::Alpha was created by Cerone Kirsle.");
  # Get a response.
  my $reply = $alpha->reply ("user", "hello alpha");


The Alpha brain was developed by AiChaos, Inc. for our chatterbots. The Alpha brain's language is line-by-line, command-driven. Alpha is a simplistic brain yet is very powerful for making impressive response systems.

Note: This module is obsolete! Alpha was superceded by a more powerful language, rewritten from scratch, called RiveScript. Chatbot::Alpha was allowed (and will be allowed) to remain here only because there are a few incompatibilities in the reply files. If you haven't used Alpha yet, I urge you to use RiveScript instead. If you've already invested time in writing reply files for Alpha, know that this module isn't going anywhere. However, this module is no longer actively maintained (and hasn't been in a number of years).

See RiveScript.



Creates a new Chatbot::Alpha object. Pass in any default arguments (in hash form). Default arguments are debug (debug mode; defaults to 0) and verify (to run syntax checking, defaults to 1).

Returns a Chatbot::Alpha instance.


Returns the version number of the module.

loadFolder (DIRECTORY[, TYPES])

Loads a directory of response files. The directory name is required. TYPES is the file extension of your response files. If TYPES is omitted, every file is considered a response file.

Just as a side note, the extension agreed upon for Alpha files is .CBA, but the extension is not important.

loadFile (FILE_PATH[, STREAM])

Loads a single file. The "loadFolder" method calls this for each valid file. If STREAM is 1, the current contents of the stream cache will be loaded (assuming FILE_PATH is omitted). You shouldn't need to worry about using STREAM, see the "stream" method below.

stream (ALPHA_CODE)

Inputs a set of Alpha code directly into the module ("streaming") rather than loading it from an external document. See synopsis for an example.


Sorts the replies already loaded: solid triggers go first, followed by triggers containing wildcards. If you fail to call this method yourself, it will be called automatically when "reply" is called.

Update with v 1.7 - Reply sorting method reprogrammed: items are sorted with solid triggers first, then those with wildcards and 16 whole words, then 15 whole words, 14, etc. and then unknown triggers, followed lastly by those that contain NO full words.

setVariable (VARIABLE, VALUE)

Sets an internal variable. These are used primarily in conditionals in your Alpha responses.

removeVariable (VARIABLE)

Removes an internal variable.


Clears all internal variables (only those set with set_variable).

reply (ID, MESSAGE)

Scans the loaded replies to find a response to MESSAGE. ID is a unique ID for the particular person requesting a response. The ID is used for things such as topics and conversation holders. Returns a reply, or one of default_reply if a better response wasn't found.

search (MESSAGE)

Scans the loaded replies to find any triggers that match MESSAGE. Will return an array containing every trigger that matched the message, including their filenames and line numbers.

stringUtil (TYPE, STRING)

Called on internally for the string modification tags. TYPE would be uppercase, lowercase, formal, or sentence. String would be the string to modify. Returns the modified string.


The Alpha response language is a line-by-line command-driven language. The first character on each line is the command (prepent white spaces are ignored). Everything following the command are the command's arguments. The commands are as follows:

+ (Plus)

The + symbol indicates a trigger. Every Alpha reply begins with this command. The arguments are what the trigger is (i.e. "hello chatbot"). If the message matches this trigger, then the rest of the response code is considered. Else, the triggers are skipped over until a good match is found for the message.

~ (Tilde)

The ~ command is another version of the trigger, added in version 2.03. The contents of this command would be a regexp pattern. Any parts that would normally be put into $1 to $9 can be obtained in <star1> to <star9>.


  ~ i (would have|would\'ve) done it
  - Do you really think you <star1> done it?

Use either +TRIGGER or ~REGEXP, but not both. If you use both for the same reply, the latter one will override.

% (Percent)

This is used as a "that" -- that is, an emulation of the <that> tag in AIML. The value of this would be Alpha's last reply, lowercase and without any punctuation. There's an example of this in the example reply code below.

- (Minus)

The - symbol indicates a response to a trigger. This and all other commands (except for > and <) always go below the + command. A single + and a single - will be a one-way question/answer scenario. If more than one - is used, they will become random replies to the trigger. If conditionals are used, the -'s will be considered if each conditional is false. If a conversation holder is used, the - will be the first reply sent in the conversation. See the example code below for examples.

^ (Carat)

The ^ symbol indicates a continuation of your last - reply. This command can only be used after a - command, and adds its arguments to the end of the arguments of the last - command. See the example code for an example.

@ (At)

The @ symbol indicates a redirection. Alpha triggers are "dead-on" triggers, meaning pipes can't be used to make multiple matchibles for one reply. In the case you would want more than one trigger (i.e. "hello" and "hey"), you use the @ command to redirect them to eachother. See the example code below.

* (Asterisk)

The * command is for conditionals. At this time conditionals are very primative:

  * variable=value::this reply is sent back

More/better support for conditionals may or may not be added in the future.

& (Amperstand)

The & command is for conversation holders. Each & will be called in succession once the trigger has been matched. Each message, no matter what it is, will call the next one down the line. This is also the rare case in which a "<msg>" tag can be included in the response, for capturing the user's message. See the example code.

# (Pound)

The # command is for executing actual Perl codes within your Alpha responses. The # commands are executed last, after all the other reply handling mechanisms are completed. So in this sense, it's always a good idea to include at least one reply (-) to fall back on in case the Perl code fails.

> (Greater Than)

The > starts a labeled piece of code. At this time, the only label supported is "topic" -- see "TOPICS" below.

< (Less Than)

This command closes a label.

/ (Forward Slash)

The / command is used for comments (actually two /'s is the standard, as in Java and C++).


These tags can be used within Alpha -REPLIES, some of which may be used also in @REDIRECTS.

<star>, <star1> - <star9>

Captures the patterns matched by wildcards in a reply trigger, from left to right. <star> is an alias for <star1>.

<input1> - <input9>

Inserts the last 1 to 9 messages the user sent (1 being most recent).

<reply1> - <reply9>

Inserts the last 1 to 9 messages the BOT sent in reply (1 being most recent).


Sets a topic. Set topic to random to return to the default topic.


Include a redirection within another response. Example:

  + * or something
  - Or something. {@<star1>}
  "Your stupid or something?"
  "Or something. At least I know the difference between "your" and "you're.""


Formalizes A String (Makes Every Word Capitalized)


Sentence-cases a string (only the first word is capitalized). Don't pass in multiple sentences if at all possible. :)




lowercases a string


Inserts a bit of randomness within the reply. This has two uses: to insert a random single-word or to insert a random sentence. If the pipe symbol is used, the latter will be the case.


  + random test one
  - This {random}reply trigger command  {/random} has a random noun.

  + random test two
  - Fortune Cookie: {random}You will be rich and famous.|You will 
  ^ go to the moon.|You will suffer an agonizing death.{/random}


This can only be used in &HOLDERS, it inserts the user's message (for example a knock-knock joke convo).


  // Test Replies

  // Chatbot-Alpha 2.0 - Mid-sentence redirections.
  + redirect test
  - If you said hello I would've said: {@hello} But if you said whats up I'd say: {@whats up}

  // Redirect test with <star1>.
  + i say *
  - Indeed you do say. {@<star1>}

  // Chatbot-Alpha 1.7 - A reply with continuation...
  + tell me a poem
  - Little Miss Muffet,\n
    ^ sat on her tuffet,\n
    ^ in a nonchalant sort of way.\n\n
    ^ With her forcefield around her,\n
    ^ the spider, the bounder\n
    ^ is not in the picture today.

  // Chatbot-Alpha 1.7 - Check syntax errors on deep recursion.
  + one
  @ two

  + two
  @ one

  // A standard reply to "hello", with multiple responses.
  + hello
  - Hello there!
  - What's up?
  - This is random, eh?

  // A "that" test.
  + i hate you
  - You're really mean... =(

  + sorry
  % youre really mean
  - Don't worry--it's okay. :-)

  // A test of having two of the same trigger in different topics.
  + sorry
  - Why are you sorry?

  // A simple one-reply response to "what's up"
  + whats up
  - Not much, you?

  // A test using <star1>
  + say *
  - Um.... "<star1>"

  // This reply is referred to below.
  + identify yourself
  - I am Alpha.

  // Refers the asker back to the reply above.
  + who are you
  @ identify yourself

  // Wildcard Tests
  + my name is *
  - Nice to meet you <star1>.
  + i am * years old
  - Many people are <star1>.

  // Conditionals Tests
  + am i your master
  * master=1::Yes, you are my master.
  - No, you are not my master.

  + is my name bob
  * name=bob::Yes, that's your name.
  - No your name is not Bob.

  // Perl Evaluation Test
  + what is 2 plus 2
  # $reply = "2 + 2 = 4";

  // A Conversation Holder: Knock Knock!
  + knock knock
  - Who's there?
  & <msg> who?
  & Ha! <msg>! That's a good one!

  // A Conversation Holder: Rambling!
  + are you crazy
  - I was crazy once.
  & They locked me away...
  & In a room with padded walls.
  & There were rats there...
  & Did I mention I was crazy once?

  // Regexp Trigger Tests
  ~ i (would have|would\'ve) done it
  - Do you really think you <star1> done it?

  ~ i am (\d) years old
  - A lot of people are <star1> years old.

  ~ i am ([^0-9]) years old
  - You're a "word" years old?

  // Random tests.
  + random test one
  - This {random}reply trigger command  {/random} has a random noun.

  + random test two
  - Fortune Cookie: {random}You will be rich and famous.|You will 
  ^ go to the moon.|You will suffer an agonizing death.{/random}

  // Topic Test
  + you suck
  - And you're very rude. Apologize now!{topic=apology}

  // 1.71 Test - Single wildcards should sort LAST, so this could be
  // used as a "I can't reply to that" reply.
  + *
  - Hm, I'm going to have to think about that one for a minute.
  - I'm sorry, but I can't answer that!
  - I really don't know what to say to that one...

  > topic apology

    + *
    - No, apologize for being so rude to me.

    // Set {topic=random} to return to the default topic.
    + sorry
    - See, that wasn't too hard. I'll forgive you.{topic=random}

  < topic


As seen in the example code, Chatbot::Alpha has support for topics.

Setting a Topic

To set a topic, use the {topic} tag in a response:

  + play hangman
  - Alright, let's play hangman.{topic=hangman}

Use the > and < commands (labels) to specify a section of code for the topic to exist in.

  > topic hangman
    + *
    - 500 Internal Error. Type "quit" to quit.
    # $reply = &main::hangman ($msg);

    + quit
    - Done playing hangman.{topic=random}
  < topic

The default topic is "random" -- setting the topic to random breaks out of code-defined topics. When in a topic, any triggers that aren't in that topic are not available for reply matching. In this way, you can have the same trigger many times but under different topics without them interfering with one another.


The Perl command #CODE can be used to enhance your replies to perform things too complex for Alpha alone to handle. The "hangman" example under TOPICS above is an example of how to call on a subroutine from your main process and put its output into the reply.

Chatbot::Alpha Internal Variables

Here are the main variables you should be interested in when making complex replies with the #CODE command:

  $reply - The final reply that the brain is going to return.
  $id    - The user ID of the one making the request.
  $msg   - The message that the user sent in.


It's possible to run into errors with contradicting or conflicting code. For example, some types of replies are very strict in how they're formatted. For example, a %THAT command must come immediately following a trigger command. And a +TRIGGER and ~REGEXP should not both be used at the same time, the latter call would override any others.

If you follow the syntax provided in the examples on this page, you should not expect to run into any contradictions in your code. Perhaps in a later release of Chatbot::Alpha the syntax checker will look for common errors such as these.


With Chatbot::Alpha 1.7, the module keeps filenames and line numbers with each command it finds (kept in $alpha->{_syntax} in the same order as $alpha->{_replies}). In this way, internal errors such as deep recursion can return filenames and line numbers. See the example code for a way to provoke this error.

  ERR: Deep Recursion (15+ loops in reply set) at ./testreplies.txt line 17


The following changes have been made from Chatbot-Alpha 1.x to 2.x

  - Methods have been renamed:
    load_folder     => loadFolder
    load_file       => loadFile
    sort_replies    => sortReplies
    set_variable    => setVariable
    remove_variable => removeVariable
    clear_variables => clearVariables

  - Methods that have been REMOVED:

  - Alpha commands added:

  - Alpha commands changed:
    New format:

  * Set a trigger of just an asterisk to set up a fallback for when no better
    response is found. Example:

    + *
    - I don't know how to reply to your message!


  - Conversation holders aren't always perfect. If a different trigger
    was matched 100% dead-on, the conversation may become broken.
  - If a bogus topic is started (a topic with no responses) there is
    no handler for repairing the topic.


  Version 2.05
  - Added a mention that Alpha has been superceded by RiveScript.

  Version 2.04
  - Fixed up some Perl warnings within the code.
  - Renamed the example script to '' to not confuse Makefile.

  Version 2.03
  - Added ~REGEXP command.
  - Added {random} tag.
  - Added more information about #CODE on manpage.
  - Updated Chatbot::Alpha::Syntax to support the new ~REGEXP command.
  - Applied a patch to to hopefully make automatic installation
    run more smoothly.

  Version 2.02
  - Mostly bug fixes in this release:
  - Added 'verify' argument to the new() constructor. If 1 (default),
    Chatbot::Alpha::Syntax is run on all files loaded. Set to 0 to avoid
    syntax checking (not recommended).
  - Fixed regexp bug with {formal}, {sentence}, {uppercase}, and {lowercase}.
    They should now function correctly even if their values have odd characters
    in them that would've previously screwed up the regexp parser.
  - Chatbot::Alpha::Syntax updated. See its manpage for details.
  - Rearranged a bit of the code so that <input> and <reply> would process
    before string tags.

  Version 2.01
  - Added string tags {formal}, {sentence}, {uppercase}, {lowercase}
  - Added tags <input> and <reply> and alias <star>.
  - Fixed conditionals bug (conditionals wouldn't increment correctly so
    only the last condition remained in memory. Now multiple conditions
    can be used for one trigger... i.e. comparing gender to male/female
    in two different conditions).

  Version 2.00
  - Added some AIML emulation:
    - In-reply redirections (like <srai>):
         + * or something
         - Or something. {@<star1>}
    - "That" kind of support.
         + i hate you
         - You're really mean... =(

         + sorry
         % youre really mean
         - Don't worry--it's okay. :-)
  - Renamed all methods to be alternatingCaps instead of with underscores.
  - Chatbot::Alpha::Syntax supports the newly-added commands.
  - Fixed conditionals, should work more efficiently now:
    - Format changed to *VARIABLE=VALUE::HAPPENS
    - Does numeric == for numbers, or eq for strings... = better matching.

  Version 1.71
  - Redid sorting method. Sometimes triggers such as I AM * would match
    before I AM * YEARS OLD.

  Version 1.7
  - Chatbot::Alpha::Syntax added.
  - ^ command added.
  - Module keeps filenames and line numbers internally, so on internal
    errors such as 'Deep Recursion' and 'Infinite Loop' it can point you
    to the source of the problem.
  - $alpha->search() method added.

  Version 1.61
  - Chatbot::Alpha::Sort completed.

  Version 1.6
  - Created Chatbot::Alpha::Sort for sorting your Alpha documents.

  Version 1.5
  - Added "stream" method, revised POD.

  Version 1.4
  - Fixed bug with wildcard subsitutitons.

  Version 1.3
  - Added the ">" and "<" commands, now used for topics.

  Version 1.2
  - "sortReplies" method added

  Version 1.1
  - Fixed a bug in reply matching with wildcards.
  - Added a "#" command for executing System Commands.

  Version 1.0
  - Initial release.


RiveScript, the successor to Alpha.




Casey Kirsle,


    Chatbot::Alpha - A simple chatterbot brain.
    Copyright (C) 2005  Casey Kirsle

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA