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

标签:#tor

找到 1180 篇相关文章

AI 资讯

The Markdown File That Beat a $50M Vector Database: Separating Storage and Search in Agent Memory

In the rush to build AI agents, we defaulted to complex vector databases. But high-traffic platforms are converging on a simpler, more robust foundation: plain files. Most long-term agent memory setups are massively over-engineered. When developers start building LLM applications, the default prescription is almost always: "Spin up a managed vector database and build a RAG pipeline." But if you look at the highest-traffic production agent platforms (like Claude Code, Manus, and OpenClaw), a quieter trend has emerged. They are bypassing the enterprise embeddings store and using plain markdown files as their primary memory substrate. This is not a regression to simplicity. Done well, it is a stronger engineering foundation because files are inspectable, diffable, portable, and git-native. But a folder of plain text notes with no structure is just a slow, poorly indexing database. To make a file-first architecture work at scale, you must follow a fundamental system design principle: separate storage from search . The Core Invariant: Storage vs. Search The single highest-leverage decision you can make in agent memory design is treating your storage layer and search indexes as completely separate systems. Storage (Canonical Source of Truth): Versioned, human-readable files (Markdown + YAML frontmatter). Search (Derived Index): Derived search structures (vector databases, full-text BM25 indexes, entity graphs, keyword indexes). In this architecture, every search index is treated as a disposable artifact. You can delete your vector embeddings database or rebuild your entity graph at any time, with zero loss of underlying memory. This buys you three advantages: Auditability for free: By storing memories in text files, you can version-control them using Git. Every memory update, supersession, or correction is diffable, attributable, and reversible without any custom database versioning logic. Algorithmic freedom: Swap your embedding models, adjust your chunking strategies, o

2026-07-02 原文 →
AI 资讯

Stop Letting AI Agents Raw-Dog Your Filesystem: Building SafeMCP

We need to have a serious talk about the Model Context Protocol. Everyone is losing their minds over "vibe coding" right now. You plug an MCP server into Cursor, Claude Code, or VS Code, tell the AI to fix a bug across three directories, and go grab a coffee while it spins up local servers, reads files, and executes terminal commands. It feels like absolute magic. But honestly? It's also completely terrifying. Maybe I’m just paranoid, but it seems like we’ve collectively skipped the part where we ask ourselves if giving a statistical text-prediction engine raw, unvetted access to our local machines is a good idea. Some security folks are already warning that we’re walking directly into a massive remote code execution crisis. Think about it. Most MCP servers run as local subprocesses. They inherit your exact user permissions. If you run your editor as an admin or with access to sensitive environment variables, so does the AI. And the real issue isn't that the AI will spontaneously turn evil. The issue is prompt injection. The Security Void in the Hype I spent some time looking through public MCP servers on GitHub recently, and the sheer lack of input validation is wild. Because developers are rushing to build cool tools, basic security hygiene has completely lagged behind. If an AI agent reads an untrusted string—like a malicious comment in a GitHub issue, an automated email, or a dirty record inside a database—it can easily be manipulated into executing an injection payload. The model doesn't know the difference between your system instructions and the data it's processing. It treats them exactly the same. What happens when a prompt injection tricks a standard filesystem MCP tool into looking for a file named ../../../../../../etc/passwd or pulling your private AWS keys? The tool just does it. It’s a classic path traversal vulnerability, except instead of a malicious hacker typing it into a web form, an automated agent is doing it because a piece of text told it to.

2026-07-01 原文 →
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; }

2026-07-01 原文 →
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: ┌───────────────

2026-07-01 原文 →
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

2026-07-01 原文 →
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

2026-07-01 原文 →
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

2026-07-01 原文 →
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

2026-07-01 原文 →
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

2026-07-01 原文 →
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

2026-07-01 原文 →
AI 资讯

01: What Is a Keyboard Simulator? A Complete Introduction to Interactive Keyboard Visualization

