<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Eliot S</title>
    <description>The latest articles on DEV Community by Eliot S (@eliots).</description>
    <link>https://dev.to/eliots</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4021422%2F777b6279-6fec-4eba-b7e1-b806d26640e7.png</url>
      <title>DEV Community: Eliot S</title>
      <link>https://dev.to/eliots</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/eliots"/>
    <language>en</language>
    <item>
      <title>Free vs Paid AI Writing Tools: What the Difference Looks Like on a CS Assignment</title>
      <dc:creator>Eliot S</dc:creator>
      <pubDate>Mon, 20 Jul 2026 12:28:33 +0000</pubDate>
      <link>https://dev.to/eliots/free-vs-paid-ai-writing-tools-what-the-difference-looks-like-on-a-cs-assignment-4p06</link>
      <guid>https://dev.to/eliots/free-vs-paid-ai-writing-tools-what-the-difference-looks-like-on-a-cs-assignment-4p06</guid>
      <description>&lt;p&gt;In May, I had a 1,400-word software ethics paper due in 48 hours. Drafted the whole thing with a free AI tool, touched up maybe two paragraphs, fixed some clunky phrasing, and hit submit. Two days later: "Turnitin flagged your submission with a high AI probability score."&lt;/p&gt;

&lt;p&gt;So that was the end of my free-is-probably-fine era.&lt;/p&gt;

&lt;p&gt;I didn't stop using AI. That's not where this story goes. What changed was I started paying attention to the real gap between free and paid tools, because it turns out that gap is about more than monthly word limits. It shows up in the output itself, and that matters a lot when you're submitting anything with real technical depth.&lt;/p&gt;

&lt;p&gt;For most of this semester I've been comparing free AI writing tools for students against their paid equivalents, specifically on CS writing: lab reports, algorithm analysis papers, technical reflections, discussion posts, README docs. Below is what I found, not what the landing pages say.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why free AI writing tools for students dominate
&lt;/h2&gt;

&lt;p&gt;The math is obvious. You're broke, you have a ten-page OS concepts paper due Thursday, and $20/month on a writing tool you'll use three times a semester makes no sense.&lt;/p&gt;

&lt;p&gt;ChatGPT free, Gemini free, Claude free, plus dozens of smaller tools advertising themselves as AI writing assistants, all run on an email address and five minutes. For short, low-stakes stuff, they work. Once you need output that can pass a detection scan or genuinely sound like a person wrote it, the story shifts.&lt;/p&gt;

&lt;p&gt;"Perfectly functional" has a ceiling, and that ceiling tends to appear exactly when you need the tool most: the paper worth 30% of your grade that goes through Turnitin.&lt;/p&gt;

&lt;h2&gt;
  
  
  What free tiers produce on a CS assignment
&lt;/h2&gt;

&lt;p&gt;Pick a standard CS writing assignment: a 900-word reflection on the ethical implications of biased training data. Free tools give you the same thing every time, and it's pretty easy to spot.&lt;/p&gt;

&lt;p&gt;The output reads like an AI summarizing Wikipedia. Technically correct, completely forgettable. It'll hit the obvious points: fairness, representation, accountability. But it'll say nothing that distinguishes your answer from the 200 other students who ran a similar prompt. There's no angle. No specific argument. Just the surface-level version of the topic restated in paragraph form.&lt;/p&gt;

&lt;p&gt;Then there's the structure issue. Ask an AI about "three ethical challenges in machine learning" and the free output will have three sections literally titled "Challenge 1," "Challenge 2," and "Challenge 3." No synthesis, no through-line, no moment where the paper makes a claim. The prompt became headings.&lt;/p&gt;

&lt;p&gt;The sentence rhythm is where it really falls apart. Cadence too even. Vocabulary sitting a register higher than what a student would write. Transitions like "Furthermore" and "It is worth noting that" appearing every third sentence without fail. It gets detected as AI because it reads like AI: there's no inconsistency in it, which is itself suspicious.&lt;/p&gt;

&lt;p&gt;On Discord or in a casual personal project, none of that matters. On Turnitin, it matters a lot.&lt;/p&gt;

&lt;p&gt;I've run the same prompt through several free tools and checked output at the document level. Unedited, they land at 70-90% AI probability. Light editing, varying sentence structure, swapping vocabulary, breaking up the rhythm, gets some down to 50-60%. Still borderline for anything high-stakes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where paid tiers earn their price
&lt;/h2&gt;

&lt;p&gt;Not all of them do, to be clear. Some of what you're paying for is real. Some of it is just better branding on the same underlying model.&lt;/p&gt;

&lt;p&gt;Context windows are the real one. Paid tools hold more of your paper in context while generating, which cuts down on the contradictions and repetition that show up when a free tool effectively forgets what it wrote three paragraphs ago. Free tiers often cap at a few thousand tokens: enough for a 500-word response, not enough for a 1,500-word lab report where the conclusion needs to reference specific claims from section two.&lt;/p&gt;

&lt;p&gt;Instruction-following is the other big gap. Tell a paid model to write for "a second-year CS student explaining cache coherence to a non-technical reader" and it adjusts register, avoids jargon, and maintains that adjustment for the whole document. The free equivalent typically starts okay and drifts back into textbook language by paragraph three. That drift is what kills you on reflective writing and technical essays, where voice and consistency are what separates a passable paper from an obvious AI dump.&lt;/p&gt;

