今日已更新 240 条资讯 | 累计 23823 条内容
关于我们

标签:#tutorial

找到 437 篇相关文章

AI 资讯

**# 🐛 The Bug That Made Me Stop Blaming Python**

# 🐛 The Bug That Made Me Stop Blaming Python "The computer wasn't confused. I was." I still remember the moment. I had just started learning Python. Every new concept felt exciting. Every successful program made me believe I was getting closer to becoming a real developer. Then I met my first bug. It wasn't a complicated algorithm. It wasn't artificial intelligence. It wasn't even a project. It was a simple countdown. "Print the numbers from 5 to 1." That sounded easy enough. So I wrote this: count = 5 while count > 0 : print ( count ) I pressed Run . For a split second, everything looked normal. Then the terminal kept printing. 5 5 5 5 5 5 ... It never stopped. My first thought was that VS Code had frozen. Then I wondered if Python was broken. Maybe I'd installed something incorrectly. Maybe my laptop was the problem. I restarted everything. Nothing changed. Finally, I stopped blaming the tools and started reading my own code. That's when I noticed something embarrassingly simple. I was asking Python the same question over and over again: Is count greater than zero? The answer was always yes . Because I had never told Python to change count . Not once. The computer wasn't making a mistake. It was following my instructions perfectly. The fix took one line. count = 5 while count > 0 : print ( count ) count -= 1 I ran it again. 5 4 3 2 1 Done. One line. One lesson I'll probably never forget. That day changed how I think about programming. Before, I believed debugging meant finding what the computer had done wrong. Now I know debugging usually means discovering what I told the computer to do. Computers don't guess. They don't assume. They don't fill in missing logic. They execute instructions exactly as they're written. If the result is wrong, the first place I look isn't Python anymore. It's my own thinking. I'm still a beginner, and I know much harder bugs are waiting for me. But strangely, I'm looking forward to them. Because every bug teaches something that no tuto

2026-07-16 原文 →
AI 资讯

How to Build a Semantic Search Engine for E-Commerce in Python

Building a semantic search engine for an e-commerce catalogue doesn't require a team of PhDs or a six-figure cloud budget. In this tutorial, I'll walk you through a production-ready pipeline using open-source tools: sentence-transformers for embedding, FAISS for vector indexing, and FastAPI for serving. The core insight is that semantic search isn't magic — it's just good engineering wrapped around a pre-trained language model. We'll start by setting up a product embedding pipeline that transforms your catalogue (title, description, category, attributes) into dense vectors. The key architectural decision is whether to embed each product as a single vector or to use late interaction models like ColBERT that preserve token-level detail. For most e-commerce use cases with fewer than 1 million SKUs, single-vector embedding with sentence-transformers' all-MiniLM-L6-v2 offers the best balance of speed and accuracy. The entire indexing pipeline — from CSV export to queryable vector index — runs in under 100 lines of Python. The re-ranking layer is where most tutorials stop and real-world systems begin. Pure vector similarity doesn't understand your business: it doesn't know that out-of-stock items should be deprioritised, that high-margin products should float up, or that a customer's purchase history should influence results. I'll show you how to build a hybrid scoring function that blends semantic relevance (cosine similarity), business rules (margin, inventory), and personalisation signals (user embedding) into a single ranked result set that returns in under 100ms. Canonical: https://alteglobal.ai/insights/ecommerce-ai-automation-personalisation-fulfillment/

2026-07-16 原文 →
AI 资讯

I Built a Free AI Photo Transformer — 50+ Styles, No Signup Required

I wanted to play with AI image generation without paying for Midjourney or dealing with Discord bots. So I built SnapShift — a free web tool that transforms photos into artwork in seconds. What it does: Upload any photo (portrait, pet, landscape, product) Pick from 50+ styles — cyberpunk, anime, oil painting, Ghibli, movie posters, 3D figurines, and more Download in 1K or 2K quality No signup, no limits, completely free Tech stack: static site on GitHub Pages, AI generation via Agnes API with Cloudflare Worker proxy. Try it: https://snapshit.fun Would love to hear what other styles you'd like to see!