If you've ever wondered how to visualize, teach, or explore keyboards without owning physical hardware, a keyboard simulator is the answer. In this in-depth guide, we explore what keyboard simulators are, how they work, and why they are changing the way people learn to type. Defining a Keyboard Simulator A keyboard simulator is a software application that digitally recreates the visual, functional, and interactive behavior of a physical keyboard. Unlike a simple on-screen keyboard that merely serves as a typing aid, a true keyboard simulator renders the keyboard in detail — often in three dimensions — and responds to keystrokes in real time, creating an immersive and educational experience. The best keyboard simulators go far beyond static images. They animate individual key presses, replicate the visual design of specific keyboard models, support multiple layouts (QWERTY, Dvorak, AZERTY), and even show animated hands performing the typing — making them extraordinarily useful for remote teaching, accessibility testing, content creation, and learning to type. 💡 Did you know? The Keyboard Simulator by Roboticela is one of the most advanced free and open-source keyboard simulators available today, featuring 3D interactive rendering powered by React Three Fiber, five authentic laptop keyboard models, and eight beautiful visual themes. The Core Components of a Keyboard Simulator A fully-featured keyboard simulator typically includes several key components that work together to create a complete experience: 🎮 3D Rendering Engine: Displays the keyboard model from any angle with smooth rotations and zoom capabilities. ⌨️ Real-Time Key Feedback: Every keystroke on your physical keyboard mirrors instantly on the 3D model. 🖐️ Hand Animation: Animated hands show proper finger placement and movement as you type. 📝 Document Editor: A built-in text editor captures your input and links it to the keyboard visualization. 🎨 Theme System: Multiple visual themes make the experience beau

2026-06-30 原文 →
AI 资讯

Building a Denim Collection API: A Practical Guide to Handling Product Variants

If you've ever worked with e-commerce data, you know that "a pair of jeans" is never just one product. A single style might come in 5 washes, 8 sizes, and 3 inseam lengths. That's 120 potential SKUs. Handling this correctly in an API can be tricky, so let me share a pattern I've used for structuring product variants. The core problem is balancing flexibility with performance. You want customers to filter by size, color, and fit without making dozens of API calls. Here's a simple but effective approach using a normalized database schema with a flat query layer: -- Products table (the "parent") CREATE TABLE products ( id UUID PRIMARY KEY , name TEXT NOT NULL , description TEXT , base_price DECIMAL ( 10 , 2 ), category TEXT ); -- Variants table (the actual sellable items) CREATE TABLE variants ( id UUID PRIMARY KEY , product_id UUID REFERENCES products ( id ), sku TEXT UNIQUE NOT NULL , size TEXT , color TEXT , wash TEXT , inseam TEXT , price DECIMAL ( 10 , 2 ), -- can override base price stock_quantity INT , image_url TEXT ); The key insight? Keep the product metadata (description, care instructions, brand story) in the products table, but put all the sellable attributes in variants. This lets you run queries like: -- Find all size 28 jeans in "mid wash" under $80 SELECT p . name , v . color , v . wash , v . price , v . stock_quantity FROM products p JOIN variants v ON p . id = v . product_id WHERE p . category = &# 039 ; women - jeans &# 039 ; AND v . size = &# 039 ; 28 &# 039 ; AND v . wash LIKE &# 039 ; % mid %&# 039 ; AND v . price & lt ; 80 AND v . stock_quantity & gt ; 0 ORDER BY v . price ; For the frontend, I usually return a flattened structure: { "product": { "id": "abc -123 " , "name": "Classic Straight Leg Jean" , "description": "High-rise fit in stretch denim..." , "availableSizes": [ " 24 " , " 25 " , " 26 " , " 27 "

2026-06-30 原文 →
AI 资讯

Beyond ChatGPT: Understanding the Core Building Blocks of Generative AI

Most developers have experimented with ChatGPT or GitHub Copilot. But when it comes to building AI-powered applications, simply calling an LLM API isn't enough. Understanding what's happening behind the scenes helps you design systems that are scalable, reliable, and cost-effective. In this article, we'll explore four concepts every software engineer should know: tokens, embeddings, transformers, and Retrieval-Augmented Generation (RAG). 1. LLMs Think in Tokens, Not Words One of the biggest misconceptions about Large Language Models (LLMs) is that they understand words like humans do. In reality, they process tokens, which are smaller units of text. For example: Prompt: Explain dependency injection in Spring Boot. is first converted into a sequence of tokens before the model processes it. Why does this matter? API pricing is based on the number of input and output tokens. Longer prompts increase latency and cost. Every model has a maximum context window measured in tokens. When building AI applications, prompt design isn't just about getting better answers—it's also about optimizing performance and cost. 2. Transformers: The Breakthrough Behind Modern AI Before 2017, language models processed text one word at a time using architectures like RNNs and LSTMs. They struggled with long conversations because earlier context was gradually forgotten. The introduction of the Transformer architecture changed this with a mechanism called self-attention. Instead of reading text sequentially, transformers analyze the relationships between all tokens in a sentence simultaneously. Consider this sentence: "The server restarted because it ran out of memory." The model understands that "it" refers to "the server", not "memory", by assigning attention to the relevant words. This ability to capture context efficiently is what powers modern LLMs like GPT, Gemini, Claude, and Llama. 3. Embeddings Enable Semantic Search Suppose a customer searches: "How can I get my money back?" But your

2026-06-30 原文 →