&lt;p&gt;On detection: nothing is undetectable, but paid tools built for academic writing produce output with more sentence variety, more natural paragraph rhythm, and fewer of the statistical patterns that detection tools are trained to catch. On a 600-word algorithm analysis prompt, the free output came back at 84% AI probability on first run. Same prompt on a paid tool: 41%. One editing pass got it under 30%.&lt;/p&gt;

&lt;p&gt;Then there's the time math. Editing a free output usually means rewriting 40-50% of the content to get it somewhere passable. When the starting point is better, you're touching maybe 15-20%. That compounds across a semester.&lt;/p&gt;

&lt;h2&gt;
  
  
  Side-by-side on three CS writing tasks
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Lab report introduction (200 words)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Free output: technically accurate, appropriately formal, three consecutive sentences starting with "The." Detection probability: 79%.&lt;/p&gt;

&lt;p&gt;Paid output: same technical content, more varied sentence structure, one deliberate sentence fragment for emphasis. Detection probability: 38%.&lt;/p&gt;

&lt;p&gt;Editing time to reach a submittable draft: roughly 15 minutes for the free output, 5 for the paid. That gap widens considerably for longer assignments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Technical reflection on a failed project (500 words)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is where it's most obvious. Reflective writing needs voice, and free tools default to corporate-sounding reflection: "challenges were encountered," "lessons were learned," "future iterations will benefit from." Passive, vague, and flagged every time.&lt;/p&gt;

&lt;p&gt;Paid tools with a first-person or personal essay mode get noticeably closer to something that sounds real. You still have to inject the specifics: what went wrong, what you felt when the deployment broke at 2am. But the scaffolding is much closer to human writing, which cuts down on how much you need to rewrite before it sounds like you.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub README (200-400 words)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Free tools are mostly fine here. Detection isn't really a concern in a README anyway. A free model handles "write a README for a Flask REST API with JWT authentication, Python 3.11, and PostgreSQL" almost as well as a paid one. Minimal difference for documentation-only use.&lt;/p&gt;

&lt;p&gt;If READMEs and code documentation are all you're generating AI writing for, the free tier probably covers it. I wrote a full breakdown of the best tools specifically for this use case in &lt;a href="https://eliotreads.substack.com/p/best-free-ai-writing-tools-for-computer" rel="noopener noreferrer"&gt;Best Free AI Writing Tools for Computer Science Students&lt;/a&gt; on my Substack, if that's what you're after.&lt;/p&gt;

&lt;h2&gt;
  
  
  Free AI writing tools for students: when they're enough
&lt;/h2&gt;

&lt;p&gt;The answer depends on the assignment, not on the tool.&lt;/p&gt;

&lt;p&gt;For low-stakes work: discussion posts under 300 words, peer review responses, short reflections that aren't weighted heavily. Free is fine. Edit once, submit. Detection scores matter a lot less when a professor isn't cross-referencing the paper against your in-class writing samples, and most low-weight discussion posts aren't worth that level of scrutiny.&lt;/p&gt;

&lt;p&gt;500-1,000 word papers and major discussion boards are where it gets conditional. Free tools work, but you need to edit hard. Rewrite at least 40% of what gets generated, vary sentence lengths, cut vocabulary that doesn't match how you write. It's not faster than starting from scratch. It's faster than staring at a blank page.&lt;/p&gt;

&lt;p&gt;Anything over 1,000 words going through Turnitin, or anything a professor has flagged as monitored? Free tools are a liability. At that point you're doing a near-full rewrite anyway, which means the AI is giving you an outline and rough phrases, not a draft. A paid tool with better baseline output saves more editing time per month than it costs.&lt;/p&gt;

&lt;h2&gt;
  
  
  The thing nobody mentions about free tiers
&lt;/h2&gt;

&lt;p&gt;Run the same prompt twice on a free tool. The quality difference between those two outputs is often significant: one will be solid, the next will be stiff and generic. Paid tiers show variance too, but the floor is higher and the swings are smaller.&lt;/p&gt;

&lt;p&gt;When you're under deadline and can't spend time running the same prompt four times to find the good output, that consistency gap matters. Free tools sometimes get you there. Paid tools get you there more reliably.&lt;/p&gt;

&lt;h2&gt;
  
  
  The verdict
&lt;/h2&gt;

&lt;p&gt;Paid AI writing tools produce better output on CS assignments. The detection numbers are lower, the instruction-following is tighter, and editing time is shorter. Is it worth paying for on a student budget? That's the real question.&lt;/p&gt;

&lt;p&gt;For most CS students, one paid tool used selectively for high-stakes assignments makes sense. Two or three major papers a semester where you cut editing time and reduce detection risk can justify $10-15/month. Everything else: READMEs, portfolio blog posts, low-stakes coursework. Free AI writing tools for students handle those well enough.&lt;/p&gt;

&lt;p&gt;You just need to know which category you're dealing with before you submit.&lt;/p&gt;

&lt;p&gt;ngl, I figured this out the hard way. Hopefully this saves you the Turnitin email.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>computerscience</category>
      <category>education</category>
      <category>writing</category>
    </item>
    <item>
      <title>AI Humanizer Comparison: What Actually Changes When You Run Text Through Them</title>
      <dc:creator>Eliot S</dc:creator>
      <pubDate>Mon, 13 Jul 2026 14:05:59 +0000</pubDate>
      <link>https://dev.to/eliots/ai-humanizer-comparison-what-actually-changes-when-you-run-text-through-them-56p9</link>
      <guid>https://dev.to/eliots/ai-humanizer-comparison-what-actually-changes-when-you-run-text-through-them-56p9</guid>
      <description>&lt;p&gt;Last semester I got tired of guesswork and made a spreadsheet. Same 500-word paragraph, six different tools, back to back. None were detection scores. The actual output was which sentences got rearranged, which words switched out, whether the output still read like something a person wrote.&lt;/p&gt;