2026-07-16 原文 →
AI 资讯

Don't apply WordPress major releases on day one — the "x.0.1 rule" and a calibration framework

The companion to the seven things to check before a WordPress major upgrade is the question that comes right after: when do you actually apply it? A new WordPress major drops today. Do you ship it to production tonight? Tomorrow? In a week? Hold for the next scheduled monthly maintenance? This call tends to live in tribal knowledge, but a few clear axes combined together give you a calibration framework you can apply every time without re-deciding from scratch. Here are five axes worth using. Premise — majors are not security patches The first thing to anchor: a major upgrade is not a security patch . WordPress ships security fixes via minor releases ( 6.4.1 → 6.4.2 , 6.5.0 → 6.5.1 — the second-digit bumps ). Those are same-day apply by default . Major releases ( 6.4 → 6.5 , eventually some 6.x → 7.0 ) carry new features and API changes; they aren't released to be applied immediately for security reasons. Without this distinction, the felt urgency of " we have to apply this for security " pushes you to rush majors that should wait. Minors immediately, majors by judgment — that separation is the first rule worth writing down. Axis 1 — wait for x.0.1 For essentially every major release, x.0.1 (the first patch release) lands within 1–3 weeks and absorbs the critical bugs that surfaced after launch. Past examples have included things like "the admin goes white under specific settings," "a particular theme breaks the block editor," "DB migration stalls in specific environments." Nobody hit these on launch day; they emerged as the world started using it for days or weeks. Just waiting for x.0.1 instead of x.0 sidesteps most of those launch-window bugs. For the first few weeks after a major lands, the world's WordPress installations are effectively running the beta test . Being downstream of the people who hit the mines is the rational position for a maintenance practice. Axis 2 — wait until major plugin vendors update "Tested up to" The thing that breaks most after a majo

2026-07-16 原文 →
AI 资讯

Your Codex model shuts off July 23 — a 7-day migration map

