惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

有赞技术团队
有赞技术团队
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
P
Palo Alto Networks Blog
C
Cisco Blogs
The Hacker News
The Hacker News
T
Threatpost
S
Schneier on Security
K
Kaspersky official blog
Spread Privacy
Spread Privacy
博客园_首页
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
NISL@THU
NISL@THU
量子位
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Google DeepMind News
Google DeepMind News
Security Latest
Security Latest
博客园 - 司徒正美
云风的 BLOG
云风的 BLOG
博客园 - 叶小钗
H
Hackread – Cybersecurity News, Data Breaches, AI and More
N
News and Events Feed by Topic
爱范儿
爱范儿
P
Proofpoint News Feed
C
CERT Recently Published Vulnerability Notes
Project Zero
Project Zero
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Cisco Talos Blog
Cisco Talos Blog
GbyAI
GbyAI
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Apple Machine Learning Research
Apple Machine Learning Research
T
Tenable Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
V
Vulnerabilities – Threatpost
Forbes - Security
Forbes - Security
博客园 - 三生石上(FineUI控件)
C
Cyber Attacks, Cyber Crime and Cyber Security
N
News and Events Feed by Topic
V
V2EX
Webroot Blog
Webroot Blog
The Register - Security
The Register - Security
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
阮一峰的网络日志
阮一峰的网络日志
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Blog — PlanetScale
Blog — PlanetScale
M
MIT News - Artificial intelligence
Scott Helme
Scott Helme
Simon Willison's Weblog
Simon Willison's Weblog
L
LangChain Blog
W
WeLiveSecurity
Cloudbric
Cloudbric

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python) The Hidden Cost of AI Systems Nobody Talks About. undefined vs undeclared, and how typeof behaves Switching from file-based jobs to NATS/Kafka in Rust without changing code io_uring Adventures: Rust Servers That Love Syscalls Why Agentic AI is Killing the Traditional Database The POUR principles of web accessibility for developers and designers Quantum Neural Network 3D — A Deep Dive into Interactive WebGL Visualization How To Install Caveman In Codex On macOS And Windows Automation Pipeline Reliability: Why Your Workflow Breaks When Nobody Is Watching I Built an 'Open World' AI Coding Agent — It Works From ANY Folder From Freelancing to Product: A Tech Service Company's SaaS Transformation China's AI Giants: Adding Tencent Hunyuan & ByteDance Doubao to AI University (74 Providers) On the Vibe Coders and Their Lies clerk: Auto-Summarize Your Claude Code Sessions AI Weekly — 2026/04/10–04/17 | The Model Lockdown Is Here, but the Toolchain Is the Real Battleground AI 週報 — 2026/04/10–2026/04/17 模型封鎖潮來了,但工具鏈才是真戰場 Maybe this is how Open-Source apps are born... 🚀 Fine-Tune LLMs with LoRA and QLoRA: 2026 Guide tRPC v11 + Next.js App Router: End-to-End Type Safety Without the Boilerplate ShadCN UI in 2026: Why I Stopped Installing Component Libraries and Started Owning My Components SaaS Billing in React Server Components: Stripe + Supabase Without a Single `useEffect` Join our DEV Weekend Challenge — $1,000 in Prizes Across TEN winners! Submissions Due April 20 at 6:59 AM UTC. Implementing FSRS Spaced Repetition in Flutter + Supabase — Adding Memory Science to an AI Learning App "I Texted My Localhost From the Train — Claude Code Fixed the Bug Before I Got Home" I Built a Sales Prep AI and It Went Deeper Than Expected Design to Code #2: One JSON, Eleven Outputs Solving the 100M-Row Problem: A Summary Table Pattern for High-Volume Push Notification Logs Flutter Web With Wasm: What Actually Changes For Developers I Built 50 Royalty-Free Soundtracks for My Side Project in a Weekend Using AI Music Generation The Vibe Coding Security Checklist: 7 Things to Check Before You Ship Stop Letting Googlebot Guess Fix Your React App's SEO Right Desconstruindo o Streaming do LinkedIn: Como Criar um Engine de Extração de Vídeo de Alta Performance com HLS e FFmpeg (EDA Part-1) EDA (Exploratory Data Analysis) Explained With Real Life — Why Looking at Your Data Is the Most Important Step in Machine Learning Brand Relationship Management at Scale: Our 4-Touch Outreach System for 200+ Brands Why String.fromEnvironment() Might Return an Empty String in Dart JGuardrails 1.0.0 — Hardening Java LLM Apps Against Jailbreaks, Toxicity, and Prompt Injection Plan and Schedule a Full Week of Threads Content From One Claude Conversation Coding Cat Oran Ep3, Five Tables Changed Everything Updated: BFF Pattern I'm done watching freelancers get buried by 200 proposals. So I'm building the alternative. This is my first post BFS Algorithm in Java Step by Step Tutorial with Examples Tracking LLM Pricing Monthly: An Open Dataset for 22 AI Models How We Measure Content ROI on a Comparison Site: Revenue Attribution Without Perfect Data Introducing Nova AI Ops: The AI-Native Operating System for SRE Teams I built a free desktop video downloader for Windows — Grabbit How Talkie OCR Helps Vision-Impaired & Dyslexic Users Read the World Around Them VRCFaceTracking安装和iPhone面捕配置教程,有bug Even CrowdStrike Can't See Your Agents The Automation Gold Rush: What n8n Workflows and Claude Are Opening Up for Developers Right Now
Testing GLM-5.2 on OpenCode: I'm impressed!
Daniel Bergholz · 2026-06-18 · via DEV Community