&lt;p&gt;I'd been using these tools for almost two years at that point. And every AI humanizer comparison post I found was the same. Tools. Prices. Star ratings. Nothing about what happened to your writing, which is the only part that matters if you want to understand why some tools work and others don't. So I ran my own test.&lt;/p&gt;

&lt;p&gt;The gap between free and paid tools is bigger than people let on. The gap between "swaps words around" and "reorganizes sentences" is also larger. In fact, there's a middle category too, tools that partially rewrite some sentences while leaving others identical, which gives you spotty results and makes you think the tool failed even though it didn't. Knowing what each type does helps make choosing one less random.&lt;/p&gt;

&lt;h2&gt;
  
  
  What an AI humanizer does to your text (technical version)
&lt;/h2&gt;

&lt;p&gt;Understanding detection before comparing tools helpfully explains exactly what detection measures.&lt;/p&gt;

&lt;p&gt;Turnitin and GPTZero look at two things: perplexity (how predictable were each word choice compared to what a language model would have picked?) and burstiness (how much does sentence length vary across a paragraph?). Human-written text scores low because the model takes the statistically likely path with every single word. Burstiness is short sentences here and long ones there. Fragments. Occasional run-ons. Clusters in a narrow band are how AI output works.&lt;/p&gt;

&lt;p&gt;Humanizers target one or both. The least expensive way is to use vocabulary substitution. Swap predictable words for less common ones and perplexity increases. Structural rewriting costs more. Break down sentences, rebuild them differently, change where information arrives. Transition phrases such as "Furthermore," and "It is important to note that..." get special attention from many tools today because bro, those are pretty much detector bait at this point.&lt;/p&gt;

&lt;p&gt;The problem with just swapping vocabulary: detectors caught up to it. Uncommon words over identical sentence structure can be flagged. Perplexity increases but burstiness stays flat, and that mismatch is now its own signal. The tools that hold up do both passes: different words and different structure.&lt;/p&gt;

&lt;p&gt;There's another signal that gets far less attention: argument coherence. AI paragraphs follow a super predictable sequence: claim, support, support, conclusion. Some structural rewriting tools break this by changing where ideas land. That's harder to detect and it's not something any substitution-only tool can replicate.&lt;/p&gt;

&lt;p&gt;I went deeper on this with real score comparisons in &lt;a href="https://eliotreads.substack.com/p/best-ai-humanizers-for-college-students" rel="noopener noreferrer"&gt;Best AI Humanizers for College Students: Free and Paid Options Tested&lt;/a&gt; if you want the data.&lt;/p&gt;

&lt;h2&gt;
  
  
  AI humanizer comparison: what the text looked like after processing
&lt;/h2&gt;

&lt;p&gt;Four things tracked per tool: sentences structurally rearranged, words swapped, meaning preserved, output readable.&lt;/p&gt;

&lt;p&gt;More surprisingly large than expected were the gaps between free tools and paid tools. The gaps between "words changed" and "sentences rearranged" were also larger than expected. There's a middle category too, tools that partially rewrite some sentences while leaving other sentences entirely intact, which produces spotty results and leads you to think the tool has failed even though it may not have done anything wrong.&lt;/p&gt;

&lt;p&gt;Understanding what each type does makes choosing a tool significantly less random.&lt;/p&gt;

&lt;h2&gt;
  
  
  Is there a free AI humanizer?
&lt;/h2&gt;

&lt;p&gt;Yeah, a handful actually work. Most free tools are either capped at a few hundred words, watermark the output, or run so slow you give up. It is what it is.&lt;/p&gt;

&lt;p&gt;Walter Writes has a Lite tier that doesn't require a subscription. For quick tests before submitting or checking whether a tool is worth paying for, it's genuinely useful. I tested a bunch of free options head-to-head in &lt;a href="https://eliotreads.substack.com/p/i-tested-every-free-ai-humanizer" rel="noopener noreferrer"&gt;I tested every free AI humanizer I could find&lt;/a&gt; with before/after detection scores if you want specifics on each one.&lt;/p&gt;

&lt;p&gt;The bigger issue with free tools is consistency. A tool that scores well today might not after the next model update, and free tiers don't always get updated at the same pace. For low-stakes stuff, free is fine. For anything that affects your grade, pay the difference. It's usually not much.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to 100% humanize AI text?
&lt;/h2&gt;

&lt;p&gt;"100%" is the wrong frame. No tool makes text permanently undetectable across every platform and every future update. Turnitin updates. GPTZero updates. A professor who's graded your work all semester is a fundamentally different kind of evaluation than any software score.&lt;/p&gt;

&lt;p&gt;What you can do is get the text statistically indistinguishable from human writing and editorially consistent with your voice. Those are two different jobs. The tool handles the statistical side, perplexity, burstiness, structural variation. You handle the editorial side.&lt;/p&gt;

