Based on the experiments of Simon Goodway, it seems that a simple way to reduce comment spam without affecting the reader's experience is to make sure that every comment has some level of human input. As Simon suggests, by validating that the user has entered keystrokes while entering a comment (using javascript), we can effectively weed out any robots that bypass the comment form altogether.

MT-Keystrokes is a simple plugin for Movable Type 3 implementing this spam-aversion technique. With a trivial installation and a few simple changes to your templates, you can avoid nearly all spam at no cost to the reader.

Installation

1. Install the files

Copy or FTP the given archive to the base directory of your MT installation and unarchive the file. If the directory structure is kept intact, you can skip to step 2. Otherwise you'll have to manually move the files to their correct locations:

2. Update Templates

Next you'll have to make two changes to each template with a comment form, in every weblog you plan to use it in. In a default Installation, the comment form is located in the Individual Archive. Edit this template and find the location of your comment form. Immediately after the form declaration, insert the tag <$MTKeystrokes$>. This stub will place a small piece of javascript and a hidden variable inside the form. For instance:

...
<form method="post" action="/mt/mt-comments.cgi" name="comments_form">
<$MTKeystrokes$>
<input type="hidden" id="entry_id" name="author" />
<input id="author" name="author" />
...

Next you'll need to add some code to the comments textarea to call this javascript. The javascript function that needs to be called is named keystrokes and takes the current form as an argument. Like this:

...
<label for="text">Comments:</label>
<textarea id="text" name="text" cols="50" onkeypress="keystrokes(this.form)"></textarea>
<input type="button" onclick="window.close()" value="Cancel" />
...

Just in case the user edits their text in another editor, hits paste, and then submits, we'll add a human-user check on the submit button as well:

...
<input type="button" onclick="window.close()" value="&nbsp;Cancel&nbsp;" />
<input type="submit" name="preview" value="&nbsp;Preview&nbsp;" />
<input type="submit" onclick="keystrokes(this.form)" name="post" value="&nbsp;Post&nbsp;" />
...

3. Configure keystrokes.pl (optional)

If you don't plan to use Keystrokes for every weblog in your MT installation, or you'd like to change the behavior a bit, there are three variables located within keystrokes.pl that will allow you to configure it. Open this file in a text editor and you should see them located at the top of the file. Here's what they do:

Done

That's it, presto, whamo.

Changes

0.1.5
XHTML Compliancy fix (removed language= in script tags)
0.1.4
Minor bugfix
0.1.3
Added support for dynamically generated templates via the function.MTKeystrokes.php module. Added support for ignoring various weblogs within a given MT installation
0.1.2
added support for the <$MTCommentFields$> tag, used in the default comment-previewing template. On Maciej's suggestion, got rid of the keystroke count, as it's redundant.
0.1.1
fixed javascript bug that made the script unusable
0.1
initial version