تماشای این درس نیاز به اشتراک حرفه‌ای دارد.

Spam detection overview0:00

All right, welcome back, everybody. So now for our next example, why don't we see if we can use OpenAI to detect and alert us to potential spam, maybe as part of a forum or a blog post, a comment section, something like that. Okay, so you're probably thinking, oh, that's probably pretty easy to do. And well, yes and no, I think. Sure, we could create a prompt that says, please analyze the following text, and the following text is the person's comment, right? And let us know if it includes spam. But think about it, the response from OpenAI is going to be as usual, like a paragraph.

And let us know if it includes spam. But think about it, the response from OpenAI is going to be as usual, like a paragraph of text that says, it seems likely that this includes spam due to such and such reasons. Maybe the article is linking to something a bit shady, or it's asking for personal information, blah, blah, blah. You get the idea. If I have that paragraph, how do I determine if the answer was yes or no? Do I try to concoct some kind of regular expression? I don't even know where to begin with that. So instead, we're going to figure out how to ask OpenAI to return JSON.

Building the form handler1:08

I don't even know where to begin with that. So instead, we're going to figure out how to ask OpenAI to return JSON. Let's get started. All right, so here is our starting point. It's a simple form. Maybe you'd see this at the bottom of a blog post. You enter your response, and you can publish it to the page. Okay, so if I switch over to phpStorm, and we visit our routes file, yeah, here's the home page that loads that form, as you see here. It's a pretty simple Tailwind UI snippet.

home page that loads that form, as you see here. It's a pretty simple Tailwind UI snippet. And yeah, the only thing you care about is we have a text area with a name of body. All right, so now when we submit that form, it'll make a POST request to /replies. And now we can get started. Okay, so as always, the first thing we want to do is validate the request. And in this case, I'll just say, it's required, it's a string, and that's good enough for me. Okay, so now, next, let's work with the OpenAI facade directly, just so we can see the entire example from A to Z without any indirection. We're going to chat with it, and we will create, and you've already learned this, so I can

example from A to Z without any indirection. We're going to chat with it, and we will create, and you've already learned this, so I can set the model to GPT-3.5 Turbo, even though I'll give you a warning. We're going to tweak that slightly in just a little bit. All right, next, the messages, and let's begin. All right, so first up, I'm going to have a system role, and we'll say the content is, you are a, let's imagine it's a forum. You are a forum moderator. All right, next, we'll have what I want to say to it. So the content will be, please inspect the following text and determine if it is spam.

All right, next, we'll have what I want to say to it. So the content will be, please inspect the following text and determine if it is spam. All right, and then what I could do, let's switch our quotes, and then I could do new line, new line, and then paste in the body from that text area. All right, that looks good, so let's close that out. We will receive our response, and I'm just going to die and dumps it to the page, and we'll have a look. All right, let's start with something simple. This was a great post, Bill. Probably not spam.

This was a great post, Bill. Probably not spam. Not very useful, but also not really spam. So if we go into choices, the first item, the message itself, as a forum moderator, I can confirm that the text you shared is not spam. But yeah, you see what I mean, right? In response, we get a paragraph of text, and I really have no idea what kind of magical regular expression I would have to write to parse that and figure out whether it ultimately translates to, yes, this is spam, no, it's not spam, or true or false. So yeah, of course, we could tweak the prompt a little bit, but also, I'm going to turn

Enabling JSON mode3:39

translates to, yes, this is spam, no, it's not spam, or true or false. So yeah, of course, we could tweak the prompt a little bit, but also, I'm going to turn on JSON mode, just so I can make it crystal clear that what I'm looking for here is basically an object with a property called isSpam, and I want OpenAI to set that to true or false. That's all I care about here. All right, so let's do this. I will open the OpenAI docs, and notice there is a reference to the new, or at least new at the time of this recording, JSON mode, all right? So if we have a look, we need to be using at least GPT-4 11.06 preview or 3.5 11.06 in order for this to work.

So if we have a look, we need to be using at least GPT-4 11.06 preview or 3.5 11.06 in order for this to work. So that's the first thing I'm going to do. I will copy that and paste it here. Next, we need to turn it on. So notice as part of our request, I can set this responseFormat key equal to a type of JSON object. So that can go right here. responseFormat type is a JSON object. All right.

Response format type is a JSON object. All right. Cool. But now, as it turns out, we actually have to double up, so to speak. So for example, if I come back here and submit the form again, I bet we get some kind of exception, and we do. Messages must contain the word JSON in some form. All right. So what are they referring to? Have a look right here.