&lt;p&gt;fr fr the biggest mistake I see is running text through a humanizer and submitting it without reading the output. The tool might have introduced a sentence that doesn't fit your argument, or phrasing you'd never actually write. A 15-minute read catches all of that.&lt;/p&gt;

&lt;p&gt;My process: generate the draft, run it through a structural humanizer, then spend 15 minutes editing specifically for sentences that don't sound like you. That last step is the one people skip. It's also the step that closes the gap between a low AI score and something a professor flags for style inconsistency. Covered the full editing breakdown in &lt;a href="https://eliotreads.substack.com/p/the-editing-step-is-where-most-people" rel="noopener noreferrer"&gt;the editing step is where most people lose&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Is there a 100% accurate AI detector?
&lt;/h2&gt;

&lt;p&gt;No. But some are way more useful than others.&lt;/p&gt;

&lt;p&gt;Every detection tool has false positive problems. A checker that flags real human writing 30% of the time is just noise. The useful ones are calibrated, show sentence-level breakdowns instead of one overall score, and are upfront about confidence levels.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://proofademic.ai/ai-text-detector/" rel="noopener noreferrer"&gt;Proofademic&lt;/a&gt; does sentence-level analysis. You get individual sentences flagged with reasons, not just "40% AI." That matters because "40%" tells you there's a problem somewhere. Sentence-level output tells you it's your intro paragraph and the rest reads clean. You know exactly what to fix.&lt;/p&gt;

&lt;p&gt;For high-stakes assignments, that difference is significant. It also builds a feedback loop over time. You start noticing which sentence structures keep getting flagged and avoid them before you even run detection. That's worth more than any single score.&lt;/p&gt;

&lt;h2&gt;
  
  
  One thing this AI humanizer comparison won't tell you six months from now
&lt;/h2&gt;

&lt;p&gt;Tools change. Most comparison posts skip this part because it makes the whole post feel less definitive.&lt;/p&gt;

&lt;p&gt;A tool that scored well in my tests last semester might not perform the same today. Turnitin updates its detection model. GPTZero updates. The tools that stay useful are the ones doing real structural rewrites and staying current, not tools that gamed one pattern and have been running the same model since.&lt;/p&gt;

&lt;p&gt;I re-run my test paragraph every few months to see if results shifted. Occasionally they do. I wrote about how keeping your voice consistent through this whole process, not just chasing detection scores, is the long-term move in &lt;a href="https://eliotreads.substack.com/p/how-to-make-ai-to-sound-like-human" rel="noopener noreferrer"&gt;how to make AI sound like human&lt;/a&gt;. A tool that outputs structurally different text can still get you flagged if it doesn't sound like you. The detection problem just moves from software to professor.&lt;/p&gt;

&lt;p&gt;The AI humanizer comparison that actually matters isn't which tool scores best on one test. It's which tool is still working in six months, still doing real structural rewrites, and still producing output that doesn't read like a thesaurus ran it. That list stays short.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>reviews</category>
      <category>writing</category>
    </item>
    <item>
      <title>AI for CS Assignments: How I Survive Technical Writing (Without Completely Dreading It)</title>
      <dc:creator>Eliot S</dc:creator>
      <pubDate>Fri, 10 Jul 2026 10:44:03 +0000</pubDate>
      <link>https://dev.to/eliots/ai-for-cs-assignments-how-i-survive-technical-writing-without-completely-dreading-it-3cjl</link>
      <guid>https://dev.to/eliots/ai-for-cs-assignments-how-i-survive-technical-writing-without-completely-dreading-it-3cjl</guid>
      <description>&lt;p&gt;Sophomore year. My algorithms professor dropped a 1,500-word reflection assignment about the ethics of AI in software development on a Monday morning. The class is called Data Structures and Algorithms. There's not supposed to be a reflection assignment. I stared at the prompt for a full minute, confused about what any of it had to do with binary trees, and then I did what I now do for every writing assignment: I opened an AI tool and started talking to it like it was a very patient tutor who could also write.&lt;/p&gt;

&lt;p&gt;I'm a CS student. I'm not bad at school. I'm just bad at writing, and I've stopped pretending that's going to change before I graduate. My brain works in logic, systems, and patterns. Prose is not my thing. Using AI for CS assignments isn't a moral position for me. It's just a time allocation decision, the same way using Stack Overflow to debug is a time allocation decision. I'm not going to build a binary search tree from scratch when documentation exists. I'm not going to write a 1,500-word ethics reflection from scratch when AI exists.&lt;/p&gt;

&lt;p&gt;If you're a CS student who has the same relationship with writing that I do, here's a breakdown of how I approach it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why AI for CS assignments is different from AI for other subjects
&lt;/h2&gt;

&lt;p&gt;The thing nobody tells you before you try this is that AI outputs for technical writing are weirdly inconsistent. I learned this the hard way my freshman year.&lt;/p&gt;

&lt;p&gt;For writing-heavy majors, AI can probably produce a passable essay with minimal editing. For CS writing assignments, that's less reliable. CS professors write prompts that assume you've been paying attention in class. They want you to connect concepts, reference the specific material, and sometimes argue a position using the exact framework they lectured on.&lt;/p&gt;

&lt;p&gt;Generic AI output misses that context completely. I've gotten drafts that were technically correct, coherent, and completely useless because they didn't engage with the actual course content. My professor wanted me to analyze an algorithm design decision using the trade-off framework from week four. The AI gave me a thoughtful general essay about algorithmic complexity. That's not the same thing.&lt;/p&gt;