I have a confession: I roll my eyes at AI benchmarks. Every other week someone on Twitter posts a chart where a brand new model is suddenly beating Opus and GPT, the replies go crazy, and then you actually use the thing and it falls apart on the first real task. Beautiful numbers, ugly code.

So when z.ai shipped GLM 5.2 and the timeline started shouting that an open-weights model was now nipping at the heels of the frontier labs, my instinct was the usual one. Sure. Prove it.

This post is me proving it. I gave GLM 5.2 a real feature to build on my actual production website, with almost no hand-holding, and watched what happened. Spoiler: I was not expecting to write the sentence I ended up writing.

If you'd rather watch me run the whole thing live (including the part where my tools crashed on camera), the video is right here:

The claims I was here to test

Let's get the hype out of the way first, because the claims are genuinely big.

GLM 5.2 is the same physical size as GLM 5.1 (744B total parameters, 40B active), but on the Artificial Analysis Intelligence Index it jumped 11 points, from 40 to 51. That score makes it the leading open-weights model, ahead of MiniMax-M3 (44), DeepSeek V4 Pro (44) and Kimi K2.6 (43). On the overall leaderboard it sits behind only Claude Fable 5 (60), Claude Opus 4.8 (56) and GPT-5.5 (55). For an open, MIT-licensed model you can download the weights for, that is a wild place to be.

Here is the upgrade at a glance:

GLM 5.1 GLM 5.2
Intelligence Index (v4.1) 40 51
Context window 200K 1M
Total / active params 744B / 40B 744B / 40B
Output tokens per task 26k 43k
Cost per task ~$0.25 ~$0.46
Price (in / cache / out per 1M) $1.4 / $0.26 / $4.4 $1.4 / $0.26 / $4.4
License MIT MIT

Two things jump out. First, the context window went from 200K to a full 1 million tokens, which matters a lot for agentic coding where the harness stuffs your whole repo into the prompt. Second, the price did not move at all. Same cost as 5.1, 11 points smarter.

That last row in the table is also the explanation for a complaint you'll see online, and I'll come back to it. Numbers on a chart are one thing. Let's go build something.

My setup: OpenCode plus OpenRouter