I pin model IDs on purpose. Floating aliases have burned me before — a silent swap under a -latest tag once changed a tool-calling detail in production and cost me a Saturday with git bisect and a coffee I didn't enjoy. So everything I run points at a dated snapshot. gpt-5-codex was one of them. Last week I finally read OpenAI's deprecations page top to bottom instead of skimming it, and there it was: gpt-5-codex , retiring 2026-07-23 , sitting quietly next to ten of its neighbors. As I write this it's July 16. That's seven days . If you pinned any of the snapshots below, consider this your heads-up. Here's the full retirement list, how to find out in about ten minutes whether you're exposed, the replacement map with the things I'd actually regression-test, and the one structural change that turned my last forced migration from scary into boring. The shutdown list (retiring 2026-07-23) Straight from OpenAI's API deprecations page . I checked each row against the source while writing this — do the same before you act on it, because dates and replacements do get revised. Retiring model OpenAI's suggested replacement gpt-5-codex gpt-5.5 gpt-5.1-codex gpt-5.5 gpt-5.1-codex-max gpt-5.5 gpt-5.1-codex-mini gpt-5.4-mini gpt-5.2-codex gpt-5.5 gpt-5-chat-latest gpt-5.5 gpt-5.1-chat-latest gpt-5.5 gpt-4o-search-preview-2025-03-11 gpt-5.4-mini gpt-4o-mini-search-preview-2025-03-11 gpt-5.4-mini gpt-4o-mini-tts-2025-03-20 gpt-4o-mini-tts-2025-12-15 computer-use-preview-2025-03-11 computer-use-preview (or gpt-5.4-mini ) Note the shape of it: the *-codex line collapses into gpt-5.5 — except gpt-5.1-codex-mini , which drops to gpt-5.4-mini — the chat-latest aliases fold into gpt-5.5 too, the two *-search-preview snapshots move to gpt-5.4-mini , and the two preview families ( tts , computer-use ) just roll to a newer dated snapshot / the undated alias. Once you see the buckets, the migration is less intimidating than the eleven-row table looks. Find out if you're exposed (about ten m

2026-07-16 原文 →
AI 资讯

How to Automate SEO Content Publishing Without Breaking Your Workflow

How to Automate SEO Content Publishing Without Breaking Your Workflow Managing SEO content at scale is one of those problems that looks simple until you're staring at a spreadsheet of 200 articles in various stages of draft, review, and scheduled publication — and you still have to manually paste metadata into WordPress, set canonical tags, and remember which pieces need internal links updated. Automating SEO content publishing means connecting your content pipeline — from keyword targeting through final scheduling — into a repeatable system where the manual handoffs disappear. The short version: you use a combination of a CMS with robust API access, a content workflow tool or spreadsheet-to-publish bridge (like Zapier, Make, or a custom script), and structured content templates with pre-filled SEO fields, so that a piece of content moves from approved draft to live URL without someone doing ten small tasks by hand. The rest of this tutorial is about how that actually works, where it breaks, and what's not worth automating. What You Actually Need Before You Start Automating Most guides jump straight to tools. That skips the part that determines whether automation saves you time or just makes your errors faster. Before any automation runs, your content process needs to be defined well enough to describe in writing. Can you list every step from "keyword approved" to "post is live" right now, including who does what? If that list doesn't exist yet, building automation on top of undefined process is how you end up with 40 posts published with missing meta descriptions and no one knowing why. The other thing people underestimate: your CMS needs to support programmatic publishing. WordPress with REST API enabled, Webflow's CMS API, Contentful, Ghost — these all work. A legacy CMS that requires someone to log in and click publish is a wall, not a speed bump. If your platform doesn't have an API or a native integration path, you're looking at a rebuild before automation is

2026-07-16 原文 →
AI 资讯

Array in JavaScript

Array An Array is a collection of multiple values stored in a single variable. let fruits = [ " Apple " , " Mango " , " Orange " ]; Here, fruits contains three values. Why Do We Need Arrays? Without an array, you would write: let fruit1 = " Apple " ; let fruit2 = " Mango " ; let fruit3 = " Orange " ; Using an array: let fruits = [ " Apple " , " Mango " , " Orange " ]; This makes the code shorter and easier to manage. Array Index Each value in an array has an index. The index always starts from 0. Index: 0 1 2 ------------------------- Array: Apple Mango Orange Accessing Array Elements Use the index number to access a value. let fruits = [ " Apple " , " Mango " , " Orange " ]; console . log ( fruits [ 0 ]); console . log ( fruits [ 1 ]); // Output: Apple Mango Changing an Array Element You can update any value using its index. let fruits = [ " Apple " , " Mango " , " Orange " ]; fruits [ 1 ] = " Banana " ; console . log ( fruits ); // Output: [ " Apple " , " Banana " , " Orange " ] Finding the Length of an Array Use the "length" property. let fruits = [ " Apple " , " Mango " , " Orange " ]; console . log ( fruits . length ); // Output: 3 Adding Elements push() – Add at the End let fruits = [ " Apple " , " Mango " ]; fruits . push ( " Orange " ); console . log ( fruits ); // Output: ["Apple", "Mango", "Orange"] unshift() – Add at the Beginning let fruits = [ " Mango " , " Orange " ]; fruits . unshift ( " Apple " ); console . log ( fruits ); // Output: ["Apple", "Mango", "Orange"] Removing Elements pop() – Remove from the End let fruits = [ " Apple " , " Mango " , " Orange " ]; fruits . pop (); console . log ( fruits ); // Output: ["Apple", "Mango"] shift() – Remove from the Beginning let fruits = [ " Apple " , " Mango " , " Orange " ]; fruits . shift (); console . log ( fruits ); // Output: ["Mango", "Orange"] Looping Through an Array Use a "for loop" to print all elements. let fruits = [ " Apple " , " Mango " , " Orange " ]; for ( let i = 0 ; i < fruits . length ; i

2026-07-15 原文 →
AI 资讯

From Zero to First PR: How I Contributed to an Open-Source AI Project as a Beginner

I stared at the GitHub page for what felt like forever. The repo had thousands of stars, hundreds of issues, and a long list of contributors who clearly knew what they were doing. Me? I had a few small personal projects, some half-finished tutorials, and a nagging feeling that I wasn’t “ready” to contribute to real open-source software. Especially not an AI project with fancy models, complex pipelines, and people publishing papers off the codebase. But I wanted in. I wanted to learn how real-world AI systems are built, to get feedback on my code, and to be part of something bigger than my local src/ folder. So I made a deal with myself: no more waiting until I feel “ready.” I’d go from zero to my first pull request (PR) in one focused push. Here’s exactly how I did it, what I learned, and what I’d tell anyone hesitant about contributing to an open-source AI or machine learning project for the first time. Step 1: Pick the Right Project (Not the Biggest One) The biggest mistake I almost made was aiming for the most famous AI repo I could find. Big projects are great, but they can be intimidating and slow for a first-timer. Instead, I looked for: Active maintenance : recent commits, issues being closed, maintainers responding. Clear contribution guidelines: a CONTRIBUTING.md or at least a solid README. Beginner-friendly issues: labels like good first issue, beginner, or help wanted. Scope I could understand: I didn’t need to grasp the entire codebase, just enough to fix one small thing. I ended up choosing a mid-sized open-source AI library : not unknown, not legendary. Perfect. If you’re searching now, try queries like: “awesome open source llm” “open source machine learning projects good first issue” “open source AI tools GitHub” Then scan their issues tab for beginner-friendly tasks. Step 2: Set Up the Project Locally (Without Panicking) Once I picked a project, the next hurdle was getting it to run on my machine. The repo had a typical structure: project/ README.md

2026-07-15 原文 →
产品设计

Dual role of * in C

Prerequisites Let's create a variable. int myNum = 5 ; Now, myNum refers to the value 5 . However, we can get its memory address using the & operator like this: &myNum . Role 1: Creating pointers A pointer holds a memory address. int * pointerToMyNum = & myNum ; Role 2: Modifying values using a pointer In this case, * works as the dereference operator. * pointerToMyNum = 10 ; Now, if we print myNum , the output will be 10 . Understanding that they are different in each context makes things much easier ✨ Note Both int ptr and int ptr are functionally identical in C.

2026-07-15 原文 →
AI 资讯

DeepSeek vs Qwen vs Kimi vs GLM: Which One Wins My Freelance Budget?

DeepSeek vs Qwen vs Kimi vs GLM: Which One Wins My Freelance Budget? Last Tuesday I spent two hours building a client dashboard that needed AI-powered text summarization. The client is a small e-commerce shop, they get maybe 500 product descriptions a week that need condensing into bullet points. Sounds simple, right? Except when I ran the numbers on my usual OpenAI setup, the bill was going to eat into my margin harder than I'd like. That's when I went down the rabbit hole of Chinese AI models. DeepSeek, Qwen, Kimi, GLM — I've been hearing about these for months from other devs in Discord, but I never actually committed to testing them because, honestly, who has the time? Well, apparently I do, because that Tuesday I decided to run all four head-to-head against my actual workload. Here's what happened. Why I Even Bothered (The Real Math) Before we get into the benchmarks and pricing tables, let me put this in perspective. My hourly rate as a freelance dev sits at $85. Every hour I spend wrestling with a subpar API that hallucinates or charges too much is an hour I'm not billing a client. The "free" model is never free — either it costs me time or it costs me money, and usually both. I was paying roughly $0.60 per 1M output tokens on GPT-4o for the summarization work. For 500 product descriptions, each averaging maybe 150 tokens output, that's about $0.045 per batch. Sounds tiny, right? But multiply that across multiple clients, and suddenly I'm watching $40-60 a month vanish into API costs that I can't really pass along without awkward pricing conversations. So I started shopping. And what I found genuinely surprised me. The Contenders at a Glance All four model families run through Global API's unified endpoint, which means I didn't have to maintain four different SDKs, four different auth setups, four different billing dashboards. Just swap the model name in the request and ship. For a one-person operation, that's huge. Here's the landscape I was working with: Di

2026-07-15 原文 →
开发者

You Don't Need Node.js to Learn Web Development

I see this every week. Someone decides to learn web development. They Google "how to start web development" and within 20 minutes they're installing Node.js, npm, VS Code, and five extensions they don't understand. They haven't written a single line of code yet. But they've already spent an hour configuring their "environment." Then they get stuck. Node version conflicts. npm permission errors. VS Code extensions that break their syntax highlighting. They think they're not smart enough for programming. They are. They just started with the wrong step. The Problem Learning web development has three core technologies: HTML, CSS, and JavaScript. That's it. Everything else — Node.js, npm, webpack, Vite, React — is extra. It's not the starting point. But most tutorials assume you already have Node.js installed. They say "open your terminal" and "run npm install." Beginners follow along, copy the commands, and have no idea what any of it means. Here's what actually happens: You install Node.js (200MB+) You install VS Code (another 300MB+) You install 5-10 extensions You create a project folder You open terminal and run npm init -y You run npm install live-server You run npx live-server You finally see your HTML page in a browser That's 8 steps before you write Hello World . The Solution You don't need any of that. Not yet. Here's what you actually need to learn HTML, CSS, and JavaScript: A browser (you already have one) A text editor (Notepad works) That's it Open Notepad. Write this: <!DOCTYPE html> <html> <head> <title> My First Page </title> </head> <body> <h1> Hello, World! </h1> <p> This is my first web page. </p> </body> </html> Save it as index.html. Double-click the file. It opens in your browser. You just built your first web page. No terminal. No npm. No Node.js. No configuration. When Should You Actually Learn Node.js? Node.js becomes useful when you need: Server-side code (backend development) Package management (npm packages) Build tools (webpack, Vite) Framew

2026-07-15 原文 →
AI 资讯

# Building a Lightweight Product Filter with Vanilla JavaScript

Building a Lightweight Product Filter with Vanilla JavaScript While building a small e-commerce project, I wanted users to filter products instantly without refreshing the page. Instead of relying on a frontend framework, I opted for a simple solution using HTML data attributes, vanilla JavaScript, and a little CSS. The goal was straightforward: let visitors filter items by size while keeping the interface fast, responsive, and easy to maintain. HTML Structure Each product card stores its information in data-* attributes. This keeps the markup clean and makes filtering straightforward. <div class= "filters" > <button class= "filter-btn" data-filter= "all" > All </button> <button class= "filter-btn" data-filter= "small" > S </button> <button class= "filter-btn" data-filter= "medium" > M </button> <button class= "filter-btn" data-filter= "large" > L </button> </div> <div class= "product-grid" > <div class= "product-card" data-size= "medium" data-style= "cargo" > Cargo Shorts </div> <div class= "product-card" data-size= "large" data-style= "chino" > Chino Shorts </div> <!-- More product cards --> </div> Using data attributes means you can add new filter categories later without changing your overall structure. JavaScript Filtering Logic The filtering logic listens for button clicks and simply shows or hides product cards based on the selected size. const filterButtons = document . querySelectorAll ( " .filter-btn " ); const productCards = document . querySelectorAll ( " .product-card " ); filterButtons . forEach (( button ) => { button . addEventListener ( " click " , () => { const filterValue = button . dataset . filter ; productCards . forEach (( card ) => { const cardSize = card . dataset . size ; if ( filterValue === " all " || cardSize === filterValue ) { card . classList . remove ( " hidden " ); } else { card . classList . add ( " hidden " ); } }); filterButtons . forEach (( btn ) => btn . classList . remove ( " active " )); button . classList . add ( " active "

2026-07-15 原文 →
AI 资讯

An Introduction to Neural Networks

Hi guys ! I'm a new developer who's interested in data science and artificial intelligence. To showcase what I learnt thus far, I've started writing articles, with my first one being published here ! One of the most difficult parts of getting into machine learning was the overload of terminology that tutorials had, even when explaining basic concepts such as how a neural network itself would function. Because of this, I've written an article (see above) that simplifies it while ensuring the main concepts are sufficiently explained; it requires no mathematical background and will only take less than 5 minutes to read ! I hope you find it informative and well written, and I highly welcome any suggestions or corrections that might be suggested to improve my future articles !

2026-07-15 原文 →
AI 资讯

Seven things to check before a WordPress major upgrade — before "patch what breaks after" becomes a disaster

WordPress major version upgrades (5.x → 6.x, and eventually 6.x → 7.x) are a different animal from minor releases. Minor releases (like 6.4.1 → 6.4.2) are mostly bug fixes with low compatibility risk. Majors land API deprecations, raised PHP minimum requirements, and core block replacements all at once — and those things hit operations hard. The " just hit Update in the admin and patch whatever breaks " workflow can survive on a single personal site, but it tends to fall apart under multi-site maintenance — simultaneous failures across sites overwhelm root-cause triage. This post collects the things worth verifying before you run a major upgrade, as a seven-item checklist . 1. Has the minimum PHP version been raised? Major WordPress releases sometimes raise the minimum supported PHP version (6.6 lifted it to PHP 7.2.24, and a future 7.0 will very likely require PHP 8.x). What matters operationally isn't just the server's PHP version and WordPress's stated minimum — it's the intersection with the PHP versions your plugins and themes actually run on . You can usually upgrade your server's PHP, but older themes and plugins not running on new PHP isn't rare. A subtle failure mode here: traps like PHP 8.2+ deprecated warnings leaking into older WP-CLI JSON output , where nothing visibly errors but your operational tooling silently breaks. Before upgrading, run wp plugin list --format=json on the production PHP environment and verify you're getting clean JSON. That one check catches a lot of post-upgrade pain. 2. Audit "Tested up to" for every plugin Each plugin's readme.txt carries a Tested up to: X.X line — the developer's declaration of the highest WordPress version they've actually tested against . It's the first signal for major-upgrade compatibility audits. WP-CLI gives you the inventory in one shot: wp plugin list --fields = name,version,update_version,update --format = table Plugins where "Tested up to" is old AND no updates in the last year deserve scrutiny. Acti

2026-07-15 原文 →
AI 资讯

Adaptive Thinking Killed My Token Budget Code: Migrating Off budget_tokens

I had a tidy little helper that computed a thinking budget based on input size. Something like "give the model 30% of the context as thinking room." It worked great on Opus 4.5. Then I tried to point it at Opus 4.8 and got a 400. The whole concept I had built around is gone in the current models. Here is what replaced it and how I migrated. What broke The old pattern looked like this: // Opus 4.5 and earlier const response = await client . messages . create ({ model : " claude-opus-4-5 " , max_tokens : 16000 , thinking : { type : " enabled " , budget_tokens : 8000 }, messages , }); On Opus 4.7, 4.8, and Fable 5, thinking: { type: "enabled", budget_tokens: N } returns a 400. The fixed token budget is dead. The replacement is adaptive thinking, where the model decides how much to think, plus an effort knob that controls overall token spend. // Opus 4.8 const response = await client . messages . create ({ model : " claude-opus-4-8 " , max_tokens : 16000 , thinking : { type : " adaptive " }, output_config : { effort : " high " }, // low | medium | high | xhigh | max messages , }); Why this is actually better (after I got over it) My old budget code was a guess dressed up as a calculation. I had no real basis for "30% of context." I picked it because it felt reasonable and the outputs looked fine. Adaptive thinking moves that decision to the model, which sees the actual problem. The mental model shift: budget_tokens controlled how much the model could think. effort controls how much it thinks and acts . They are not the same axis, so there is no clean 1:1 mapping. I stopped trying to translate "8000 tokens" into an effort level and instead picked based on the workload. How I chose effort levels After running my own evals, here is where I landed: Workload Effort Notes Classification, routing low Fast, scoped, not intelligence-sensitive Most app traffic medium to high The balance point Coding and agentic loops xhigh Best for these; it is the Claude Code default Correctness

2026-07-14 原文 →
AI 资讯

Build a Local LLM Chatbot with Ollama and Python

Build a Local LLM Chatbot with Ollama and Python Build a Local LLM Chatbot with Ollama and Python Imagine typing a question into your chatbot and getting a response in milliseconds, completely offline, with zero data leaving your machine. No API keys, no monthly subscription fees, and no privacy concerns about your data being sent to a cloud server. This isn’t a futuristic dream—it’s the reality of running a Local Large Language Model (LLM) on your own computer. With the rise of tools like Ollama , building a private AI chatbot in Python has become as simple as installing a few packages and writing a short script. Let’s dive in and build one together. Why Go Local? Before we write any code, it’s worth understanding why running an LLM locally is a game-changer. Cloud-based AI services like OpenAI or Anthropic are powerful, but they come with trade-offs: you pay per token, your data is processed on their servers, and you’re dependent on their uptime. A local LLM flips this model. You download the model once, run it on your hardware, and you have full control. Ollama is the engine that makes this accessible. It’s a lightweight, open-source tool that simplifies running LLMs like Llama 3, Phi 3, or Mistral on macOS, Linux, and Windows. It handles model downloads, memory management, and inference, exposing a simple API that Python can easily interact with [1][2]. Step 1: Install Ollama and Pull a Model The first step is getting Ollama on your machine. Visit ollama.com , click Download , and install the version for your operating system [2]. Once installed, verify it’s working by opening your terminal or Command Prompt and running: ollama --version If you see a version number, you’re ready to go. Next, you need a model. Ollama supports dozens of open-source models, but for a beginner-friendly chatbot, Llama 3.2 is a great choice. It’s small, fast, and surprisingly capable. To download it, run: ollama pull llama3.2 This command fetches the model and stores it locally. Depen

2026-07-14 原文 →
AI 资讯

I Wish I Ran the Numbers on Open Source AI APIs Sooner

I Wish I Ran the Numbers on Open Source AI APIs Sooner Three months ago I would have told you self-hosting was the obvious move. "Open source means free, right?" I said that to a client while quoting them $3,500 for a GPU server setup. They smiled politely and went with someone else. That rejection sent me down a rabbit hole I wish I'd started years earlier, because the actual math — not the vibes-based math freelancers like me tend to do — completely flips the script. If you're running a solo practice or a tiny shop, you probably bill every minute of GPU babysitting straight out of your own pocket. That's time you could be shipping features, pitching clients, or — if we're being honest — sleeping. So let me walk you through what I learned the hard way, with all the pricing left exactly where it belongs. The Open Source Lineup That Actually Matters Right Now When I started this research, I assumed "open source AI API" was an oxymoron. If you're calling an API, somebody owns the server, so what's even the point of being open? Turns out the point is massive: open-weight models accessible through an API give you the pricing transparency of self-hosting without the DevOps funeral you're planning for your weekends. Here's the pricing matrix I put together from Global API's public rates. These are output token prices (input is usually cheaper), and yes — they're shockingly low compared to GPT-4o territory. Model License Output Price Self-Host Range DeepSeek V4 Flash Open weights $0.25/M $500-2,000/mo DeepSeek V3.2 Open weights $0.38/M $800-3,000/mo Qwen3-32B Apache 2.0 $0.28/M $400-1,500/mo Qwen3-8B Apache 2.0 $0.01/M $200-800/mo Qwen3.5-27B Apache 2.0 $0.19/M $300-1,200/mo ByteDance Seed-OSS-36B Open weights $0.20/M $500-2,000/mo GLM-4-32B Open weights $0.56/M $400-1,500/mo GLM-4-9B Open weights $0.01/M $200-800/mo Hunyuan-A13B Open weights $0.57/M $300-1,000/mo Ling-Flash-2.0 Open weights $0.50/M $300-1,000/mo Look at Qwen3-8B and GLM-4-9B at $0.01/M output tokens. A mi

2026-07-14 原文 →
AI 资讯

My MCP Server Kept Crashing. Here's the Error Recovery Pattern That Saved It.

I spent three days wondering why my MCP server would just... stop. No crash logs. No error messages. Clients connected fine, then after a few hours, every tool call returned silence. Turns out the Model Context Protocol (MCP) spec doesn't force you to handle errors — it assumes you will. But the reference implementations are minimal. Your server starts healthy, then bit by bit, things go wrong. A network blip. A malformed tool argument. An external API timeout. And suddenly your AI agent is staring at a blank response. Here's the pattern I ended up with. It's not clever. It just works. The Fix Start with a wrapper around your tool handlers. Every MCP server framework has some kind of tool registration — this works for the official Python SDK, the TypeScript SDK, and most community frameworks: from mcp.server import Server from mcp.types import ErrorData , INTERNAL_ERROR , INVALID_PARAMS import traceback import json class ResilientMCPServer ( Server ): """ An MCP server that doesn ' t silently die. """ async def call_tool ( self , name : str , arguments : dict ): try : result = await super (). call_tool ( name , arguments ) return result except ( ConnectionError , TimeoutError ) as e : # Network-level issues — reconnect and retry self . _reconnect () return self . _error_response ( f " Connection lost while executing { name } : { e } " ) except ValueError as e : # Bad arguments from the client — tell them clearly return self . _error_response ( f " Invalid arguments for { name } : { e } " , code = INVALID_PARAMS ) except Exception as e : # Everything else — log, don't crash traceback . print_exc () return self . _error_response ( f " Tool { name } failed: { e } " , code = INTERNAL_ERROR ) def _error_response ( self , message : str , code : int = INTERNAL_ERROR ): return { " content " : [{ " type " : " text " , " text " : f " ERROR: { message } " }], " isError " : True } def _reconnect ( self ): """ Reset transport layer without restarting the server. """ # Your recon

2026-07-14 原文 →
AI 资讯

Python Redis: Caching and Fast Data Structures

Python Redis: Caching and Fast Data Structures Redis is an in-memory data store used for caching, session storage, pub/sub messaging, leaderboards, rate limiting, and more. With redis-py 's async client, it integrates cleanly into any asyncio application. Installation pip install redis[hiredis] # hiredis is a C parser — 2-5× faster protocol parsing Connect and Verify import asyncio import redis.asyncio as aioredis from datetime import timedelta import json REDIS_URL = " redis://localhost:6379/0 " async def get_redis () -> aioredis . Redis : client = aioredis . from_url ( REDIS_URL , encoding = " utf-8 " , decode_responses = True , socket_connect_timeout = 5 , socket_timeout = 5 , retry_on_timeout = True , ) pong = await client . ping () print ( f " Redis connected: { pong } " ) return client Strings — Basic Cache with TTL async def cache_set ( r : aioredis . Redis , key : str , value : str , ttl : int = 300 ) -> None : await r . set ( key , value , ex = ttl ) async def cache_get ( r : aioredis . Redis , key : str ) -> str | None : return await r . get ( key ) # Cache-aside pattern async def get_user_profile ( r : aioredis . Redis , user_id : int , db ) -> dict : cache_key = f " user:profile: { user_id } " cached = await r . get ( cache_key ) if cached : print ( f " Cache HIT for user { user_id } " ) return json . loads ( cached ) print ( f " Cache MISS for user { user_id } — querying DB " ) user = await db . fetch_user ( user_id ) # your DB call if user : await r . set ( cache_key , json . dumps ( user ), ex = 600 ) return user or {} # Atomic counter async def increment_page_views ( r : aioredis . Redis , page : str ) -> int : key = f " views: { page } " count = await r . incr ( key ) await r . expire ( key , 86400 ) # reset counter after 24 h return count Hashes — Structured Objects async def save_session ( r : aioredis . Redis , session_id : str , data : dict , ttl : int = 3600 ) -> None : key = f " session: { session_id } " await r . hset ( key , mapping = data )

2026-07-13 原文 →