&lt;p&gt;So the first thing I figured out is that using AI for CS assignments requires you to give it something to work with. A blank prompt gets you a blank-feeling essay. You have to do some upfront work to get useful output.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up AI for CS assignments: the context dump
&lt;/h2&gt;

&lt;p&gt;My process starts with what I call a context dump. Before I write a single word of the actual prompt, I paste in everything relevant: the assignment instructions, any readings or slides the professor referenced, my own notes from class if they're halfway readable, and a rough bullet list of the points I want to make.&lt;/p&gt;

&lt;p&gt;That last part matters more than it sounds. Even if my bullet points are rough and incomplete, having them there shifts the output from generic to specific. The AI is building on my material instead of inventing its own. The result engages with the course content because I gave it the course content.&lt;/p&gt;

&lt;p&gt;For a 1,500-word assignment, my context dump probably takes 20-30 minutes. That's not nothing, but it's way less than writing from scratch, and the output is significantly better.&lt;/p&gt;

&lt;p&gt;Some assignments have less context to work with. Discussion posts, for example, are often just "respond to this question in 200-300 words." Those I treat differently. Less setup, lighter editing. I'm not going to spend 30 minutes preparing for a 200-word discussion post.&lt;/p&gt;

&lt;h2&gt;
  
  
  The actual workflow once you have a draft
&lt;/h2&gt;

&lt;p&gt;Getting a draft is step one. The draft is almost never submittable without editing, and I've gotten into trouble when I treated it like it was.&lt;/p&gt;

&lt;p&gt;The issues I run into consistently are:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tone mismatch.&lt;/strong&gt; AI writes formally. I write casually. My in-class writing samples exist, and professors aren't stupid. If there's a significant style gap between how I write in a timed quiz and how I write in a take-home essay, someone might notice. So I edit for tone first. I cut the academic vocabulary I'd never use and replace it with how I'd phrase things.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Missing specificity.&lt;/strong&gt; Even with a context dump, AI sometimes produces sentences that are technically accurate but vague. "This design decision involves trade-offs between time and space complexity" is not useful. My professor knows that. What they want is for me to say which trade-off, why it matters in this specific context, and what I think about it. I add that layer manually.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Weird paragraph length.&lt;/strong&gt; AI tends to write in uniform paragraph sizes, which looks artificial. I break things up or combine sections based on what makes sense for the argument.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Transition phrases I'd never say.&lt;/strong&gt; "It is worth noting that..." No. I delete these and replace them with something that sounds like me or nothing at all.&lt;/p&gt;

&lt;p&gt;The editing pass takes me maybe 30-40 minutes depending on the assignment. So total time investment for a 1,500-word essay is roughly an hour to an hour and a half. That's still significantly less than writing from scratch, which for me would be three or four miserable hours and a worse result.&lt;/p&gt;

&lt;h2&gt;
  
  
  The detection step
&lt;/h2&gt;

&lt;p&gt;I want to talk about this because it's the part that adds the most anxiety, and I've learned enough about it to be less anxious than I used to be.&lt;/p&gt;

&lt;p&gt;Most universities are using AI detection tools that work by analyzing patterns in text that are statistically associated with AI-generated writing. The tools aren't perfect. They flag human writing sometimes. They miss AI writing sometimes. The threshold matters. A paper that comes back 40% AI-flagged is very different from one that comes back 90% flagged.&lt;/p&gt;

&lt;p&gt;My edited drafts, after the kind of editing I described above, generally come back in a range that doesn't trigger concern. The tone edits and specificity additions change the text enough that the statistical patterns shift. But I still check before I submit anything major, because I'd rather know than not know.&lt;/p&gt;

&lt;p&gt;I wrote more about the mechanics of how detection works &lt;a href="https://eliotreads.substack.com/p/i-actually-looked-into-how-ai-detectors" rel="noopener noreferrer"&gt;in a piece I published a few months ago&lt;/a&gt;. If you want to understand what the tools are doing, that's probably worth reading before you submit something high-stakes.&lt;/p&gt;

&lt;p&gt;The short version is: detection is probabilistic, not certain. A flagged paper is not automatic proof of AI use. An unflagged paper is not a guarantee of safety. The risk is real but it's manageable if you edit seriously.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where AI for CS assignments breaks down
&lt;/h2&gt;

&lt;p&gt;There are assignment types where this workflow doesn't work well, and I've learned to identify them early.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Anything with a specific argument the professor wants.&lt;/strong&gt; If the assignment is "argue for or against position X using the framework from this week's lecture," and I haven't internalized that framework, the AI output is going to be hollow. I can tell. My professor will definitely be able to tell.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Short writing that has to match your in-class voice closely.&lt;/strong&gt; Some professors use short reflections throughout the semester partly to build a record of your writing style. Those are the assignments where the gap between an AI-assisted paper and your natural voice is most visible and most risky.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Anything with citations from sources the professor assigned.&lt;/strong&gt; AI will hallucinate citations with confidence. I've caught it inventing papers that don't exist, inventing page numbers for real papers, and attributing quotes to the wrong author. For anything that requires real citations, I pull the sources myself and verify every single one.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Oral follow-up.&lt;/strong&gt; Some professors ask students to come in and discuss their papers. If you can't talk about what you wrote, that's a bad situation. I make sure I understand everything in the draft before I submit it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using AI for CS assignments beyond coursework
&lt;/h2&gt;

&lt;p&gt;This part I enjoy more than the academic stuff.&lt;/p&gt;