For the harness I used OpenCode, the desktop app, which has become my go-to playground for trying models that aren't Claude. For the model itself I routed through OpenRouter.

Why OpenRouter and not OpenCode's own provider? Honestly, a small gripe: OpenCode Zen and the Go subscription have been slow to add new open-weights models. GLM 5.2 wasn't on either yet on the day I recorded. OpenRouter had it on day one, so that's where I went. If you want the model, OpenRouter is the path of least resistance right now.

One note for the regulars here: I'm normally a Claude Code person. I pay for Claude Max and I've said many times on this channel that it's the best agent out there. So this isn't a "Claude is bad" video. It's me, a Claude loyalist, genuinely curious whether an open model can hang.

The test: a real feature on my real site

No toy to-do app. The target was bergdaniel.com.br, my personal website. It's a fully server-rendered Next.js app where, at build time, I hit the dev.to API to populate my blog page and the YouTube API to populate my courses page. Nothing fancy, but it's real code that's actually deployed.

My blog list has grown enough that I wanted a search box. So that was the task. And here's the important part for a model review: I deliberately gave it almost no context. No "by the way, we don't have a database," no "remember this is server-rendered with ISR." I wanted to see whether the model would figure out the constraints on its own or trip over them.

This was the entire prompt:

Help me implement a search feature on the blog page. If possible, use query params and URL state for the search. Example: ?q=. Whenever the user types something on the search, no need to build an explicit submit button, use debounced searches after waiting like 300 milliseconds.

Then I switched on plan mode and hit submit. The honest test of an agent isn't whether it can follow a spec. It's what it does when the spec is vague.

Plan mode actually surprised me

GLM 5.2 is a slower, more deliberate model than the other open-weights options. I'd noticed that the day before. But I'll take a slow model that one-shots the feature over a fast one I have to argue with, so I let it think.

First it researched the codebase and reported back, correctly, that my blog page is a server component calling getArticles, regenerated with ISR every twelve hours. Then it proposed the plan: keep the page as a server component, add a new client component for the search, debounce each keystroke 300ms, then run a replace on the URL so we don't pollute browser history on every letter. Clear X button to reset, empty state when nothing matches.

But the part that got me was the reasoning. It explained, unprompted, why it chose client-side filtering:

Articles are already fetched at build time. Doing the filter client side keeps ISR intact, avoids an extra fetch per keystroke, and lets the URL state be the single source of truth.

That's exactly right. That's the trap I was hoping to watch it fall into, querying the dev.to API on every keystroke at runtime, and it sidestepped it without me saying a word about ISR. It even knew to wrap the component in a Suspense boundary because useSearchParams requires it in Next.js. This is the kind of thing I expect from Opus, not from a model I downloaded the weights for.

Then it did something only the frontier models usually do: it asked me good questions before writing code.

  • When a search is active, how should the "New" badge behave? (Hide while searching / keep on the first match / always on the latest)
  • Which fields should search match against? (Title, description, and tags (recommended))
  • What shows when nothing matches? (A "No articles found" message (recommended))

See that (recommended) in the options? That's a Claude move. When I talk to Claude models, they almost always mark a recommended choice in parentheses, and it's genuinely useful. Watching GLM do the same, with sensible defaults, was the moment I sat up.

mind blown

The code it actually wrote

Talk is cheap, so here's the real output. This is the code that's deployed on my site right now, copied straight from the repo.

First, the change to the blog page. It stayed a server component, kept the ISR revalidation, and just handed the articles off to the new search component:

// src/app/blog/page.tsx
import type { Metadata } from "next"

import { BlogSearch } from "@/components/blog-search"
import { getArticles } from "@/data-access/blog"

export const metadata: Metadata = {
  title: "Blog | Daniel Bergholz",
  description: "Daniel Bergholz's blog"
}

export const revalidate = 43200 // 12 hours (twice a day)

