Beefy Boxes and Bandwidth Generously Provided by pair Networks
Come for the quick hacks, stay for the epiphanies.
 
PerlMonks  

Is ChatGPT like having a thousand monkeys?

by talexb (Chancellor)
on Mar 19, 2025 at 13:49 UTC ( [id://11164327]=perlmeditation: print w/replies, xml ) Need Help??

I have a script that builds an HTML document and sends it out as an E-Mail. The problem we were seeing was that Outlook (Microsoft's E-Mail reader application) was having problems displaying the HTML document, while the raw document looked fine when I viewed it in my browser. Within Outlook, the HTML would render fine for a while, then it would drop down into showing the raw HTML, then go back to rendering the page. It was irritating.

I was using a template to generate the HTML document, so the tags were all matched: a starting and ending table tag, within that, a bunch of paired tr tags, and within each row, paired td or th tags. I've been generating tables in HTML since the late 90's, so I'm pretty sure that's right. The only new thing I've added is using styles that are defined in the page header.

Anyway, a new employee on the client team put my vanilla HTML into ChatGPT to see if it could identify what the problem was. ChatGPT listed six problems:

  1. Invalid table headers - except they were all matched, and contained within a tr element;
  2. CSS issues - telling me that border-collapse: collapse would be better than border-collapse: separate; - irrelevant;
  3. Missing closing th tags - same error as #1. All tags were matched;
  4. Potentially Incorrect Data Formatting - suggesting that <td class='left'>0</td> would be better displayed as <td class='left'>0.00</td>, which was irrelevant;
  5. Incorrect HTML Tag Nesting (Semantics Issue) - this was reporting that a style was declared in the page header but never used, irrelevant; and
  6. Email Signature Formatting - some discussion about how the confidentiality statement was too wordy.
None of these points addressed the issue of display breakage in Outlook. The only problem I could see in the file I was generating was that there were a few blank lines in the HTML document.

Oh.

Oh no. Really?

Finally, at 8pm last night, I realized what the problem was. Blank lines. Outlook doesn't like blank lines within an HTML document. It interprets that as the end of the document, and goes back to showing raw text. Until the HTML starts up again, at which point (for some special, lucky, magic, Microsoft reasons) it goes back to showing the interpreted HTML. Oh, Microsoft.

ChatGPT didn't pick up on the blank lines, instead, it picked up on a bunch of inconsequential or irrelevant issues with the HTML.

So, I'm still a little suspicious of AI in general. It's not yet at the point where it can make creative leaps; it still wants to examine each grain of sand on the beach, rather than look at the shape of the dune. Sure, maybe ChatGPT should have been specifically prompted with 'Outlook isn't rendering this HTML document correctly, tell me why' -- but I think you can get better mileage by Telling It To The Bear, or having another pair of eyes looking at the problem.

Alex / talexb / Toronto

For a long time, I had a link in my .sig going to Groklaw. I heard that as of December 2024, this link is dead. Still, thanks to PJ for all your work, we owe you so much. RIP Groklaw -- 2003 to 2013.

Replies are listed 'Best First'.
Re: Is ChatGPT like having a thousand monkeys?
by kikuchiyo (Hermit) on Mar 19, 2025 at 17:55 UTC

    One particularly striking way to realize the limitations of the current LLMs: ask them to create an ASCII art banner of any word, e.g. PERLMONKS or OUTLOOK.

    They "understand" what an ASCII art banner is, they will produce an aesthetically pleasing output that is in a consistent style and (usually) features readable, well-formed letters... but the actual text will be invariably wrong.

    What's funny about it is that if you keep prompting them that "that's wrong, please make sure that it spells exactly 'PERLMONKS'", they will keep apologizing and producing different, but often increasingly bad output.

    By the way, at $work we wanted to hire a backend programmer recently, and we gave a homework exercise for the candidates with a good enough CV. Almost all of them used an LLM to produce the solution, some of them didn't even bother to remove the obvious garbage from the end of their submission. What's scary about it is that ChatGPT is advanced enough to produce an almost good solution out of the box, usually it either compiles right away or you have to fix one or two lines at most. The solutions were good enough that they figured out the main "point" of the exercise and they managed to avoid some of the common pitfalls, however none of them were 100% correct.

      I regularly get prompted by my boss to use LLM to "work faster". So i try every couple of week. So far, none of the results have made it back into my codebase, because the output was either wrong, was completely against my coding guidelines and/or had major security problems.

      Well, technically, i use one of my project at work that was modified by an LLM. I maintain exactly one Chrome extenstion, Edit Hidden Fields, and i used the help of some LLM (don't remember which one i had loaded into ollama at that time) tp upgrade it to Manifest V3. I had to manually fix a few things, but at least the LLM managed to do most of the work and talk me through the rest.

      PerlMonks XP is useless? Not anymore: XPD - Do more with your PerlMonks XP
      Also check out my sisters artwork and my weekly webcomics
Re: Is ChatGPT like having a thousand monkeys?
by NERDVANA (Priest) on Mar 25, 2025 at 18:16 UTC
    Sure, maybe ChatGPT should have been specifically prompted with 'Outlook isn't rendering this HTML document correctly, tell me why'

    ... what did you ask it then? Yes you should always be as specific as possible about what you want the AI to help you diagnose. Especially be sure to mention any edge cases or design constraints you want it to think about. The AI is essentially the most learned person on earth giving you an off-the-cuff hot-take about what it knows about your problem without thinking too much about it, so the more topics you "jog its memory" about, the better the answer you get.

    I've had quite good luck with ChatGPT, but only limited to small topical questions. I haven't gotten it to really write my code for me except for one time when I had it write a SMTP-receiving mini mail server in python. It seems to have more trouble with perl, presumably because there's so many ways to do things, the unusual context "gotchas", and perl's limited standard library.

    I really wish there was a quick and easy way to share the prompts that resulted in successful outcomes, but my shares are limited to my company workspace, and copy/paste out of ChatGPT is mostly broken. Meanwhile, Claude 3.5 does a fair bit better than ChatGPT and I think we should probably switch to paying for that one instead.

    Now, on the topic of email, if you want to get some nice looking HTML emails working in Outlook, especially old versions of outlook, here are my notes from the project where I do a bunch of that (using Template Toolkit in Email::MIME::Kit, though I recommend Email::MIME::CreateHTML instead):

    [%# Notes for email styles: - Microsoft Outlook does not display "HTML Email", it imports the HTM +L into a Microsoft Word document and renders that. So, email styling is mor +e about what Microsoft Word is able to import than it is about correct HTML +. - never put "margin" on a table element, because some Outlook version +s will apply that to all of the table cells as well. - Outlook can't properly handle padding on anything other than a tabl +e cell - Outlook can only have "border:collapse" on tables. - never use "float" or absolute positioning - you can't reliably create @print styles, so make everything work on + a 7.5" page - Outlook can't do centered fixed-width content without using a table +, so the whole page needs wrapped in a table - the "Mkit" system will inline all these styles into the elements th +emselves, because some email clients don't handle classes well. %]
    [%# Outlook has goofy spacing on list item elements. CSS flattens it +down, but then unindent to compensate for the default padding that we removed. %] <!--[if gte mso 9]> <style> li { text-indent: -1em; } </style> <![endif]--> </head> <body leftmargin="0" marginwidth="0" topmargin="0" marginheight="0" bg +color='[% bgcolor %]' style="margin: 0px; padding:0px; color:black; background-color:[% bg +color %];"> [%# ----- PAGE WRAPPER ----- %] [%# MS Office cant handle css width, so need to wrap everything with a + table %] <!--[if mso]> <table cellpadding="0" cellspacing="0" border="0" style="padding:0px;m +argin:0px;width:100%;"> <tr> <td style="padding:0px;margin:0px;">&nbsp;</td> <td style="padding:0px;margin:0px;width:800px;" width="800"> <font face="arial"><font face="calibri"> <![endif]--> <div style='width:7.5in; margin:auto; [% style_font_family %] font-size: 9pt; color: black; background-color: [% bgcolor %]; '>

    I've never had the problem you describe with blank lines. I would guess that either you've found a special misbehaving version of Outlook I've not encountered, or maybe your MIME structure or html declaration isn't correct. Here's one of ours:

    From: example <example@example.com> To: example <example@example.com> Subject: Example Date: Tue, 25 Mar 2025 13:02:21 -0500 MIME-Version: 1.0 Content-Type: multipart/alternative; boundary=17429257410.7ADB6.10260 Content-Transfer-Encoding: 7bit Message-ID: <17429257411.685ff8.10260@redacted.example.com> --17429257410.7ADB6.10260 Date: Tue, 25 Mar 2025 13:02:21 -0500 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Example --17429257410.7ADB6.10260 Date: Tue, 25 Mar 2025 13:02:21 -0500 MIME-Version: 1.0 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta charset=3D"UTF-8" /> <title>Example</title> </head> <body bgcolor=3D"#cccccc" leftmargin=3D"0" marginheight=3D"0" marginw +idth= =3D"0" offset=3D"0" topmargin=3D"0"> <table bgcolor=3D"#cccccc" cellpadding=3D"10" cellspacing=3D"0" widt +h=3D"= 100%"> ... </table> </body> </html> --17429257410.7ADB6.10260--

    And an example of how to assemble that:

    $text ||= HTML::FormatText::WithLinks->new(unique_links => 1)->pars +e($html); # Ugly workaround for WPEngine.com discriminating against perl my $real_new= Email::MIME::CreateHTML::Resolver::LWP->can('new'); local *Email::MIME::CreateHTML::Resolver::LWP::new= sub { my $self= $real_new->(@_); $self->{UA}->agent(q{We're your customer, dammit, stop blocking +perl}); $self->{UA}->protocols_allowed(['http', 'https']); return $self; }; # Build the email. The resolver will find all external images and +stylesheets # and suck them in as multiple parts. my $viewable= Email::MIME->create_html( header => [ ], # we use the unicode-enabled setters, instead text_body_attributes => { charset => 'UTF-8', encoding => 'quote +d-printable' }, text_body => encode('UTF-8', $text), # text gets assigned as-is body_attributes => { charset => 'UTF-8', encoding => 'quoted-pri +ntable' }, body => $html, # body gets assigned as body_str embed => 1, base => "https://redacted.example.com", object_cache => $self->resource_cache, # Prevent excessive looku +ps of resources # Because most mail clients don't properly process <style> block +s, # we have to embed the style onto each individual element. inline_css => 1, %$args, ); # Assemble MIME structure for attachments my $email= @attachments? Email::MIME->create(header => [], parts => [ $viewable, @attachm +ents ]) : $viewable; # These methods properly handle unicode, which is why we use them i +nstead of # passing these to the constructor $email->header_str_set(To => (ref $to eq 'ARRAY'? join(', ',@$to) : + ''.$to)); $email->header_str_set(From => (ref $from eq 'ARRAY'? join(', ',@$f +rom) : ''.$from)); $email->header_str_set(Subject => ''.$subject); return $email; }
Re: Is ChatGPT like having a thousand monkeys?
by NERDVANA (Priest) on Mar 27, 2025 at 17:04 UTC
    Here's an example where ChatGPT shines. I just saved about an hour and a half by asking it this:
    I'm serving over HTTP a potentially large document of "Content-Type: text/plain". I want to create a javascript interface that loads the first 100K of the file, then as the user scrolls to the bottom it loads the next 100K and so on. The javascript can use jQuery if needed. I'd like the page structure to have one scrolling div with an event tied to the scroll that triggers loading the next portion. There should be a div below that which appears as part of the document text with "..." content if the document is not fully loaded, and it should display a spinner beside that any time the ajax is in progress. There should be a div at the top that states the size of the file, how much has been loaded, and a small button "load all" that loads all remaining text. The javascript should be configured with a simple URL (of the document) and DOM node (parent for it's generated nodes) and use HTTP byte range requests to fetch from that document.
    ChatGPT 4o:
    Here's a full working example of the JavaScript interface you're describing. This implementation uses:
    • HTTP Range requests to fetch 100KB chunks.
    • A scrollable <div> to display the text.
    • A status bar with file size, loaded size, and a "Load All" button.
    • A spinner and "..." that show while more content is being fetched.
    You can drop this into a page and call initLazyTextLoader(url, parentElement) to attach it.
    (etc etc)

    Now, regular JS developer may have only saved 20 minutes, but I'm rusty on all the jQuery API and DOM API and HTTP range requests and would have gone a bit slowly as I look up all those details.

    Then I saved another hour when I decided to restructure the page:

    Instead of jQuery, can you write this as an ExtJS 3.4 Component?
    ChatGPT 4o:
    Absolutely! Here's how you can implement this as a custom ExtJS 3.4 component, using only ExtJS classes and APIs (no jQuery). This component:
    • Is scrollable
    • Uses HTTP Range requests to fetch chunks of text
    • Updates a status bar
    • Shows a spinner and "..." when loading
    • Has a "Load All" button

    Then, I lost 10 minutes as I came here to post about it :-)

    Epilogue:

    Actually, the code above has a few bugs, the main one being that the 'afterrender' event of the parent component runs before the child components have been rendered, and can't be used to apply event listeners. (to be fair, seems like a terrible design decision on the part of ExtJS) The correct solution is to put the event on the child component's afterrender event. But, I needed to do a few more iteration of the idea, and got annoyed that ChatGPT kept making this mistake even when I told it about that problem, so I moved over to Claude 3.5 and *that* one got it right on the first try. Though, I made things more complicated and then it generated a bug as well, but it was fairly easily fixed. It's still a time-saver to automate the boring mundane code and not have to look up all those APIs.

Re: Is ChatGPT like having a thousand monkeys? (Empty lines in emails)
by LanX (Saint) on Mar 22, 2025 at 20:37 UTC
    > I realized what the problem was. Blank lines.

    It's been a wile since I worked with the email format, but I seem to remember empty lines¹ have syntactic meaning to separate header and different "paragraph portions" (like content and attachments) of the email. (I'm too tired to look up the correct terminology)

    So I guess that Outlook doesn't see the whole HTML to belong to the same part of the email, because it splits on paragraphs. ³

    I bet, you could just base64 encode your HTML and it would work ... provided you set the correct content encoding. Outlook should happily accept empty lines inside HTML then. ²

    You could also insert space characters where they are ignored by HTML to have non-empty lines.

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    see Wikisyntax for the Monastery

    Update

    ¹) i.e., a line with nothing preceding the CRLF

    ²) I always use base64 for inserted content outside my control. ⁴

    ³) in the meantime I tried to look it up in the (many) RFCs and there is a mention of an old format interfering...

    ⁴) NB: there is also a 1000 characters per line restriction in emails, which is solved by base64 with its maximum line length of 76 characters.

      It's been a wile since I worked with the email format, but I seem to remember empty lines¹ have syntactic meaning to separate header and different "paragraph portions" (like content and attachments) of the email. (I'm too tired to look up the correct terminology)

      Only the first empty line has that special meaning, it separates the message headers from the message body. The message body can literally be everything for a basic RFC822-style mail. For multi-part MIME messages (e.g. HTML with plain text alternative, or HTML with images), the message header specifies a boundary that marks the end of a MIME message part, after that, you are back to parsing headers, and another empty line separates that from the next message body. See MIME in the Wikipedia for a nice short example, and for links to the RFCs.

      Outlook should have absolutely no problems with empty lines in the message body. That said, Outlook has a very long and very ugly history of ignoring established standards, so I would not bet a penny on Outlook behaving properly.

      I would have a look at the mails in another mail client, like Thunderbird. Also, I would have a look at the raw mail format, as received from the mail server. Again, Thunderbird could help with that, it does not mess with the message source.

      Alexander

      --
      Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
        IMHO, only unless the OP used an empty boundary in multipart message.

        https://en.wikipedia.org/wiki/MIME#Multipart_messages

        It would be easier to tell if we saw an SSCCE of the problematic email

        Outlook is not the only client to ignore standards, Thunderbird is mentioned in the WP article.¹

        My approach was to go for an as simple as possible "standard" which tested well with all main mail clients. (My paying clients insisted on freely composing HTML emails in TinyMCE with embedded images and send them to hundreds of recipients in a group of companies with > 300K employees in total)

        Multipart in combination with base 64 worked very well. And of course a unique boundary (very similar to here-docs)

        Cheers Rolf
        (addicted to the Perl Programming Language :)
        see Wikisyntax for the Monastery

        ¹) And to be fair, old RFCs are prone to ambiguities. Sometimes clients established new "standards" for extensions which were only codified later. While MS was notorious for this, it's not the only player in this game.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlmeditation [id://11164327]
Front-paged by Arunbear
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having an uproarious good time at the Monastery: (3)
As of 2025-07-13 05:17 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?
    erzuuliAnonymous Monks are no longer allowed to use Super Search, due to an excessive use of this resource by robots.