&lt;p&gt;My GitHub READMEs used to be three lines. Project name, what it does, how to run it. That's it. I knew this was bad but I couldn't make myself write more. Now I use the same basic workflow: context dump (the code, what the project does, any interesting technical decisions I made), let the AI draft something, edit for my voice, and publish.&lt;/p&gt;

&lt;p&gt;The result looks like I'm a developer who can explain his own projects. Which is apparently a skill recruiters care about, even though it's not what I thought I was signing up for when I started this degree.&lt;/p&gt;

&lt;p&gt;Same with documentation. I'm working on a side project right now that I want to put in my portfolio, and the docs need to be readable. AI handles the first pass. I handle the part that requires knowing what the code does and why I made specific choices.&lt;/p&gt;

&lt;p&gt;For portfolio work, detection is less of a concern. Nobody's running recruiter AI detectors on GitHub READMEs. But sounding human still matters because a robotic README signals low effort on the one artifact that's supposed to show you off.&lt;/p&gt;

&lt;h2&gt;
  
  
  My take on where this is headed
&lt;/h2&gt;

&lt;p&gt;I think the current cat-and-mouse situation between AI tools and detection tools is going to get more complicated before it gets simpler. Detection is improving. AI output is also improving. Universities are updating their policies semi-regularly, mostly in ways that are inconsistent and hard to keep up with.&lt;/p&gt;

&lt;p&gt;The practical reality for a student right now is that the risk is real but manageable with a serious editing process. The students I've seen get flagged were mostly the ones who ran a bare AI output through submission without editing it. That's not a good strategy.&lt;/p&gt;

&lt;p&gt;I also believe the line between "using AI" and "using any other tool to help you work" is blurry in a way that a lot of institutional AI policies haven't caught up with. I use AI the same way I use syntax highlighters, linters, and autocomplete. It's a tool that makes me faster at a task. The task still requires my judgment, my context, and my editing.&lt;/p&gt;

&lt;p&gt;That's the part that makes AI for CS assignments work when it works. The tool gets you to a draft. The draft is your problem.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>computerscience</category>
      <category>productivity</category>
      <category>writing</category>
    </item>
    <item>
      <title>AI Detector Accuracy Test: I Built a Python Script to Send the Same Essay to 5 Tools at Once</title>
      <dc:creator>Eliot S</dc:creator>
      <pubDate>Wed, 08 Jul 2026 14:06:25 +0000</pubDate>
      <link>https://dev.to/eliots/ai-detector-accuracy-test-i-built-a-python-script-to-send-the-same-essay-to-5-tools-at-once-mbc</link>
      <guid>https://dev.to/eliots/ai-detector-accuracy-test-i-built-a-python-script-to-send-the-same-essay-to-5-tools-at-once-mbc</guid>
      <description>&lt;p&gt;Last semester I pasted the same essay into two detectors back to back and got 82% on one, 31% on the other. No edits. Same paste. Within the same hour.&lt;/p&gt;

&lt;p&gt;I stared at that for a while. Like, which one do I trust? Both? Neither? If I'd only checked one, I'd have a completely different read on my actual situation. That's when I decided manual tab-switching wasn't going to cut it for a real AI detector accuracy test.&lt;/p&gt;

&lt;p&gt;So I spent a Saturday morning building a script. This is that script plus what I found when I actually ran it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I bothered automating the AI detector accuracy test
&lt;/h2&gt;

&lt;p&gt;Honestly, two reasons.&lt;/p&gt;

&lt;p&gt;The boring one first: speed. If you're comparing versions of the same text (raw, edited, humanized), that's five tools times three versions equals fifteen paste jobs. I don't have that kind of patience and I suspect you don't either.&lt;/p&gt;

&lt;p&gt;The less obvious one is that these tools aren't consistent even with themselves. I pasted the same block of text into ZeroGPT twice, no changes at all, and got slightly different numbers. Not dramatically different, but different. If you're anywhere near a threshold that matters, that variance is a problem. Running everything in one script simultaneously at least controls for that. Not a perfect solution, but better.&lt;/p&gt;

&lt;p&gt;For my test I used three versions of the same essay:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Version A:&lt;/strong&gt; Straight from GPT-4o, zero editing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Version B:&lt;/strong&gt; About 20 minutes of hand editing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Version C:&lt;/strong&gt; Processed through a humanizer tool&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The five detectors
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;GPTZero&lt;/strong&gt; — my university writing center literally name-dropped this one in their updated AI policy email. So that's probably what people in my department are running.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Originality.ai&lt;/strong&gt; — has an actual documented API, used a lot in publishing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Winston AI&lt;/strong&gt; — good docs, and you can get per-sentence breakdowns which turns out to be useful&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ZeroGPT&lt;/strong&gt; — free, no account, but I'm using an unofficial endpoint. Could stop working tomorrow, no idea.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Copyleaks&lt;/strong&gt; — handles both AI detection and plagiarism in one go. I'm not implementing it fully here because the OAuth flow adds a bunch of boilerplate that's not really the point of this post.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The code
&lt;/h2&gt;

&lt;p&gt;The main thing is &lt;code&gt;aiohttp&lt;/code&gt; so all four requests fire simultaneously instead of waiting in sequence. Install it first:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;aiohttp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then the full script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;asyncio&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;aiohttp&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;dataclasses&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;dataclass&lt;/span&gt;