So what are they referring to? Have a look right here. When using JSON mode, always instruct the model to produce JSON as part of the conversation. So you can see it right here. Who won the World Series in 2020? But the system rule above it says you are a helpful assistant designed to output JSON. And notice the word JSON is included there, and that's what it's looking for. All right. So yeah, we have to turn on JSON mode, but then we also have to be explicit that we want OpenAI to return JSON.

So yeah, we have to turn on JSON mode, but then we also have to be explicit that we want OpenAI to return JSON. So how about this? Who always responds using JSON? Okay. Let's give this another shot. I publish it again. And yeah. Okay. So choices.

Okay. So choices. Here's the first item. And hopefully, this will include JSON. And it does. So we have encoded JSON here. And notice it says result, not spam, and then they include a reason. Okay. But this still isn't enough, because, well, the schema of that JSON is going to change potentially every time, or if not every time, at least some of the time, the schema is going.

But this still isn't enough, because, well, the schema of that JSON is going to change potentially every time, or if not every time, at least some of the time, the schema is going to be different. So in this case, result was not spam. But maybe on the next iteration, that property result is called isSpam. And on the next iteration after that, they named the property spam. So let's give it a shot. One more time. Choices. Let's go in again.

Stabilizing JSON schema6:26

Choices. Let's go in again. And, oh, well, this time it's still called result, but notice there is no reason. So, yeah, the main point is you can't depend on the structure of the JSON response. So my next order of business is to give it just a little more of a hint as to what I'm looking for. So here's what we're going to do. Let's rewrite content. And I will use heredoc. Something like that.

And I will use here docs. Something like that. Okay. So I will begin by grabbing this initial request. All right. So we will grab the request body. Let's do this, actually. I usually save this to attributes. And then what I can do is say attributes body. Just a different way that we can write this.

And then what I can do is say attributes body. Just a different way that we can write this. All right. So I can get rid of all of that now. But this time I'm going to include an example response that I want. Expected response example. And here I will have an object where the key is spam and the value will be true or false. Yeah, I'm just providing OpenAI with a little more feedback about what I want it to do. Okay.

Yeah, I'm just providing OpenAI with a little more feedback about what I want it to do. Okay. So let's save that, switch back to the browser, and give it a refresh. All right. This time, excuse me, we have choices, 0, message, content. And then I will return json_encode the response so that I see a properly formatted php object.

Right down here, choices, zero, message, content. And then I will return json_encode the response so that I see a properly formatted PHP object converted to JSON. Okay. So let's give it a refresh. isSpam is false. One more time. isSpam is false. Third time, just showing you that it's far more consistent at this point. Okay.

Testing with real spam8:26

Third time, just showing you that it's far more consistent at this point. Okay. So next, why don't we try out actual spam? And here's what I've done. In my notes app, I've just collected a handful of spam threads that I've seen, either on the LaraCast forum or around the web. So why don't we just copy one of these and give it a shot. Paste it in. That looks like spam to me. We publish it.

That looks like spam to me. We publish it. And there we go. Is spam is set to true. Let's try another one. All three. Publish. Is spam is true. And the last one. There we go.

Blocking spam in app8:59

And the last one. There we go. Is spam is true. Everything seems to be working. Okay. So now, just for a quick example, why don't we say if the response is spam, then display flash message, fail the validator, whatever you want. I'm just going to say this is spam in this case, so we can be quick. Otherwise, we'll say valid post. And then, of course, we can't forget to decode that JSON string into valid JSON so we can

Otherwise, we'll say valid Post. And then, of course, we can't forget to decode that JSON string into valid JSON so we can interact with it. All right. Let's give it a shot. First, let's say great Post, Bill. It's a boring but entirely valid Post, and it will indicate that. If I instead use something that is clearly spam, what do we get? And we do get this is spam. Okay.

And we do get this is spam. Okay. So I think we're in business here. We have our hook, and that's really what we cared about. We wanted a simple boolean that indicated yes or no, true or false, is this spam? And as we learned, it can be tricky sometimes because OpenAI can respond in a variety of ways. Right? So we protected against that by being explicit about what we wanted, and then we provided examples for how it should respond, and that really does help a great deal.

So we protected against that by being explicit about what we wanted, and then we provided examples for how it should respond, and that really does help a great deal. Okay. So I think that's been your spam-specific example for this series. In the next episode, we'll move on to something new.

دوست دارید گاهی خبرهای Laracasts را ایمیل کنیم؟