export default async function Blog() {
  const articles = await getArticles()

  return (
    <main className="my-14 md:my-28 flex flex-col gap-5 max-w-5xl mx-auto">
      <h1 className="font-serif text-3xl md:text-4xl italic tracking-tight">
        Blog
      </h1>
      <hr className="w-12 border-t border-current opacity-20" />
      <BlogSearch articles={articles} />
    </main>
  )
}

Then the new client component. Notice the matches helper that searches across title, description, and tags exactly like I asked, the 300ms debounce, the router.replace with scroll: false, and the Suspense wrapper at the bottom:

// src/components/blog-search.tsx
"use client"

import { useRouter, useSearchParams } from "next/navigation"
import { Suspense, useEffect, useRef, useState } from "react"

import { Article } from "@/components/article"
import type { Article as ArticleType } from "@/lib/types"

function matches(article: ArticleType, query: string): boolean {
  const q = query.trim().toLowerCase()
  if (!q) return true
  const haystack = [article.title, article.description, ...(article.tag_list ?? [])]
    .filter(Boolean)
    .join(" ")
    .toLowerCase()
  return haystack.includes(q)
}

function BlogSearchInner({ articles }: { articles: ArticleType[] }) {
  const router = useRouter()
  const searchParams = useSearchParams()
  const queryFromUrl = searchParams?.get("q") ?? ""

  const [inputValue, setInputValue] = useState(queryFromUrl)
  const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null)

  const updateUrl = (value: string) => {
    const params = new URLSearchParams(searchParams?.toString() ?? "")
    if (value.trim()) {
      params.set("q", value.trim())
    } else {
      params.delete("q")
    }
    const queryString = params.toString()
    router.replace(queryString ? `/blog?${queryString}` : "/blog", {
      scroll: false
    })
  }

  const handleChange = (value: string) => {
    setInputValue(value)
    if (debounceRef.current) clearTimeout(debounceRef.current)
    debounceRef.current = setTimeout(() => {
      updateUrl(value)
    }, 300)
  }

  const isSearching = inputValue.trim().length > 0
  const filtered = isSearching
    ? articles.filter((article) => matches(article, inputValue))
    : articles

  return (
    <div className="flex flex-col gap-5">
      <SearchInput value={inputValue} onChange={handleChange} />
      {filtered.length === 0 ? (
        <p className="opacity-50 text-sm md:text-base">
          No articles found for &ldquo;{inputValue.trim()}&rdquo;.
        </p>
      ) : (
        <div className="flex flex-col gap-4">
          {filtered.map((article, index) => (
            <Article
              key={article.id}
              article={article}
              newPost={!isSearching && index === 0}
            />
          ))}
        </div>
      )}
    </div>
  )
}

export function BlogSearch(props: { articles: ArticleType[] }) {
  return (
    <Suspense fallback={null}>
      <BlogSearchInner {...props} />
    </Suspense>
  )
}

I trimmed the SearchInput sub-component and a couple of effects out of the snippet above so it stays readable, but everything you see is the model's actual code, untouched. The newPost={!isSearching && index === 0} line is the answer to its own "New badge" question: hide the badge while searching, show it on the latest post otherwise. It wired its own design decision straight into the JSX.

Design-wise, it matched the rest of my site without being told what the site looks like. Same border treatment, same spacing, same muted opacity. When I tested it, typing "Elixir", "React", "Fable", it filtered instantly, and pasting /blog?q=fable straight into the address bar worked too. URL state as the single source of truth, exactly as planned.

The part I didn't expect to like: restraint

After it finished, I ran npm run check and there were a couple of lint warnings. But here's the thing: the warnings were in my Tidewave proxy files, code GLM never touched. And its response was basically, "the one remaining warning is preexisting and unrelated to my changes, so I left it alone."

Some developers will hate that. They want the agent to fix everything it sees. I'm the opposite. If a model starts proactively rewriting files I didn't ask it to touch, that's how you get a 40-file diff for a one-component feature and a code review that takes longer than writing it yourself would have. GLM drew the line exactly where I'd draw it: change what I asked for, run format, check the build, and leave the rest of the repo alone.