&lt;span class="nd"&gt;@dataclass&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DetectionResult&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;        &lt;span class="c1"&gt;# 0.0 = human, 1.0 = AI
&lt;/span&gt;    &lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;

&lt;span class="n"&gt;API_KEYS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gptzero&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;YOUR_GPTZERO_KEY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;originality&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;YOUR_ORIGINALITY_KEY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;winston&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;YOUR_WINSTON_KEY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;ESSAY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Paste your essay text here.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;


&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;check_gptzero&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;aiohttp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ClientSession&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;DetectionResult&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://api.gptzero.me/v2/predict/text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;headers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;x-api-key&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;API_KEYS&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gptzero&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Content-Type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;application/json&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Accept&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;application/json&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;document&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;multilingual&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;documents&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;completely_generated_prob&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;DetectionResult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tool&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GPTZero&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;Exception&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;DetectionResult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tool&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GPTZero&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;


&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;check_originality&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;aiohttp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ClientSession&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;DetectionResult&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://api.originality.ai/api/v1/scan/ai&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;headers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;X-OAI-API-KEY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;API_KEYS&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;originality&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Content-Type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;application/json&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;aiModelVersion&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;DetectionResult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tool&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Originality.ai&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;score&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ai&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;Exception&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;DetectionResult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tool&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Originality.ai&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;


&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;check_winston&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;aiohttp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ClientSession&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;DetectionResult&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://api.gowinston.ai/functions/v1/predict&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;headers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Authorization&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Bearer &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;API_KEYS&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;winston&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Content-Type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;application/json&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;sentences&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;DetectionResult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tool&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Winston AI&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;score&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;Exception&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;DetectionResult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tool&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Winston AI&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;


&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;check_zerogpt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;aiohttp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ClientSession&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;DetectionResult&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# unofficial — may break at any time
&lt;/span&gt;    &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://api.zerogpt.com/api/detect/detectText&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;headers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Content-Type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;application/json&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;input_text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;fakePercentage&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;DetectionResult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tool&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ZeroGPT&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;Exception&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;DetectionResult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tool&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ZeroGPT&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;


&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;run_all_detectors&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;DetectionResult&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;aiohttp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ClientSession&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;tasks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="nf"&gt;check_gptzero&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="nf"&gt;check_originality&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="nf"&gt;check_winston&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="nf"&gt;check_zerogpt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;asyncio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;gather&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;print_results&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;DetectionResult&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;version_label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Version: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;version_label&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Tool&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Score&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;  &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Verdict&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;-&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;44&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;sorted&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;reverse&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tool&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;ERROR&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;  &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;pct&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;
            &lt;span class="n"&gt;verdict&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AI&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;pct&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Human&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
            &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tool&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;pct&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="mf"&gt;7.1&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;%  &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;verdict&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;versions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Version A (raw GPT-4o output)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ESSAY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="c1"&gt;# swap in your other versions:
&lt;/span&gt;        &lt;span class="c1"&gt;# "Version B (light edits)": ESSAY_B,
&lt;/span&gt;        &lt;span class="c1"&gt;# "Version C (humanized)":   ESSAY_C,
&lt;/span&gt;    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;versions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;items&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;asyncio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;run_all_detectors&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="nf"&gt;print_results&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Version A output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;==================================================
Version: Version A (raw GPT-4o output)
==================================================
Tool                     Score     Verdict
--------------------------------------------
Originality.ai          94.0%          AI
Winston AI              88.0%          AI
GPTZero                 81.0%          AI
ZeroGPT                 74.0%          AI
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  AI detector accuracy test results across all three versions
&lt;/h2&gt;

&lt;p&gt;Here's what I got:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Version A — Raw GPT-4o:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Originality.ai: 94%&lt;/li&gt;
&lt;li&gt;Winston AI: 88%&lt;/li&gt;
&lt;li&gt;GPTZero: 81%&lt;/li&gt;
&lt;li&gt;ZeroGPT: 74%&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Version B — Lightly edited by hand:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Originality.ai: 71%&lt;/li&gt;
&lt;li&gt;Winston AI: 62%&lt;/li&gt;
&lt;li&gt;GPTZero: 58%&lt;/li&gt;
&lt;li&gt;ZeroGPT: 43%&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Version C — Humanized:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Originality.ai: 31%&lt;/li&gt;
&lt;li&gt;Winston AI: 28%&lt;/li&gt;
&lt;li&gt;GPTZero: 24%&lt;/li&gt;
&lt;li&gt;ZeroGPT: 19%&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Version A spread killed me a little. 74% to 94% on the exact same raw GPT-4o output. That range matters because schools draw the line in different places: 80% at some institutions, 50% at others, 60% at others depending on who wrote the policy that week. You can pass one bar and fail another on the same document.&lt;/p&gt;

&lt;p&gt;Version B was the disappointing one. I actually put time into those edits — went through every paragraph, tried to break up the cadence, cut some sentences, added my own phrasing. Still got flagged by three out of four. ZeroGPT was the only one that dipped under 50%. Twenty minutes of editing barely moved Originality.ai. Wasn't expecting that.&lt;/p&gt;

&lt;p&gt;Version C passed everything. Still a 12-point spread (19% to 31%) but well below any real threshold. The variance didn't disappear though. These four tools are clearly measuring different things.&lt;/p&gt;

&lt;h2&gt;
  
  
  Most accurate AI detector 2026: what I actually found
&lt;/h2&gt;

