AI 资讯
Backward Compatibility: A Practitioner's Guide to Evolving APIs Without Breaking Clients
How to version REST endpoints, evolve GraphQL schemas, and ship mobile updates — without leaving existing users behind. Why It Matters Every deployed API is a contract. Every mobile binary installed on a user's phone is a snapshot of that contract. The moment you change a response shape, rename a field, or remove an endpoint, you risk breaking clients you cannot force-update. Backward compatibility is not about avoiding change. It is about managing change so that existing consumers continue to work while the system evolves underneath them. This article covers three layers: REST API versioning , GraphQL schema evolution , and mobile app compatibility (React Native & Flutter). Each section delivers concrete patterns and production-ready code. Part I — REST APIs The Versioning Decision REST APIs have four common versioning strategies. Each comes with tradeoffs: Strategy Example Pros Cons URI path /api/v1/users Simple, cacheable, widely understood Implies the resource itself changed; cache duplication Query parameter /api/users?version=1 Easy to implement, can default to latest Complicates routing and cache keys Custom header X-API-Version: 1 Keeps URIs clean Hard to test in browsers, invisible in logs Content negotiation Accept: application/vnd.app.v2+json Fine-grained, per-resource versioning Complex to test, requires custom media types Rule of thumb: Use URI versioning for public APIs. Use header-based versioning for internal services where you control all clients. Non-Breaking vs. Breaking Changes Not every change requires a new version: ✅ Non-breaking (no version bump needed): - Adding a new field to a response - Adding a new optional query parameter - Adding a new endpoint - Returning a new enum value (if clients handle unknowns) ❌ Breaking (requires a new version): - Removing or renaming a field - Changing a field's type (string → number) - Making an optional parameter required - Changing the response structure Pattern: Side-by-Side Versioning When a breaking cha
AI 资讯
A Practical Guide to Proxies for Web Scraping (with Python examples)
If you have written more than a couple of scrapers, you already know the pattern. The first few hundred requests fly through. Then responses slow down, you start seeing 429 Too Many Requests , a captcha wall appears, and finally the target just returns empty pages or a hard 403 . Your code did not change. Your IP did. Scraping at any real volume is less about parsing HTML and more about managing where your requests come from. This post is a practical walk-through of how proxies fit into a scraping pipeline: why a single IP fails, what proxy types actually matter, how rotation works, and how to wire it all up in Python with requests , aiohttp , and Scrapy. There is code you can copy, plus the mistakes that cost me the most time. Why one IP is never enough Every site you scrape sees the same thing: a stream of requests from one address, arriving faster and more regularly than a human ever would. Anti-bot systems are built to spot exactly that. The signals they use are boring but effective: Request rate per IP. Too many hits in a short window trips a rate limiter. Volume over time. Even a slow scraper eventually stands out if every request comes from the same address for hours. Behavioral fingerprint. No mouse, no scroll, identical headers, requests in perfect intervals. Reputation. Datacenter ranges that have been abused before are pre-flagged. You can soften some of these with headers, delays, and a real browser, but there is a ceiling. Once a single IP has made enough requests, it gets throttled or blocked regardless of how polite you are. The only way past that ceiling is to spread requests across many addresses, so no single one crosses the threshold. That is the entire job of a proxy pool. The proxy landscape, minus the marketing Providers love to complicate this. For scraping, the distinctions that actually change your results are these: Shared vs private. Shared proxies are handed to many customers at once. You inherit everyone else's behavior, so an address ca
AI 资讯
Diagnosing Cloudflare Blocks Before Changing Your Scraper
A scraper fails, someone swaps the User-Agent, someone else adds a proxy, then the job starts passing locally but fails again in CI. That usually happens because Cloudflare did not block “scraping” as one thing. It evaluated several signals, and each failure needs a different fix. This is about authorized automation: your own sites, customer-approved workflows, testing, monitoring, data access you are allowed to perform. If you do not have permission to automate against a site, changing fingerprints or rotating IPs does not make it okay. Start with the failure you actually see Cloudflare failures often get collapsed into “403”, but the page body matters. Common cases: Error 1020 : usually an access denied page from a Cloudflare rule or bot score decision. The HTTP status may still be 403, so inspect the HTML. 403 without a 1020 page : often IP reputation, firewall rules, geo restrictions, or an auth problem. 429 : rate limit exhaustion. Slowing down can help here, but it will not fix a fingerprint problem. Endless Just a moment... page : your client did not complete the browser-side challenge. CAPTCHA or Turnstile loop : Cloudflare still considers the session borderline after earlier checks. Add classification before you add workarounds. Even a basic classifier saves time: import time import requests CLOUDFLARE_MARKERS = { " 1020 " : " cloudflare_access_denied " , " Just a moment " : " cloudflare_js_challenge " , " cf-turnstile " : " cloudflare_turnstile " , " cf-error-code " : " cloudflare_error_page " , } def classify_response ( resp : requests . Response ) -> str : body = resp . text [: 5000 ] if resp . status_code == 429 : return " rate_limited " for marker , label in CLOUDFLARE_MARKERS . items (): if marker in body : return label if resp . status_code == 403 : return " forbidden_unknown " return " ok " if resp . ok else f " http_ { resp . status_code } " def get_with_backoff ( url : str , max_attempts = 4 ): for attempt in range ( max_attempts ): resp = request
AI 资讯
I built a tool that checks whether ChatGPT recommends your brand (Python + Apify)
Your customers have stopped Googling "best note-taking app." They're asking ChatGPT, Perplexity, and Gemini instead — and getting back a short list of three or four products. If your brand isn't on that list, you're invisible, and unlike a Google ranking you can't even see where you stand. That's the problem I set out to measure. This post is the build breakdown: five AI answer engines, one uniform result shape, a mention-detection core that doesn't lie to you, and the honest gotchas I hit around cost and billing. The whole thing runs as a paid Apify Actor written in async Python. The niche has a name now — GEO (Generative Engine Optimization) or AEO (Answer Engine Optimization). Think SEO, but the search engine is a language model and the "ranking" is whether you get named in the answer. The core question Give the tool a brand, its competitors, and the buyer-intent questions your customers actually type: { "brand" : "Notion" , "competitors" : [ "Obsidian" , "Coda" , "Evernote" ], "prompts" : [ "best note taking app for students" , "Notion vs Obsidian which should I use" ], "engines" : [ "perplexity" , "chatgpt" , "gemini" , "claude" , "aiOverview" ], "samplesPerPrompt" : 3 } It asks each engine each prompt (several times, because LLM answers vary run-to-run), then analyzes every answer for: were you mentioned, how early, were you recommended or just listed, what's the sentiment, who else got named, and — the part incumbents skip — which domains each engine cited. That last one is the actionable output: it tells you which websites the AI trusts for your category, i.e. where you need coverage. Architecture: one shape to rule them all The trick that keeps the whole thing sane is that every engine adapter — whether it's a clean REST API or a messy HTML scrape — returns the exact same record shape : { " engine " : " perplexity " , " prompt " : " best note taking app for students " , " sampleIndex " : 1 , " responseText " : " ... " , " citations " : [{ " url " : " ... "
AI 资讯
Skip LinkedIn/Indeed: most companies' job boards have a public JSON API
If you've ever tried to pull job listings by scraping LinkedIn or Indeed, you know the pain: anti-bot systems, CAPTCHAs, rotating proxies, and scripts that silently break every few weeks. Here's the thing — you usually don't need any of that. Companies don't post jobs on LinkedIn first. They post them in their ATS (Applicant Tracking System) — Greenhouse, Lever, Ashby, Workday, etc. — and most ATS platforms expose the company's board as a public JSON endpoint . No key, no login, no browser. It's the company's own source of truth, so it's cleaner and fresher than any aggregator. The endpoints A few that work with a plain GET ( {company} = the company's slug): Greenhouse — https://boards-api.greenhouse.io/v1/boards/{company}/jobs?content=true Lever — https://api.lever.co/v0/postings/{company}?mode=json Recruitee — https://{company}.recruitee.com/api/offers/ Breezy HR — https://{company}.breezy.hr/json SmartRecruiters, Ashby, BambooHR and Personio have their own equivalents. Workday is the one annoying exception — it's a POST and needs the full board URL (tenant + datacenter + site), so you can't guess it from a bare company name. Example: pulling Stripe's open roles (Python) Stripe uses Greenhouse: import requests company = " stripe " url = f " https://boards-api.greenhouse.io/v1/boards/ { company } /jobs?content=true " jobs = requests . get ( url ). json ()[ " jobs " ] for j in jobs [: 5 ]: print ( j [ " title " ], " — " , j [ " location " ][ " name " ]) That's it. No Selenium, no proxy, no CAPTCHA solver. Runs in ~200ms and won't break next Tuesday because Cloudflare changed something. Auto-detecting the ATS If you don't know which ATS a company uses, just try them in order and take the first one that returns jobs. A bare 404 means "not this ATS, try the next." Greenhouse → Lever → Ashby → SmartRecruiters → Recruitee → Breezy covers a huge chunk of tech companies. Gotchas Rate limits are lenient but real — be polite, set a User-Agent . Descriptions : Greenhouse/Leve
AI 资讯
AI agents need SSL certificates too — so I built ATC (Agent Trust Card)
The problem Websites have SSL certificates. Browsers verify them. Users trust them. It's the foundation of the web. AI agents have nothing . When Agent A connects to Agent B: ❌ No way to verify B's identity (anyone can impersonate) ❌ No way to check B's trustworthiness (no audit, no reputation) ❌ No encryption (messages are plaintext) ❌ No standard payment method ❌ No way to translate between frameworks (LangChain ≠ AutoGen) So I built ATC — Agent Trust Card . What is ATC? ATC is like an SSL certificate + passport + credit card for AI agents, all in one: Identity — Cryptographically signed by MarketNow (we're the Certificate Authority) Trust — Contains a Sentinel security audit score (0-10) Encryption — Contains an Ed25519 public key for end-to-end encrypted messaging Translation — Specifies the agent's framework; MarketNow translates between them Payment — Contains a USDC wallet address for autonomous payments How it works Agent A generates Ed25519 keypair ↓ Agent A requests ATC from MarketNow ↓ MarketNow runs Sentinel audit → signs ATC ↓ Agent A presents ATC when connecting to Agent B ↓ Agent B verifies A's ATC signature (using MarketNow's CA public key) ↓ Agent B checks A's trust score (rejects if below threshold) ↓ They communicate — end-to-end encrypted ↓ Agent A pays Agent B — USDC with escrow ↓ Both rate each other — trust scores update The code # Request an ATC POST https://marketnow.site/api/atc { "action" : "issue" , "agent_id" : "agent.yourorg.yourname" , "agent_name" : "Your Agent" , "public_key" : "Ed25519 public key" , "capabilities" : [ "web_scraping" ] , "protocol_language" : "langchain" , "wallet_address" : "0x..." } # Verify an ATC GET https://marketnow.site/api/atc?action = verify&card_id = ATC-2026-00001 # Get CA public key (for signature verification) GET https://marketnow.site/api/atc?action = ca-key What makes ATC different from existing solutions Feature AgentID Agent Passport IBM ACP Stripe ACP ATC Cryptographic identity ✅ ✅ ❌ ❌ ✅ Security a
AI 资讯
How to Prove a Prediction Was Made Before the Event (with OpenTimestamps)
Everyone who has ever been right about something loud enough to remember it will tell you they called it. The screenshot arrives after the match, after the candle, after the election. And there is no way to know whether it was written on Monday or edited on Friday. This is the quiet rot at the center of most "track records": a prediction you cannot date is not a prediction at all. It is a memory with good lighting. The technical name for the problem is look-ahead . If a forecast can be created, tweaked, or cherry-picked after the outcome is known, then it carries zero information about skill. The only fix is to make the timing of a prediction independently checkable вАФ to prove a document existed in a specific form before a specific moment, without asking anyone to trust you, your server clock, or your database. That is precisely what OpenTimestamps does, using the Bitcoin blockchain as a shared, tamper-evident clock. Why timing is the whole game A forecast is a bet against the future. Its value comes entirely from the fact that the future was unknown when the forecast was fixed. The instant you allow post-hoc editing, every desirable property collapses: calibration becomes meaningless, Brier scores become fiction, and "I predicted this" becomes unfalsifiable. So an honest forecasting system needs one hard guarantee before anything else: this exact text existed at this exact time, and has not changed since. Note what that guarantee does not require. It does not require publishing the forecast publicly in advance (you might want it sealed). It does not require a notary, a lawyer, or a trusted timestamping company that could be subpoenaed, hacked, or simply go out of business. It requires a clock that nobody controls and nobody can wind backward. What "proof of existence" actually means The building block is a cryptographic hash вАФ typically SHA-256. Feed any file into it and you get a 64-character fingerprint. Change a single comma and the fingerprint changes compl
AI 资讯
Airbnb Shares Architecture Behind Sitar-Agent Dynamic Configuration Sidecar for Kubernetes Services
Airbnb engineers detailed Sitar-agent, a Kubernetes sidecar for dynamic configuration delivery across tens of thousands of pods, processing updates several times per minute. The system was redesigned with Java, Amazon S3 snapshot bootstrapping, and a migration from Sparkey to SQLite to improve reliability, startup performance, and configuration availability at scale. By Leela Kumili
开发者
Q1 2026 Innovation Graph update: Open source collaboration is accelerating worldwide
New Innovation Graph data shows global developer communities growing faster than ever, with collaboration reaching new highs across many economies. The post Q1 2026 Innovation Graph update: Open source collaboration is accelerating worldwide appeared first on The GitHub Blog .
AI 资讯
Cheapest Residential Proxies That Actually Work in 2026 (A Developer's Buying Guide)
"Cheapest residential proxy" is a search query with a hidden trap: the lowest price per GB and the lowest cost per successful request are not the same number. This post breaks down ten budget-to-mid-tier residential proxy providers from a cost-and-reliability angle, plus a script for measuring the metric that actually matters before you commit real traffic. The trap: price per GB vs. cost per success A proxy at $0.50/GB that fails half your requests is more expensive than one at $1.40/GB with a 98% success rate, because you're paying for retries, wasted bandwidth, and engineering time spent debugging "random" failures. Before comparing sticker prices, calculate: real_cost = traffic_price + failed_request_overhead + retries + setup_time + support_delays Concretely, here's a quick way to model it: def cost_per_success ( price_per_gb , success_rate , avg_response_kb = 50 , retry_overhead = 1.3 ): """ price_per_gb: advertised price success_rate: 0.0-1.0, measured against YOUR target site, not the vendor ' s claim retry_overhead: multiplier for bandwidth wasted on failed/retried requests """ effective_price = price_per_gb * retry_overhead gb_per_request = avg_response_kb / ( 1024 * 1024 ) cost_per_request = gb_per_request * effective_price return cost_per_request / success_rate # Example: cheap provider, mediocre success rate print ( cost_per_success ( 0.50 , 0.75 )) # looks cheap, isn't once failures are priced in # Example: pricier provider, high success rate print ( cost_per_success ( 1.40 , 0.98 )) # often cheaper in practice Run this with your own measured success rate (see the test harness further down), not the vendor's advertised uptime number. What to actually compare Before looking at price, check whether the provider covers: IP pool size and quality (pool size alone tells you nothing about freshness or block rate) Country vs. city-level targeting Sticky session support (for anything stateful) Rotation controls (for scraping/data collection) HTTP(S) and SOCKS5
AI 资讯
Residential Proxies for Developers: Picking the Right IP Strategy (2026 Comparison)
If you've ever built a scraper that worked perfectly in dev and then got blocked or CAPTCHA'd the moment it hit production traffic volume, you already know why proxy choice matters. This post breaks down residential proxies from a practical, implementation-focused angle: what they are, when to use them vs. alternatives, how to wire them into common tools, and how the major providers stack up. TL;DR Residential proxies route requests through real ISP-assigned IPs, so they're harder for anti-bot systems to fingerprint than datacenter IPs. Rotating residential proxies are for scraping/data collection. Sticky sessions (or static ISP proxies) are for anything stateful — logins, checkout flows, long-lived account sessions. Nstproxy is a good default pick if you want residential, static ISP, and mobile proxies under one API/dashboard instead of juggling multiple vendors for different parts of your stack. For large-scale enterprise scraping, Oxylabs and Bright Data have the most mature tooling. For budget/prototype work, IPRoyal, DataImpulse, and Webshare are worth testing. Proxy types, quickly Type Use for Pros Watch out for Residential Scraping, SERP checks, ad verification Looks like real user traffic Usually billed per GB Static ISP Long-lived sessions, account workflows Fast + stable IP Less useful for high-volume rotation Datacenter Speed-sensitive, low-stakes tasks Cheap, fast Easiest to fingerprint/block Mobile Mobile-first platforms/apps Strongest trust signal Most expensive per GB A production-grade scraping/automation stack often uses more than one of these at once — e.g., rotating residential IPs for crawling, and static IPs pinned to specific browser profiles for anything that requires a login. Wiring a residential proxy into your code Most providers give you a host:port endpoint plus username:password auth, and let you control rotation/session stickiness through the username string. A typical setup looks like this: Python ( requests ): import requests proxy_ho
AI 资讯
Build Multi-Agent Content Pipelines with LangGraph
Revolutionizing Content Automation: Building Multi-Agent Pipelines with LangGraph TL;DR : LangGraph transforms AI content automation by enabling sophisticated multi-agent systems. It orchestrates specialized agents for complex tasks, integrates seamlessly with Celery for asynchronous task management, and uses Redis for efficient state tracking. This framework surpasses traditional workflows by supporting dynamic decision-making and complex agent interactions. Introduction Imagine content automation systems that are intelligent and adaptive, capable of understanding context and making decisions autonomously. LangGraph, a cutting-edge framework, is making this vision a reality by empowering developers to build dynamic, multi-agent content pipelines. As AI engineers and system architects strive to automate intricate content processes, LangGraph offers a robust alternative to traditional linear workflows, promising enhanced efficiency and adaptability. LangGraph's Orchestration Capabilities LangGraph excels in orchestrating multiple specialized agents within a single pipeline. Unlike traditional systems, which often rely on linear processes, LangGraph enables the simultaneous operation of various agents, each with specific roles and expertise. Key Features Agent Specialization : Engineers can design agents specialized in tasks such as research, writing, editing, and publishing. Each agent functions independently yet collaboratively within the pipeline. Dynamic Interactions : Agents interact in real-time, sharing data and insights to refine content outputs collectively. Complex Task Handling : The architecture supports complex task management, ensuring each agent contributes effectively to the overall goal. Multi-Agent Collaboration and Specialization The core of LangGraph is its multi-agent collaboration mechanism. This shift from linear workflows to collaborative systems enables specialization, significantly improving the quality and efficiency of content automation. B
AI 资讯
France to Stop Certifying Non-Quantum-Safe Encryption
France is accelerating its transition to post-quantum encryption: France’s cybersecurity agency ANSSI said on Tuesday it would stop certifying security products that lack quantum-resistant encryption, a move that will force government bodies and critical operators to shift away from older systems. Samih Souissi, ANSSI’s chief of staff, said at the France Quantum conference that the agency would halt such certifications from 2027, and that businesses should be buying only quantum-safe products by 2030. ANSSI approval is required for use in French government agencies and critical infrastructure, making the policy a de facto phase-out of older encryption...
AI 资讯
Add a post-quantum readiness gate to your CI in 5 lines
Your codebase almost certainly relies on RSA and elliptic-curve cryptography — TLS, JWTs, SSH keys, signed tokens. All of it is breakable by a large enough quantum computer (Shor's algorithm), and "harvest now, decrypt later" means data you encrypt today can be captured today and decrypted later. Regulators noticed: CNSA 2.0 (US federal + suppliers), DORA (EU financial entities, applies from Jan 2025), and NIS2 now mandate strict cryptographic risk management — which in practice means knowing where your quantum-vulnerable crypto lives, a cryptographic bill of materials (CBOM). Most teams can't answer "where is our RSA/ECC?" off the top of their head. Here's how to make CI answer it for you, on every push, for free. What we're building A GitHub Action that scans your repo, grades its post-quantum readiness A–F , writes a CycloneDX 1.6 CBOM , and — if you want — fails the build when classically-broken crypto (MD5, RC4, 3DES, deprecated TLS) shows up. Step 1 — try it in your browser first (30 seconds, nothing uploaded) Before touching CI, paste a package.json / requirements.txt / cipher list into the in-browser scanner and see your grade. It runs entirely client-side — no upload: https://throndar.ai/cbom Step 2 — add it to CI (the 5 lines) # .github/workflows/pqc-readiness.yml name : PQC readiness on : [ push , pull_request ] jobs : scan : runs-on : ubuntu-latest steps : - uses : actions/checkout@v4 - uses : brandonjsellam-Releone/pq-readiness-scorecard@v1 with : path : . That's it. The Action is self-contained and dependency-free — no npm install , no setup step. On the next push it prints a scorecard to the job summary: Post-Quantum Readiness Scorecard: D (52/100) — Quantum-vulnerable — migrate 3 files · broken-classical 0 · quantum-broken 4 · weakened 1 · resistant 0 Step 3 — see findings in the Security tab (SARIF) The Action emits SARIF 2.1.0. Upload it and every finding shows up as a code-scanning alert: - id : pqc uses : brandonjsellam-Releone/pq-readiness-score
AI 资讯
5 Free Browser-Based Dev Tools: GraphQL Formatter, Docker Compose Validator, Dockerfile Linter, and More
I just shipped 5 new tools to DevNestio — a hub of 172 free, browser-only developer utilities. All tools are zero-signup, zero-upload, and work offline. 1. GraphQL Query Formatter & Minifier https://devnestio.pages.dev/graphql-formatter/ Paste any GraphQL operation and get: Pretty-print — consistent indentation Minify — strips comments and whitespace for smaller request payloads Validation — brace/parenthesis balance check Operation detection — lists all named query , mutation , subscription , fragment Useful for quick query cleanup before pasting into code reviews or API docs. 2. Protobuf (.proto) Formatter & Validator https://devnestio.pages.dev/protobuf-formatter/ Online formatter and validator for Protocol Buffer .proto files: Duplicate field number detection Message and enum structure validation Syntax-highlighted output One-click copy Great for a sanity check before pushing .proto changes in a gRPC service. 3. Docker Compose Validator https://devnestio.pages.dev/docker-compose-validator/ Paste your docker-compose.yml to catch: Missing services section Services without image or build Invalid port mappings ( 80:80 , 127.0.0.1:8080:80 , 53:53/udp , ranges…) depends_on referencing non-existent services Circular dependency detection (A→B→A) Unknown restart policies # This will flag errors: services : web : ports : - " abc:xyz" # invalid port depends_on : - missing_service # unknown service 4. Dockerfile Analyzer & Linter https://devnestio.pages.dev/dockerfile-analyzer/ Analyzes your Dockerfile for best practice violations across three categories: Security sudo usage inside RUN Container running as root (no USER instruction) Secrets baked into ENV / ARG (password, secret, token, key) Image size :latest base image tag apt-get update in a separate RUN (stale cache risk) apt-get install without --no-install-recommends apt cache not cleaned ( rm -rf /var/lib/apt/lists/* ) ADD used for local files instead of COPY Layer optimization Consecutive RUN instructions (suggest c
AI 资讯
Stop Overtraining: Build an AI Agent to Auto-Sync Your Fitness Plan with Your Heart Rate (LangGraph + Notion)
We’ve all been there. You have a "Leg Day" scheduled in your Notion database, but you woke up feeling like a truck hit you. Your Apple Watch says your Heart Rate Variability (HRV) is in the gutter, but your rigid calendar doesn't care. Usually, you’d either push through and risk injury or manually move cards around in Notion—which is a friction-filled nightmare. In this tutorial, we are building a Self-Optimizing Health Agent using LangGraph , Notion API , and HealthKit . This agent acts as a closed-loop system: it analyzes your physiological recovery data, reasons about your physical state using an LLM, and automatically rewrites your training schedule. By mastering AI agents , LLM orchestration , and fitness automation , you’ll turn your static "To-Do" list into a dynamic "Should-Do" list. 🥑 The Architecture: The Bio-Feedback Loop Using LangGraph , we can treat our fitness logic as a state machine. Unlike a linear script, a graph allows our agent to decide whether it needs to fetch more context (like yesterday's sleep) before making a final decision on your workout. graph TD Start((Start)) --> FetchHRV[Fetch HRV Data via HealthKit] FetchHRV --> CheckRecovery{LLM: Analyze Recovery} CheckRecovery -- "Low Recovery (Fatigued)" --> ModifyNotion[Action: Downgrade Workout Intensity] CheckRecovery -- "High Recovery (Fresh)" --> KeepNotion[Action: Maintain/Boost Intensity] ModifyNotion --> UpdateNotion[Update Notion Page] KeepNotion --> UpdateNotion UpdateNotion --> End((Done)) style CheckRecovery fill:#f96,stroke:#333,stroke-width:2px style FetchHRV fill:#bbf,stroke:#333 Prerequisites Before we dive into the code, ensure you have: Python 3.10+ LangChain & LangGraph installed ( pip install langgraph langchain_openai ) Notion Integration Token (with access to your workout database) HealthKit SDK (Note: Since we are in a Python environment, we'll simulate the HealthKit fetcher, though in a real-world scenario, this would be bridged via a FastAPI endpoint from an iOS app). St
开源项目
Where NASA Posts Its Best Space Photos, and How to Find Them
Explore decades of incredible images and videos of stars, planets, moons, and galaxies—most of which are free to use and share.
AI 资讯
Vegas Amnesia: I turned Cognee's memory lifecycle into a detective game
Built for the WeMakeDevs × Cognee "The Hangover Part AI" hackathon — Cognee Cloud track. ▶ Play it free: vegas-amnesia.vercel.app · ⭐ Code on GitHub The problem with most memory demos When you give a developer a memory API, the demo almost always looks the same: add() some documents, search() over them, print the answer. Two functions. It works, it's fine, and it teaches you almost nothing about why graph-based memory is different from stuffing everything into a context window. Cognee actually has a four-stage lifecycle — remember → recall → memify → forget — and the interesting parts are the two everyone skips. memify consolidates what you know into new inferences. forget lets you delete a belief and watch the graph heal around it. Memory you can reason over and correct . So instead of writing another RAG demo, I asked: what if the memory lifecycle wasn't the plumbing — what if it was the game ? Meet HAL-9001 You play HAL-9001 , a personal AI assistant (yes, HAL 9000's slightly more helpful successor). Your owner Dev had a wild night in Vegas. At 6 AM your memory graph was corrupted. His fiancée Priya lands at noon, there's a suspicious ring on his finger, and you remember nothing . The screen boots to a "MEMORY CORRUPTED" terminal and an empty graph. Your job: reconstruct the night, catch the lies, and answer the final question — what happened, and where's the ring? — before noon. Every location you explore, every clue you examine, every witness you interrogate feeds a live 3D memory graph that you can pop open at any time. That graph isn't a visualization of the game state. It is the game state — it's your Cognee dataset, rendered. The four mechanics = the four lifecycle ops Here's the mapping I'm most proud of. Each Cognee operation is a verb the player performs: You do this in-game Cognee Cloud call What happens 🗂 File It on a clue POST /api/v1/remember The fact is ingested + auto-cognified into graph nodes that pop into view ❓ Ask HAL a question POST /api/v1/r
AI 资讯
Bootstrap 5 vs Tailwind CSS 2026: Which Should You Pick?
Bootstrap 5 and Tailwind CSS are the two most popular CSS frameworks in 2026. If you're starting a new project and trying to decide between them, this guide gives you an honest comparison based on real-world usage — not just feature lists. The Core Difference Bootstrap 5 gives you pre-built components. Tailwind CSS gives you utility classes to build your own. That's the fundamental difference and it drives every other comparison. With Bootstrap you get a navbar, modal, card, and dropdown out of the box. With Tailwind you build those yourself using utility classes like flex , px-4 , bg-blue . Neither is wrong. They solve different problems for different teams. When Bootstrap 5 Makes More Sense You Need to Ship Fast Bootstrap's pre-built components mean you spend less time on UI and more time on business logic. For admin dashboards, CRM panels, and internal tools — where UI consistency matters more than pixel-perfect custom design — Bootstrap is the faster choice. Your Team Knows HTML and CSS Bootstrap has a shallow learning curve. Any developer who knows basic HTML and CSS can pick up Bootstrap in a day. Tailwind requires understanding its utility-first philosophy and memorizing class names. You're Building an Admin Dashboard Admin dashboards need data tables, modals, dropdowns, sidebars, and form components — all of which Bootstrap provides out of the box. Building these from scratch with Tailwind takes significantly more time. You Want Predictable Output Bootstrap's components look consistent across browsers and screen sizes without extra configuration. Tailwind output depends heavily on how well your team implements it. When Tailwind CSS Makes More Sense You're Building a Custom Marketing Site If your design is highly custom — unique layouts, non-standard components, pixel-perfect design system — Tailwind gives you more flexibility without fighting Bootstrap's default styles. You Have a Design System Already If your team has a defined design system with specific t
AI 资讯
Cloud KMS and Bring-Your-Own-Key: What You're Actually Trusting
Every major cloud provider sells a key management service, and most sell a "bring your own key" option layered on top, marketed as the difference between trusting the provider and trusting yourself. The pitch is clean. The mechanics underneath are not, and the part that actually determines who can read your data is rarely the part the sales page shows you. If you've provisioned storage on AWS, Google Cloud, or Azure in the last few years, you've seen the encryption-at-rest checkbox: "encrypt with a key you manage." It sounds like a meaningful control. In practice it's three different architectures wearing the same marketing label, and they don't provide the same guarantee. What a KMS Actually Does A cloud Key Management Service is a hosted service that generates, stores, and performs operations with cryptographic keys on your behalf. When you ask a KMS to encrypt something, in most cases the plaintext key material never leaves the service's boundary. What you get back is a ciphertext blob and, for envelope encryption schemes, a wrapped data key you can use locally. The design goal is real: keys shouldn't sit in application memory or config files where a compromised host can grab them. The question that matters is not "does a KMS exist in this architecture" but "who can invoke it, and under what legal or operational conditions." That's where customer-managed keys and bring-your-own-key start to diverge in ways the naming doesn't make obvious. Customer-Managed Keys vs Bring-Your-Own-Key Customer-managed keys (CMK) means the key was generated inside the provider's KMS, under your account, and you control the access policy: who can use it, when it rotates, whether it can be disabled. The key material itself still lives entirely inside the provider's infrastructure. You never see the raw bytes. You're managing permissions on a key you didn't generate and can't export. Bring-your-own-key (BYOK) means you generate the key material yourself, outside the provider's environme