For context, my AGENTS.md on this repo has a hard rule:

**IMPORTANT**: After making any code changes, always run:
1. `npm run format` - Format the code
2. `npm run check` - Verify no linting or type errors
3. `npm run build` - Verify the production build succeeds

GLM followed it to the letter. It formatted, it checked, it built, and it stopped. That's an agent reading its instructions and respecting their boundaries, which is harder than it sounds.

Then OpenCode crashed

Now for the honest part, because I'm not going to pretend the run was flawless. Right after I asked it to clean up the commits, OpenCode froze and threw a JavaScript error in the main process. The whole app went down on camera.

facepalm

To be clear, that's an OpenCode problem, not a GLM 5.2 problem. The model's work was fine. The harness around it fell over. I relaunched, my changes were still there (just not pushed yet), and I pushed them up to deploy. Annoying, but the kind of thing that happens with fast-moving tools, and worth showing instead of editing out.

The built-in review caught something real

OpenCode ships a /review command that spins up a code-reviewer sub-agent. I pointed it at the commit GLM had made and let it go.

It found no bugs, which matches my read of the code, but it did flag two minor things: a subtle input drift while typing, and an acceptable flash on deep links. The input drift was real. The URL-sync effect was re-setting the input from the trimmed URL value about 300ms after each keystroke, which could strip trailing whitespace under your cursor. GLM fixed it cleanly:

// src/components/blog-search.tsx  (the fix)
// Keep input in sync when navigating back/forward. Skip when the URL already
// reflects the current input (e.g. trailing whitespace stripped on write) so
// the visible value doesn't shift under the cursor mid-typing.
useEffect(() => {
  if (queryFromUrl === inputValue.trim()) return
  setInputValue(queryFromUrl)
}, [queryFromUrl])

One thing worth flagging if you try this: GLM is eager to commit. The moment I used the word "commit" once, it started committing every subsequent change on its own, which isn't my default preference. I like the model to wait for my go-ahead. But to be completely fair, Claude and Codex do the exact same thing once you mention committing, so I can't single GLM out for it. At least it didn't push without asking.

So, is it actually worth it?

Remember that "43k output tokens per task" row in the table up top? That's the answer to everyone calling GLM 5.2 slow. It isn't slow because it's weak, it's slower because it thinks more: 43k output tokens per task versus 26k for GLM 5.1 and 24k for MiniMax-M3. You're paying in latency for more reasoning. After watching the plan it produced, I'll take that trade. A model that one-shots the feature after thinking for an extra minute beats a fast model I have to correct three times.

And the cost? This is the part I forgot to mention in the video, and it might be the most convincing number in the whole post: the entire session, the planning, the implementation, the code review, and the fix, cost me $0.265. That is not a typo. Twenty-six cents to ship a real feature to production. Artificial Analysis has GLM 5.2 on the Pareto frontier of intelligence versus cost, and this is what that looks like once you stop reading charts and actually build something. For an open, MIT-licensed model whose weights you can run yourself, that is hard to argue with.

bargain

Here's the sentence I didn't expect to write: this is the first time an open-weights model has genuinely impressed me on real code. Not "good for an open model." Just good. The code quality was there, the architectural instincts were there, the questions it asked were the right ones, and the speed felt close to Claude, maybe even a touch faster. From this one feature, GLM 5.2 gets my stamp of approval. I'm genuinely happy we have an open model at this level: competition is good, open weights are good, and a model you can self-host writing Next.js code this clean is a great sign for where this is all heading.

If you want to try it yourself: grab OpenCode, point it at OpenRouter, select GLM 5.2, and give it a real task instead of a benchmark. The z.ai docs have the rest of the details.

If you made it all the way down here, you're awesome, thank you for reading. Let me know in the comments whether you've tested GLM 5.2 and whether it impressed you as much as it impressed me. See you in the next one.

the end