&lt;p&gt;Nobody's running away with this. That's the honest take from my data and the benchmarking stuff I've read elsewhere.&lt;/p&gt;

&lt;p&gt;If I had to pick one for catching raw, unedited AI output: Originality.ai. It came in highest on Version A by a margin and was the last to budge as I edited. But that aggression is a double-edged thing. I've seen it flag heavily stylized human writing that just happens to be formal and structured. If you're testing a student paper from someone who writes in a clean, academic style, I'd double-check with a second tool before acting on that result.&lt;/p&gt;

&lt;p&gt;GPTZero was the most relaxed. Lowest false positive rate of the four, which probably reflects how it was designed. Specifically for academic submissions where wrongly flagging a real student is a much bigger deal than missing a borderline AI piece. Catches less, but what it catches it's more confident about.&lt;/p&gt;

&lt;p&gt;Winston AI landed somewhere in between. Comparable to GPTZero on raw output but less aggressive on edited text. Per-sentence view is genuinely handy if you want to see which paragraphs pushed the needle instead of just getting a single number and guessing.&lt;/p&gt;

&lt;p&gt;ZeroGPT? All over the place. Free, no sign-up required, which is why it's everyone's first stop. But the variance makes it basically useless for anything where the stakes are real.&lt;/p&gt;

&lt;p&gt;The question "most accurate AI detector 2026" kind of assumes there's a right answer. There isn't. High detection sensitivity and low false positive rate pull in opposite directions. You're always trading one for the other.&lt;/p&gt;

&lt;h2&gt;
  
  
  AI detector comparison: why the same text scores differently
&lt;/h2&gt;

&lt;p&gt;When I first saw the results I thought one of the tools had to be wrong. But that's not really how this works.&lt;/p&gt;

&lt;p&gt;These things aren't running the same model. Some are built around perplexity and burstiness, meaning how predictable the word choices are and how uniform the sentence lengths are. GPT-4o output is low-perplexity almost by definition. The model is trained to pick the most probable next token, which makes the text statistically smooth in ways human writing isn't. We're messier. We change our minds mid-sentence, pick words for rhythm, write shorter when tired.&lt;/p&gt;

&lt;p&gt;Other tools look at semantic patterns instead — whether the writing hedges, goes off-topic, self-corrects, circles back. That stuff shows up in human writing because we're thinking while typing. AI generates from a prompt in one pass and has no reason to qualify or digress.&lt;/p&gt;

&lt;p&gt;So this AI detector comparison isn't really about which tool is better. Originality.ai weights semantic signals more heavily, which is why it nails raw output but sometimes overcorrects on human writing that's direct and well-structured. GPTZero's calibration is different because it was trained on a different population of text.&lt;/p&gt;

&lt;p&gt;Paste the same essay into four tools, get four different scores — you're probably looking at genuinely borderline content. That's not a calibration error. That's what the gray zone looks like.&lt;/p&gt;

&lt;h2&gt;
  
  
  Can Turnitin detect ChatGPT?
&lt;/h2&gt;

&lt;p&gt;Yes. And it's not in this script, which is the more important part.&lt;/p&gt;

&lt;p&gt;Turnitin launched their AI detection feature in April 2023. Updated a few times since. Covers ChatGPT, Claude, Gemini, and the usual suspects. Their own published figures say something like 98% accuracy on unedited AI output and a 1% false positive rate on human writing. Take self-reported numbers with appropriate skepticism, but they're probably in the right ballpark.&lt;/p&gt;

&lt;p&gt;It's not in this script because there's no public API. Their detection is baked into the submission pipeline. Canvas, Blackboard, whatever LMS your school uses. The only way to test against Turnitin is to actually submit.&lt;/p&gt;

&lt;p&gt;I found this out the hard way. Ran something through this script, got a 22% on GPTZero, submitted it, got a 71% back from Turnitin. That was a bad day. Their model has context I don't — submission history, cross-comparison patterns, document metadata. It's doing something different from the external tools. Pre-checking with this script is still worth it, but a clean result here is not a Turnitin guarantee.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this AI detector accuracy test tells you (and what it doesn't)
&lt;/h2&gt;

&lt;p&gt;The main thing: one tool isn't enough. The variance is too wide to make decisions from a single number.&lt;/p&gt;

&lt;p&gt;Four tools all flagging high? Real signal. The text is probably still close to raw output and needs more work. Four tools splitting 50/50? Genuine gray zone, and your actual risk depends on which specific tool is running on the other end.&lt;/p&gt;

&lt;p&gt;The script is good for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cross-checking whether something is flagging consistently&lt;/li&gt;
&lt;li&gt;Seeing how sensitive different detectors are to the specific edits you're making&lt;/li&gt;
&lt;li&gt;Cutting the manual tab-switching down to one function call&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The editing and humanization side — what actually moves scores — is a longer topic. I went into it on my Substack, specifically &lt;a href="https://eliotreads.substack.com/p/the-editing-step-is-where-most-people" rel="noopener noreferrer"&gt;the part of the process most people skip entirely&lt;/a&gt;, which is also why a lot of people are still getting flagged even after running their text through a humanizer once.&lt;/p&gt;

&lt;p&gt;The script above is minimal by design. Per-sentence Winston output, Copyleaks integration, and CSV batch logging are reasonable things to bolt on if you need them.&lt;/p&gt;

</description>
      <category>ai</category>
    </item>
  </channel>
</rss>
