AI 资讯
Proxying RabbitMQ Management UI Through Nginx (Fixing the %2F Problem)
The Problem When you put RabbitMQ's Management UI behind an nginx reverse proxy under a sub-path like /rabbitmq/ , queue detail pages and many API calls break silently. The root cause: nginx normalizes the request URI before proxying. It decodes %2F (the URL-encoded forward slash) into a literal / . RabbitMQ's Management API uses %2F to represent the default virtual host ( / ) in API paths: GET /api/queues/%2F/my-queue When nginx decodes it: GET /api/queues///my-queue ← broken What Doesn't Work The common advice of using merge_slashes off or a rewrite directive doesn't fully solve this because nginx still normalizes $uri before forwarding. The Fix Use $request_uri inside an if block. Unlike $uri , $request_uri holds the raw, undecoded URI exactly as the client sent it — nginx never touches it. nginx # RabbitMQ: API paths — use $request_uri to preserve %2F (never decoded by nginx) location ~* ^/rabbitmq/api/ { if ($request_uri ~* "^/rabbitmq/(.*)") { proxy_pass http://rabbitmq:15672/$1; } proxy_buffering off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto https; } # RabbitMQ: general UI (JS, CSS, static assets, non-API pages) location ~* ^/rabbitmq/ { rewrite ^/rabbitmq/(.*)$ /$1 break; proxy_pass http://rabbitmq:15672; proxy_buffering off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto https; }
AI 资讯
Bikin "Otak" AI Agent Bisa Diedit di Obsidian: Panduan Sinkronisasi Dua Arah untuk Pemula
Pernah kepikiran, "Sebenarnya AI agent saya inget apa aja sih soal saya?" Kalau iya, tulisan ini buat kamu. Masalahnya: Memori AI Itu Kotak Hitam Kalau kamu pakai AI agent yang punya memori jangka panjang (persistent memory), kamu mungkin pernah ngerasa gak nyaman karena beberapa hal ini: Gak tahu persis apa yang diingat AI tentang kamu Gak tahu file-nya disimpan di mana Gak bisa edit memori itu tanpa ngetik perintah lewat chat Takut kalau file memorinya rusak, semua informasi hilang begitu saja Studi kasus di tulisan ini pakai Hermes Agent , agent open-source besutan Nous Research. Sebagai konteks buat yang belum familiar: Hermes Agent adalah agent AI open-source yang berjalan sebagai proses (daemon) mandiri di server milikmu sendiri, mengumpulkan memori lintas sesi, menjalankan tugas terjadwal, terhubung ke belasan platform pesan, dan menulis skill-nya sendiri dari pengalaman. Framework berlisensi MIT ini dirilis Februari 2026 dan dengan cepat menarik perhatian komunitas open-source AI. Hermes menyimpan memorinya di dua file utama: USER.md (profil tentang kamu) dan MEMORY.md (catatan agent soal lingkungan kerja, kebiasaan, dan pelajaran yang dipetik), plus satu file lagi SOUL.md untuk "kepribadian" si agent. Semuanya disimpan dalam format teks polos yang dipisah pakai karakter § , seperti ini: Preferensimu: komunikasi singkat dan langsung § Namamu Budi, awal 30-an, tinggal di Surabaya § Penggemar PKM / Building a Second Brain Format ini fungsional, tapi ada beberapa kekurangan: Susah diedit langsung karena bukan format yang ramah manusia Gak ada riwayat versi — sekali salah edit, informasi bisa hilang selamanya Gak ada tampilan visual — susah lihat semua catatan sekaligus Gak ada antarmuka grafis — harus lewat chat agent atau edit file mentah Solusinya: pindahkan memori itu ke Obsidian , aplikasi catatan berbasis markdown yang mendukung riwayat versi lewat git dan bisa diedit bebas. Arsitektur Sistemnya Sistem sinkronisasi ini punya empat lapisan: ┌───────────────
AI 资讯
AI Metrics Baseline: Prove Your Feature Works Before Scaling It
An AI feature can feel impressive and still be a bad product decision. The demo is fast. The answer sounds useful. The team is excited. Then usage grows and nobody can answer the basic questions: Is it accurate enough? Is it saving time? Which customers trust it? Why did costs spike? Should we scale it, fix it, or kill it? That is the trap an AI metrics baseline prevents. A baseline is not a dashboard full of vanity charts. It is a small set of before-and-after measurements that tells you whether an AI workflow is getting better, getting worse, or merely getting more expensive. Why AI features fail without a baseline Most software teams already track uptime, errors, and conversion. AI features need those too, but they also need new signals because model behavior is probabilistic. A normal API either returns the expected response or throws an error. An AI workflow can return: a fluent answer that is wrong a correct answer with missing evidence a useful answer that costs too much a slow answer that users abandon a safe answer that refuses too often a cheap answer that hurts trust a high-rated answer that does not improve the business workflow Without a baseline, every production discussion becomes opinion-driven: "The model seems better." "Users like it." "The new prompt reduced hallucinations." "The expensive model is worth it." Maybe. Maybe not. The baseline turns those claims into measurable comparisons. What an AI metrics baseline is An AI metrics baseline is the starting measurement for the workflow before you optimize or scale it. It answers five questions: What does the workflow cost today? How good are the outputs today? How fast and reliable is the experience today? Do users adopt and reuse it? Does it improve the real task it claims to improve? You do not need 80 metrics on day one. You need a small set of metrics that match the feature's risk and purpose. For example: Feature Useful baseline Support answer bot resolution rate, citation quality, escalation r
开发者
客戶開價太低嗎?Freelancer 接案前的 3 問決策樹
客戶開價太低嗎?Freelancer 接案前的 3 問決策樹 客戶說:「就改幾行代碼,收這麼多?」 你是不是也曾這樣懷疑過自己? 每個 freelancer 都遇過這種時刻——客戶開了一個數字,你直覺「好像太低了」,但又說不出具體原因。以下是三個問題,幫你在 30 秒內判斷一個報價是否值得接。 3 問決策樹 Q1:這個價格是否覆蓋你的實際時間成本? 別只算「改了幾行代碼」。真實成本包括: 讀懂陌生的 codebase(新手可能 3 小時起跳) 本地環境折騰(特別是別人維護的老項目) 測試和部署風險(部署壞了誰負責?) 客戶來回溝通的成本(「再大一點」「這個藍再淺一點」) 未知因素:如果代碼原作者已經不在,你是在維修「別人的技術債」 快速算法 :把報價 ÷ 你估計的總小時數 = 每小時實際時薪。拿這個數字和你的底線比(建議:不是你「想要」的時薪,而是你「能接受吃飯」的時薪)。 如果低於底線 30%,進 Q2。 Q2:需求是否清楚到可以控制風險? 報價低且需求模糊 = 高危信號。 以下任一癥狀存在,提高風險溢價或拒絕: 「就簡單改一下」——沒有定義邊界 沒有明確定義「完成」的標準——上線了算完成?客戶滿意了算完成? 對方說「你先做再說」——這句話幾乎等於「我打算白嫖你」 沒有提供任何文件或代碼庫 access——等於讓你盲開 決策樹 : 需求不清楚 + 報價低 → 報價必須上浮 50%,否則不接 需求不清楚 + 報價合理 → 可以談,先付定金再動工 需求清楚 + 報價低 → 進 Q3 Q3:這個案子是否帶來明確後續價值? 有兩種情況可以在低報價下仍然接: 確定的後續項目 :客戶明確說「這個做好了,下個月還有 X 個功能要做」 戰略性客戶 :這個客戶有公開作品價值(大厂案例、知名公司、能寫進 portfolio 的上線項目) 如果兩者都沒有,低報價等於純粹的自我低估。 真實案例:隱藏成本解析 案例 1:$200 改 3 行 CSS 客戶說:「就改導航列的顏色,$200 應該夠了吧?」 表面看:3 行 × $66/行 = 天價。 現實: 理解整個樣式系統、找到正確的 CSS 檔案:2 小時 本地環境折騰(別人的專案,Node 版本衝突):1 小時 反覆修改確認視覺效果:3 小時(客戶說「那個藍再淺一點、再加個 hover 效果」) 部署時發現壞了其他頁面:2 小時 客戶最後說「還是原來的好」:情緒成本 實際時薪 :$200 ÷ 8 小時 = $25/小時,低於 freelancer 最低生存線。 案例 2:$2,000 報價改 2 天的「簡單項目」 客戶說:「做一個登入系統,就基本功能,2 個禮拜夠了吧?」 報價 $2,000,看起來還不錯。 現實: 需求訪談:4 小時(客戶一開始說「就登入」,後來才說「還要有第三方登入、密碼重置、邀請機制」) 設計資料庫結構:3 小時 實現 Registration + Login + OAuth:6 小時 測試覆蓋:4 小時 文件撰寫和交接:2 小時 實際 :19 小時 × $105/小時 = $1,995 ——這個案子壓根不賺錢 常見陷阱:為什麼低報價 freelancer 總是吃虧 1. 「就幾行代碼」陷阱 代碼行數 ≠ 工作量。真正的成本在「理解上下文」——你得讀懂別人的代碼邏輯,這可能比你自己寫慢三倍。 2. 「簡單的 SQL」陷阱 每一條看似簡單的 UPDATE 語句,背後可能是: 凌晨 3 點資料庫突然鎖死 備份失敗、沒有測試環境 正式資料一個失误就沒了 3. 「長期合作」陷阱 客戶說「我們長期合作」通常是好事,但前提是—— 報價不能因為「長期」而打折 長期合作應該帶來穩定收入,不是穩定低價 你現在有一個具體報價嗎? 如果客戶給了你一個數字,你不確定是否該接—— For $10, I'll review one client offer and tell you whether it looks underpriced, risky, or worth taking. 直接發報價截圖或文字到 paypal.me/cheapuno ,標註「報價審查」,24 小時內回覆具體分析。 快速決策檢查表(列印出來放桌邊) □ 報價 ÷ 預估時數 > 我的底線時薪? □ 需求有明確定義邊界嗎? □ 有隱藏的技術債或未知因素嗎? □ 客戶有明確的後續項目或品牌價值? □ 我有權利說「不」嗎? 如果以上有任何一個「否」,這個報價需要重新談。 如果你想系統性学会如何報價、報價低了怎麼談、客戶不接受怎麼辦——歡迎從 Freelance Pricing Master Index 開始,這裡有 14 篇文章覆蓋 freelancer 定價的各種場景。
AI 资讯
The Token Bucket Algorithm: Build Server-Side API Rate Limiting in ~40 Lines
The Token Bucket Algorithm: Server-Side API Rate Limiting in ~40 Lines Plenty of tutorials teach you how to survive someone else's rate limit with retries and backoff. Far fewer show you how to build one. If you run an API, you need rate limiting on your side too — to protect your database from a runaway client, keep one noisy tenant from starving everyone else, and give abusive traffic a polite 429 instead of a melted server. The cleanest algorithm for the job is the token bucket . Let's implement it from scratch, then make it production-ready. How token bucket works Picture a bucket that holds up to capacity tokens. Every request removes one token. The bucket refills at a steady refillRate (tokens per second), up to its cap. If a request arrives and the bucket is empty, it's rejected. This gives you two useful properties at once: A sustained rate — the long-run average, set by refillRate . A burst allowance — clients can spend the whole bucket at once, set by capacity . That burst tolerance is why token bucket feels fair. A user who's been quiet for a minute can fire off a batch of requests without being punished for it. A minimal implementation Here's a self-contained bucket in JavaScript. No dependencies, no timers — we compute refill lazily based on elapsed time, which is both simpler and more accurate than a background interval. class TokenBucket { constructor ( capacity , refillRatePerSec ) { this . capacity = capacity ; this . refillRate = refillRatePerSec ; this . tokens = capacity ; this . lastRefill = Date . now (); } _refill () { const now = Date . now (); const elapsedSec = ( now - this . lastRefill ) / 1000 ; this . tokens = Math . min ( this . capacity , this . tokens + elapsedSec * this . refillRate ); this . lastRefill = now ; } take ( cost = 1 ) { this . _refill (); if ( this . tokens >= cost ) { this . tokens -= cost ; return { ok : true , remaining : Math . floor ( this . tokens ) }; } const deficit = cost - this . tokens ; const retryAfter = Mat
AI 资讯
Web Scraping with Python in 2026: Best Libraries and Anti-Bot Strategies
Web Scraping with Python in 2026: Best Libraries and Anti-Bot Strategies Web scraping in 2026 looks very different from 2020. Sites are smarter, anti-bot systems are more aggressive, and the legal landscape has evolved. Here's what actually works now. The 2026 Scraping Landscape Challenge 2020 Solution 2026 Solution Bot detection Rotate User-Agent Fingerprint randomization + residential proxies CAPTCHAs Manual solving Turnstile/hCaptcha solvers JavaScript rendering Selenium Playwright (faster, more reliable) Rate limiting Sleep between requests Adaptive pacing + request signing IP blocking VPN rotation Residential proxy pools Best Libraries in 2026 1. Playwright (Best for JS-heavy sites) from playwright.sync_api import sync_playwright def scrape_with_playwright ( url ): with sync_playwright () as p : browser = p . chromium . launch ( headless = True ) page = browser . new_page () page . goto ( url , wait_until = " networkidle " ) data = page . query_selector_all ( " .job-item " ) results = [] for item in data : title = item . query_selector ( " h2 " ). text_content () results . append ( title ) browser . close () return results 2. httpx + Selectolax (Fast, no JS needed) import httpx from selectolax.parser import HTMLParser def scrape_static ( url ): resp = httpx . get ( url , headers = { " User-Agent " : " Mozilla/5.0 " }) tree = HTMLParser ( resp . text ) for node in tree . css ( " .listing " ): print ( node . text ()) 3. API-First Approach (Always check first!) Many sites have hidden or public APIs that make scraping unnecessary: url = " https://www.freelancer.com/api/projects/0.1/projects/active/?query=python " data = httpx . get ( url ). json () Anti-Bot Strategies That Work 1. Request Fingerprint Randomization import random def get_random_headers (): browsers = [ " Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 " , " Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 " , ] return { " User-Agent " : random . choice ( browsers ), " A
AI 资讯
How We Translate 300-Page Books Using Claude Without Hitting Token Limits
Breaking long documents into overlapping chunks, preserving context, and reassembling with FastAPI At LectuLibre, we’ve built an AI‑powered platform that translates entire books—EPUBs and PDFs—using large language models. When we first hooked up Claude’s API, we naively fed it a 300‑page PDF in one request. It failed immediately. Claude 3 Opus has a 200K token window, but a 300‑page book can easily run to 300K tokens or more. Even if we squeezed it in, the output would be truncated and the quality would degrade at the extremes of the context window. So we faced a classic long‑document problem: how do you translate a book that’s larger than the model’s context window? Here’s the real approach we ended up with, the code we wrote, and the lessons we learned. The Problem: Token Limits Are Real Claude 3 Opus and Haiku models (and most LLMs) have a maximum context length—200,000 tokens for Opus. A token is roughly ¾ of a word. A 300‑page novel with ~75,000 words translates to about 100K tokens, so it should fit, right? But translations from English to Spanish can expand by 15–20%, and the prompt instructions, system message, and the user message itself all eat into that budget. Plus, we needed to send the entire source text in every call to give the model full context. That’s not feasible. We could have tried a simple split: cut the book at arbitrary page boundaries and translate piecemeal. That fails spectacularly. Narrative breaks mid‑sentence, and phrases like “the previous chapter” lose their referents. We needed a more intelligent chunking strategy. Our Approach: Sliding Window with Overlapping Paragraphs We settled on a sliding window chunking algorithm based on paragraphs, with a generous overlap. Here’s the idea: Split the source text into paragraphs (using \n\n ). Build chunks of max_chunk_tokens (we used 180,000 to keep a safety margin), adding paragraphs one by one and counting tokens with tiktoken . When the chunk exceeds the limit, we start a new chunk but we
AI 资讯
Maintaining WordPress sites behind HTTP Basic auth — Playwright, urllib, and encrypted credentials
It's pretty common to throw a layer of HTTP Basic auth on a WordPress site: a staging environment before launch, an internal test instance only employees should see, or any environment that wants an extra gate before the WordPress login screen itself. From a maintenance-tool point of view, this setup creates a peculiar "half-working, half-broken" asymmetry. The SSH/WP-CLI side runs fine. But everything HTTP-based — visual checks, thumbnail generation, browser-based fallback updates — hits 401 and dies. This post walks through how we resolved that asymmetry. What was breaking — two parallel paths, both blocked A maintenance tool actually touches a Basic-auth-protected site through two distinct paths: Playwright path : visual checks, thumbnail capture, browser fallback updates when SSH isn't available. browser.new_context() → navigation → screenshot urllib path : HTTP status checks (pre/post-update 200/5xx/4xx monitoring, rollback decisions) With no credentials, both paths see a 401 Unauthorized from the protected site. The Playwright symptom is the obvious one: the screenshot you save is the browser's "authentication required" dialog. The thumbnail grid fills with dark auth-prompt images, and you start wondering whether anything actually works. The urllib symptom is much worse — it silently breaks rollback decisions . A 401 baseline followed by another 401 after the update looks like "nothing changed = healthy." Real failures can hide behind that match, and the rollback that should have fired never does. The design — consolidate credential extraction into one helper When the same credentials need to flow through multiple code paths, picking them out of the site dict separately at each call site invites format-mismatch and missed-update bugs. So the first thing we did was build a small core/basic_auth_utils.py module that owns every form of credential extraction . # core/basic_auth_utils.py def get_basic_auth_tuple ( site ): """ Return (user, password), or None if not
AI 资讯
Além da IA: Por que a colaboração humana é o verdadeiro motor do Open Source
A narrativa atual da tecnologia está fortemente inclinada para a automação. Com agentes de IA escrevendo boilerplate , gerando componentes e até estruturando projetos inteiros, é fácil olhar para o futuro do desenvolvimento de software e assumir que o elemento humano está diminuindo. Mas se você mantém ou contribui ativamente para um projeto open source , sabe que a realidade é bem diferente. A IA pode escrever código, mas não consegue validá-lo contextualmente contra décadas de edge cases obscuros. Ela não sabe dizer por que uma regra de negócio específica falha em produção. Mais importante ainda: a IA não constrói comunidade. A evolução de um software robusto ainda depende inteiramente de pessoas colaborando, quebrando código, reportando bugs e validando se o código realmente funciona no mundo real. Para ver isso na prática, precisamos olhar para projetos que tentam fechar lacunas geracionais gigantescas na tecnologia. Um exemplo perfeito disso é o AxonASP . A Filosofia do AxonASP: Modernizando o Legado Por muito tempo, o ASP Clássico e o VBScript foram considerados presos a um modelo de servidor obsoleto — amarrados ao IIS e deixados para trás pelas práticas modernas de deploy . O AxonASP muda esse cenário. É um runtime open source e cross-platform que trata o ASP Clássico como uma Aplicação moderna, em vez de uma relíquia do passado. Ele traz o VBScript, o ASP e, principalmente, o suporte ao JavaScript Síncrono para o futuro. Construir um runtime que lida com código legado enquanto opera em um ecossistema moderno e multiplataforma não é algo que você consegue simplesmente pedindo para um LLM. Exige um ciclo de feedback agressivo. O AxonASP está em franca evolução e apresenta altíssima compatibilidade com o ASP Clássico. Mas essa compatibilidade não é mágica — ela é o resultado direto de usuários pegando seus scripts legados de 15 a 20 anos atrás, rodando no motor, vendo onde falham e reportando exatamente o que aconteceu. Cada issue aberta e cada bug reportado p
AI 资讯
The Trump Administration Is Lifting Its Export Controls on Anthropic’s Mythos and Fable AI Models
The White House is easing restrictions on Anthropic’s most advanced AI models weeks after ordering the company to suspend access for foreign nationals.
产品设计
Startup Battlefield Australia application closes in days: Apply before July 6
What if one pitch changed everything? The next company nobody has heard of yet is building something that will matter. It could be yours.
AI 资讯
Build a Minimal WebMCP Agent with Playwright and Gemini
WebMCP lets a web page expose tools that AI agents can discover and execute inside the browser. That...
AI 资讯
Claude Science is Anthropic’s newest flagship product
At an event for pharmaceutical executives, biotech founders, and researchers on Tuesday, Anthropic announced Claude Science, a major new product intended to support scientific research in the same way that Claude Code supports software engineering. Like Claude Code, Claude Science can autonomously carry out meaningful work when given concise, high-level instructions, and it has access…
AI 资讯
Learn DynamoDB by running it - accesspatterns.dev
I've been building on DynamoDB since around 2015, and these days I build tools for it: dynoxide , a DynamoDB engine, and Nubo , a native client. So I'm not neutral about it. It's the first database I reach for, and with reason - the operational overhead is close to nil, no connections to pool or instances to size, and it holds the same single-digit-millisecond reads whether the table has a thousand items or a billion. The data modelling is a craft, and a satisfying one. It's also one of the harder databases to learn, and that's the part I keep coming back to. DynamoDB punishes the instincts you bring from SQL. You don't normalise and join at read time; you work out the questions your app will ask first, and shape the data around those access patterns, until one table answers all of them. It's a real shift in how you think, and it's where a lot of people bounce off - it feels backwards right up until it clicks. The people who teach it best all teach it the same way. Alex DeBrie's The DynamoDB Book , the arc.codes team's examples, Rick Houlihan's re:Invent talks - the legendary ones, where he models half a dozen access patterns onto a single table at a hundred miles an hour - none of them hand you rules to memorise. They show you patterns and make you run them. I learned a lot of my DynamoDB from all three, and it stuck because I was building as I went. That last part is the bit that's hard to come by on your own. Reading about an access pattern and having it in your fingers are different things, and to run one - build the table, write the items, fire the query and see what comes back - you need an AWS account, or a local emulator installed and seeded. Enough friction that plenty of people read about single-table design without ever building one. There was a second thing pulling the same way. dynoxide had learned to run in the browser only last month, compiled to WebAssembly with no server behind it, and it was a preview I didn't fully trust. What it needed was a real
AI 资讯
Google's new Nano Banana 2 Lite image model is its fastest and cheapest yet
They may not look as good, but Nano Banana 2 Lite images only take a few seconds to create.
AI 资讯
How GitHub maintains compliance for open source dependencies
Explore how the Open Source Program Office uses GitHub’s new license compliance product to manage open source dependencies at scale. The post How GitHub maintains compliance for open source dependencies appeared first on The GitHub Blog .
工具
Threads adds new features to Live Chats as it expands access
The updates include translations, new tools for hosts, and more.
AI 资讯
Trump's plan to redesign every .gov website leads to AI-designed horrors
A year in, National Design Studio delays plan to update government web standards.
开源项目
Trump asked Musk for SpaceX stock to seed US kids’ savings accounts, report says
Sources suggest Musk may be mulling big donation to Trump Accounts.
AI 资讯
X now offers an MCP server to make its platform easier for AI tools to use
X has launched a hosted MCP server, making it easier for developers to connect AI applications with the company’s API.