AI 资讯
From Demo to Production: The Guardrails That Make an AI Agent Safe to Ship
From Demo to Production: The Guardrails That Make an AI Agent Safe to Ship Hook: Most "AI agents" you see on the internet are demos. Here's the single most common reason they never reach production — and a small, open-source harness that gets past it. We are past the phase where the hard part of building an AI agent was calling the model. The hard part now is the 10% nobody talks about: what stops the agent from doing something harmful? I've seen this from both sides — I built and ran a ~25-agent platform in production at Microsoft, and now I help teams take agent ideas from a notebook to real users. The uncomfortable truth: a chatbox that can call 5 tools is not a product. The difference between a weekend project and a system you can put in front of customers is three things — and they're all boring, non-glamorous engineering: How you grade output quality (the quality gate). How you decide when a human must sign off (the approval gate). How you make the whole thing model-agnostic so you're not locked into one vendor. So I wrote a tiny harness that keeps these front and center. It's intentionally small — small enough to read in an hour — because the value isn't in a framework, it's in the pattern . Repo: github.com/zhasun0818/ai-agent-scaffold 1. The quality gate: don't ship what you can't grade An agent's output is a prediction, not a promise. Before it ships, you need a check that it passes your bar. In the harness this is a pluggable QualityGate — a rule of thumb you swap with an LLM judge or a test suite: # agent_harness/eval.py @dataclass class EvalReport : passed : bool score : float checks : List [ str ] class QualityGate : def grade ( self , proposal : str , context : str = "" ) -> EvalReport : return self . grader ( proposal , context ) The loop refuses to execute if the gate fails: result . report = self . quality . grade ( proposal , f " state= { state } " ) if not result . report . passed : self . approval . log ( " quality-gate " , " blocked " , result
AI 资讯
From Local Folder to Github: Setting Up my First Project With Git and Github: A Guide
Introduction Managing files locally or manually in your own pc gets out of hand very fast. You might find that you have a file named project_final_1 and project_final_2 which are about the same project but named differently depending on the day the projects were updated or modified. Git Bash is a command line tool that records detailed history of your code as it changes over time GitHub is an online tool where the changes in your code are stored remotely. GitHub does not use folders instead it uses repositories. The repositories make it easier for you to store your work, have a back-up of your work and also showcase your portfolio. Step 1:Installing Git First you have to install git depending on your operating system. Once installed open git bash and you have to tell Git who you are. The code below will help you set up git for the very first time git config --global user.name "put your name here" git config --global user.email "put your email here" After configuration you have to verify your installation with the code below git --version Adding SSH Key For your git to be connected to git hub you have to genarate an ssh key. The key allows your git to access your github without much stress. First you open your terminal or git bash terminal and run the code below to generate the SSH key. ssh-keygen -t ed25519 -C "enter your email here" This code will prompt you on your terminal to save the key on its default location, press enter. Next you will be prompted to enter a passphrase, for easy access and to elimate the chances of forgetting the passphrase you entered just press enter twice. Now you have a public key saved in your pc, use the command below to copy the key. cat ~/.ssh/id_ed25519.pub Adding the Key to GitHub Login into github, click on your profile picture in the top left corner and select settings . in the left navigation bar click SSH and GPG keys . Click the New SSH key button. Give a description of your key (eg .my work laptop), in the drop down menu make
AI 资讯
I’m testing a faster way to research podcast guests before an interview
A podcast host recently told me that he prepares questions from the guest’s bio using ChatGPT. That works for the basics, but a bio does not show which stories the guest has repeated across other interviews or which questions they have already answered many times. I’m helping Audiogram test a different workflow. It connects to Claude through MCP, searches Apple Podcasts, retrieves available episode transcripts, and lets Claude compare the guest’s previous answers before drafting new questions. For one test, I used two published Sam Altman interviews. The workflow pulled both available transcripts, separated recurring themes from open gaps, and produced follow-up questions around measurable evidence, privacy limits, and independent review—rather than repeating another general “will AI be good or bad?” question. The prompt is simple: Prepare an interview brief for [guest] about [interview angle]. Find podcast episodes where the guest is actually interviewed, retrieve the available transcripts, and compare them. Show recurring themes, changes in position, questions already answered, and five follow-up questions based on gaps or unsupported claims. Cite the podcast and episode for every finding. Separate transcript evidence from inference, and say what is missing when the available material is not enough. This is for research across published Apple Podcasts episodes. It is not a raw-audio editor, and transcript availability and speaker labels still need to be checked. You can see the complete recipe and tested example here: Podcast guest interview preparation with Audiogram If you prepare podcast interviews, would previous-interview comparison improve your questions, or is another part of guest research still the bigger problem? Disclosure: I’m helping Audiogram with early-user growth and used AI to help edit this post.
AI 资讯
AI Agent Standards Experiment: Test Rules Before Teams Trust Them
AI agents can look reliable after one impressive demo and still fail the moment real users, messy repositories, and conflicting instructions enter the room. The dangerous part is not that an agent makes mistakes. The dangerous part is that teams often change agent rules based on vibes, not evidence. If you are building an AI feature, internal coding agent, support assistant, research workflow, or automation layer, your standards need tests. Not just model evals. Not just unit tests. You need a way to answer a practical question: Did this new rule, skill, prompt, or tool instruction actually make the agent better? This guide shows a lightweight experiment system for AI agent standards. You can use it before rolling out new agent instructions across a product, engineering team, customer workflow, or multi-tenant AI application. No vendor pitch. No magic framework. Just a repeatable way to stop guessing. Why Agent Standards Need Experiments Most teams already have standards for human developers: code review rules security policies testing expectations deployment checklists naming conventions observability requirements AI agents need the same kind of guidance, but they behave differently from humans and traditional software. A human may read a coding standard once and remember the intent. An agent may load the wrong instruction file, ignore a rule buried deep in context, over-follow a stale example, or select no skill at all. That means the main risk is not only bad instructions. It is unreliable instruction delivery. Recent practitioner discussion around agentic development points to the same pattern: teams are moving from simple prompts toward skills, rules files, context packs, tool registries, desktop agents, and workflow harnesses. At the same time, developers are asking harder questions about governance, cost, reliability, and whether agents can be trusted with production work. What Counts as an AI Agent Standard? An AI agent standard is any reusable instruction t
AI 资讯
My First GitHub Project: From a Local Folder to GitHub Using Git and SSH
My First GitHub Project: From a Local Folder to GitHub Using Git and SSH Introduction This week I learned how to use Git, Git Bash, GitHub and setting up SSH Keys . Before this, I knew about GitHub but I did not really understand how a project moves from a folder on my computer to GitHub. A simple way I now understand the relationship is: Git manages the history of my project while GitHub provides an online home for the project. In this article, I will explain the steps I followed to create a simple project locally and push it to GitHub. Creating My Project I started by creating a folder for my project using Git Bash. mkdir Kenya-Hospital-Records-Analysis cd Kenya-Hospital-Records-Analysis Inside the folder, I created a README.md file and a folder called data . My project looked like this: Kenya-Hospital-Records-Analysis/ ├── README.md └── data/ The README.md file is where I can explain what my project is about while the data folder can be used to store datasets. In the data folder i uploaded an excel file called Kenyan_Hospital_Health_Records How to use Git The next step was to make Git start tracking my project. I did this using: git init I then used: git status This helped me see which files Git was tracking and which files had not yet been added. To add my files, I used: git add . I then saved the changes to Git using a commit: git commit -m "Initial commit" One thing I learned is that a commit is like saving a checkpoint of my project. The commit message helps explain what changes I made. Connecting Git to GitHub while generating SSH Keys To push my local project to GitHub, I needed a secure way for my computer to communicate with my GitHub account. I used SSH (Secure Shell). I first generated an SSH key on my computer and then added the public key to my GitHub account. An SSH key normally consists of two parts: Private key – stays securely on my computer. Public key – can be added to GitHub. One important lesson was that the private key should never be shared.
AI 资讯
Buildroot for Embedded Linux — Part 1: Your First Buildroot Root Filesystem
Buildroot builds a cross-compiler, a Linux kernel and a complete root filesystem from source, driven by one Kconfig-style configuration file. Starting from the qemu_arm_vexpress_defconfig that ships with Buildroot 2026.05.1, two commands produce a bootable ARM system you can run under QEMU. The images you ship are the ones in output/images/ ; output/target/ looks like a root filesystem but must never be copied to a device. This post starts a new hands-on series on Buildroot for embedded Linux. By the end of this part you will have built a working Buildroot root filesystem for an ARM target, booted it under QEMU, and understood which generated directories are safe to ship. Later parts add your own packages, a BR2_EXTERNAL tree, kernel and bootloader integration, and reproducible image output. If the choice between build systems is still open, our earlier Yocto vs Buildroot comparison covers it; this series assumes the decision is made. What you need A Linux host, several gigabytes of free disk space, and a network connection. No development board is needed for this part; QEMU stands in for the hardware. On a Debian or Ubuntu host, this covers the mandatory packages the manual lists, plus the ncurses development files that menuconfig needs: raghu@techveda.org:~$ sudo apt install build-essential diffutils patch gzip bzip2 perl tar cpio unzip rsync file bc findutils gawk wget libncurses-dev One rule from the manual is worth stating plainly: build everything as a normal user. Buildroot never needs root, and running it as root exposes your host to any package that misbehaves during installation. The command above is the only one in this post that uses sudo . Getting Buildroot and choosing a target Download and unpack the current stable release — 2026.05.1 at the time of writing — from buildroot.org/downloads , and work from that directory. Buildroot ships ready-made configurations for many boards and emulated machines, one file each in configs/ , and make list-defconfigs
AI 资讯
Creating Bluesky starter packs from code: three AT Protocol records and one non-idempotency trap
Bluesky starter packs look like a single thing in the app — a shareable page that lets a new user follow a curated group in one tap. At the protocol level they are three separate records glued together by references, and if you create them from code (we do, as part of an automated outreach pipeline), the decomposition matters: it decides what you can update later, what you can only create once, and where a naive script will quietly make a mess. The three records Everything below is plain com.atproto.repo.createRecord / putRecord calls against your own PDS — no special API surface. 1. The list — app.bsky.graph.list . A starter pack is backed by an ordinary Bluesky list with purpose: app.bsky.graph.defs#referencelist . The list record itself holds metadata — name, purpose, createdAt, plus optional description and avatar. Members live elsewhere. 2. The memberships — app.bsky.graph.listitem . One record per member, each holding the member's DID and the list's AT-URI. There is no "add 20 members" batch call in the record layer: twenty members means twenty listitem creates. Plan for partial failure in the middle of that loop — more below. 3. The pack — app.bsky.graph.starterpack . The record that makes the share page exist. Per the lexicon, name , list , and createdAt are required; list is the AT-URI of the referencelist from step 1, the name is capped at 50 graphemes, and optional feeds can attach custom feeds. The official limits: up to 150 people, up to 3 feeds. The share URL is derivable, not returned: https://bsky.app/starter-pack/{your-handle}/{rkey} where {rkey} is the tail of the starterpack record's AT-URI. The trap: creation is not idempotent Every createRecord mints a fresh rkey. Run your create-starter-pack script twice and you have two packs with two URLs, both live, both indexed — and the one you already shared is not the one your script now reports. There is no natural key (like a title) that the protocol dedupes on. Our rules after learning this: Creation
AI 资讯
Understanding the Git Workflow: Working Directory, Staging, Commit and Push
Working through a practical reference to moving a change through Git took me through the process of taking a single change from my local computer, committing it in Git, and pushing it to GitHub where others would be able to see it. This was written for complete Git Novices and so I approached it without any prior experience of using Git. By the end, you will be able to move a change through all four Git stages and confirm it's visible on GitHub with a clear commit history. Who This Is For Anyone that want to work with Git in the terminal Users who find git add , git commit , and git push unclear No prior Git experience required Prerequisites Git installed ( git --version to check) A terminal or command-line application A GitHub account (create one if needed) We'll use a small sales data project as a running example. You do not need Python or Pandas installeda as we will be only tracking files, not running code. The Four-Stage Flow Every change travels in one direction: Working Directory → Staging Area → Local Repository → Remote Repository Working directory : where everything is worked on Staging area : choosing what goes in Commit : your historical record for everything worked on Push : share it so collaborators can see it Setup: Initialize a Repository Create a project folder and make it a Git repository: mkdir monthly-sales cd monthly-sales git init Expected output: Initialized empty Git repository in /path/to/monthly-sales/.git/ git init creates a hidden .git folder where Git stores the entire history. From now on, Git watches this folder. Usage 1. Working Directory (Untracked Files) Create a raw data file: echo "date,region,revenue" > sales_data.csv echo "2026-01-01,East,1200" >> sales_data.csv Check its status: git status Expected output: On branch main No commits yet Untracked files: (use "git add <file>..." to include in what will be committed) sales_data.csv Untracked means Git can see the file but isn't following it yet. This is the default for new files.
AI 资讯
My First GitHub Project.
Introduction People, especially beginners, face challenges when making changes to their projects and pushing those changes to Github. Some of the challenges faced include Git command, authentification, configuration etc. This article aims to explain the process of building a Github project, from creating local directories/folders to uploading the project to Github using Git and secure shell(ssh). I will use a project titled Poor Performance in 2025 National Exams as a case example to illustrate the steps involved in creating a project. The process is outlined in the following steps: STEP 1: Creating directories The first step of a project is to establish a well organized directory structure. This helps keep project files organized logically, making them easier to manage, access and maintain throughout the development process. We create our project directories within Desktop and OneDrive. Desktop is basically a special directory used by windows to store files and shortcuts while OneDrive is a microsoft's storage store. In our case we start by navigating to the desktop directory using Git. For example, cd desktop means 'go to desktop' Next, Use ls to list all the directories and files in desktop. Once you have navigated the desktop directory, Proceed to making your first project directory. We use mkdir commandto create a new directory. For example, mkdir "Poor-performance-in-2025-National Exam" . Next, we create additional directories within our newly created project directory. In this case we will create a directory called Data, which will store the datasets required for the analysis. For example, mkdir data STEP 2: Creating Files Files are essential part of building a project. In this step, we will create a README.md file. A README.md gives an overview of the project and describes its purpose, structure and usage in a clear and understandable way. README.md is written using Markdown language. we use touch to create files. For example, touch README.md STEP 3: Printin
开发者
Forms in React : From Inputs to Controlled Components
You have probably written HTML forms before, and so the structure below resonates with you. Perhaps you even smile because, this one, you understand. <form> <input type= "text" /> <button> Submit </button> </form> If you have done this, you know what happens when you click the button. The whole form reloads, the changes or inputs are cleared. This is the default behavior of forms in HTML. In React, we handle every step and every stage so that we have control over the data and the behavior of the form and data. The above signature represents what we call UNCONTROLLED INPUT . This means that there isn't a single source of truth to the value of this field, hence it can change to anything, and any value In addition to the above attributes, we will add value and onChange props to the input element as below: <input type= "text" value= {} onChange= {}/ > value represents the content of the input field e.g. the name text that the user enters in a Name field. onChange is the function that will be triggered everytime the input changes. Whenever a key is pressed within this field, this function will be invoked. Controlled inputs have their values set and manipulated by states, as we saw in Part 1 of the series. Uncontrolled inputs on the other hand do not have a manager that will dictate what goes into the field and when. Now let's write our first React Input, we'll keep it simple. import { useState } from " react " function Form (){ const [ name , setName ] = useState ( "" ) return ( < input type = " text " value = { name } onChange = {( event ) => setName ( event . target . value )} / > ) Let's look at what happens in the above. We have declared a state [name,setName] . name is the state variable setName is a function used to update the variable We then initialized an input element with properties value and onChange Note that, when the value of an input is set, that will always be the value even if you type something into the box. That is the essence of controlled input. The
AI 资讯
How to limit Instagram from using your data for AI and ads
You can keep Instagram from using your activity outside the app to influence the ads you get.
科技前沿
US battery startups have found a lifeline in defense
U.S. battery startups pulled in $500 million in grants from the Department of Energy, throwing a lifeline to an industry that was on the ropes after EV incentives were slashed.
AI 资讯
MY FIRST GITHUB PROJECT
Introduction In this article I will explain my practical experience of creating Git repository,connecting it to GitHub using SSH,commiting my files and pushing the project to a remote repository. Step 1 :Creating My Local Project The first step is to create a folder through file explorer which as the best option for me and name it (my-project) Next step was to open GitBash and run the command cd my- project To open the file directory Step 2 : Initializing Git This is to tell Git that my my-project folder should become a Git repository. To initialize Git I ran the command: git init Step 3:Repository Status Check After initializing Git, I used : git status This command is very useful as it can be used throughout the process it tells what's happening inside my repository. At some point people may encounter: On branch main Nothing to commit, working on a tree clean It could seem like an error,however I learned that this means Git has checked my project and found no changes that need to be committed. Another situation that I encountered is where Git told me that the older my project was already initialized .This taught me to use the command: git status To understand the current status of my project. Step 4:Connecting GitHub Using SSH The next thing I learnt was on how to generate SSH key which will be used to connect my computer securely to GitHub. To generate an SSH key I ran the command: ssh-keygen -t ed25519 -C "your_email@example.com" Under the double quotes use the email used for your GitHub account. Then press entre to save it on the default location. You'll then be told to enter passphrase which is simply a password,create a simple one which you can memorize easily like 1234.Then entre it again when asked. You then start the SSH agent Run; eval "$(ssh-agent -s)" Then add your SSH keyy Run: ssh-add ~/ .ssh/id_ed2559 It will ask you to entre the passphrase you created. Copy your public key y running the command: cat ~ .ssh/id_ed25519 .pub Add the entire line generat
AI 资讯
Token Budget Alarm on a Free Server
A free model quota is a budget, not a gift. You should treat it like one if you plan to build anything on top of it. I learned this the hard way when my prototype stopped responding in the middle of a demo. I had silently burned through the monthly allowance, and the provider cut me off without warning. This article shows how I built a small token budget alarm on a free server. It watches a free model's usage and warns me before the quota runs out. Most developers track their cloud spend religiously but ignore the token consumption of free models. The free tier feels like a gift, so we assume it will last forever. Then the provider cuts us off at the worst moment, and we scramble to find the cause. A token budget alarm removes that uncertainty by measuring your actual burn rate. It projects the exhaustion date and alerts you before you hit the wall. The design is deliberately small: a reverse proxy sits in front of the model endpoint. It records the token usage from every response and stores it in a local database. A background thread then computes the average consumption over a sliding window. It compares that rate against the remaining allowance and fires a webhook when the projection looks dangerous. You can run this entire stack on a free server, which is exactly what I did with MonkeyCode's free server option. Disclosure: This article was prepared as part of MonkeyCode's product outreach. The proxy itself is a tiny Flask application that forwards requests to the model. It extracts the usage field from each response and records the token count. If your provider does not return a usage object, you can estimate the token count with a simple heuristic. Dividing the character count by four is a rough but workable approximation. The important part is that every request is accounted for, because a single long prompt can consume more than a hundred small ones. from flask import Flask , request , Response import requests import sqlite3 import time app = Flask ( __name__
AI 资讯
Picking an eQMS for a 200-person Class II device shop — a pragmatic comparison
I work in a 200-person Class II medical device company with two QA/RA folks, three embedded-hardware teams, a small supplier-quality group, and engineers who want automation — not more paperwork. We needed an eQMS that unifies design control (DHF), CAPA, supplier records, and traceability into something engineers will actually use. I evaluated several vendors and want to share a short, practical comparison for teams with that shape. A quick regulatory framing before the list Standards that mattered to us: ISO 13485 and 21 CFR 820, plus MDR-adjacent traceability requirements for components when applicable. A note on risk and regulation posture: don’t treat Article 50 (AI oversight posture for medtech tools) like an apocalypse — it sits in the general enforcement stack. Plan for reviewability and traceability for any AI-assisted workflows, but don’t let fear of hypothetical fines block good tooling decisions today. What I judged vendors on Fit for medtech design control / DHF workflows Traceability across requirements, risk, design, and CAPA Integrations — especially with CRM/supplier systems and engineering tools Operational fit for a 200-person org (configurability, onboarding burden) Capacity for process automation (automated CAPAs, connected workflow) The list — what each vendor practically means for a team like mine 1) Greenlight Guru Why I put it first: Greenlight Guru explicitly lists medical-device as its industry. For a Class II shop that needs DHF, design-control-native workflows, and templates tuned to medtech terminology, that industry focus matters. Fit: Strong for device-focused workflows and teams that want a medtech-first product experience rather than a generic QMS. When to pick: You want a purpose-built medtech experience, quicker ramp for QA/engineering, and vendor docs/templates that speak design control and DHF. 2) Qualio Public positioning: Qualio serves general industries including medical-device and pharma. Fit: Good option if you want flexibil
AI 资讯
Pydantic AI keeps one growing message list per run — and re-sends the whole thing every step
Pydantic AI gives you a clean, typed agent: define an Agent , hand it tools, call agent.run(...) , and it loops — model call, tool call, model call — until it produces a validated result. The typed ergonomics are great. What the quickstart doesn't spell out is what the model receives on each pass of that loop. I read the run graph ( pydantic_ai_slim/pydantic_ai/_agent_graph.py on main ) to find out. The mechanism is structural, and it's the same shape I found in the OpenAI Agents SDK and smolagents. One list, appended twice per turn Each run holds a single mutable conversation list on its state: message_history : list [ _messages . ModelMessage ] = dataclasses . field ( default_factory = list [ _messages . ModelMessage ]) On every model step the graph appends to it — first the outgoing request, then the model's response: ctx . state . message_history . append ( self . request ) ... ctx . state . message_history . append ( response ) Nothing is removed. The list only grows: request, response, request, response — with tool calls and, crucially, tool outputs riding inside those messages. The full list is re-sent every step When the graph builds the input for the next model call, it takes the entire accumulated history — a full copy: messages = ctx . state . message_history [:] ... messages [:] = _clean_message_history ( ctx . state . message_history ) That [:] is the whole conversation to date. So on step 1 the model sees your prompt; on step 2 it sees your prompt + step 1's request + step 1's response (including the tool output); on step 5 it sees all of that plus steps 2–4. The payload you pay for grows every single step, and the heaviest passengers are usually the tool outputs — the search results, file contents, and API responses you least want re-uploaded five times. Why it's quadratic, and why nothing warns you A run of n steps sends roughly 1 + 2 + 3 + … + n copies of history — O(n²) cumulative tokens in the step count. A 3-step agent is fine. A 12-step agent th
AI 资讯
The Exact Funnel I Use to Get Free CLI Tools Their First Users
Every open-source tool has the same brutal first 90 days: zero users, zero signal, no idea whether anything works. I have shipped several free CLI tools and browser tool sets. This is the exact funnel I use — no ads, no paid growth, no "build in public" theater. Just a repeating sequence of small, concrete actions. Step 1: Make the Tool Trivial to Try The first rule: npx must work. If a reader has to install, configure, and read a README before running the first command, the funnel is already broken. npx @wuchunjie/dotguard . That is the entire onboarding. Zero dependencies, no config, instant output. The first 10 seconds decide whether the reader comes back. Step 2: Publish One Article Per Angle Not one article. One per angle , spread over time: Tutorial — "Scan your .env files in 1 command" (the how) Comparison — "Why I stopped using X" (the why) Listicle — "5 tools for Y" (the discovery) Workflow — "My dev setup" (the context) Security/devops — "Your CI is missing this" (the fear) Each article targets a different search intent. A developer looking for "pre-commit secret scan" lands on article 4, not article 1. The funnel is wide because the angles are wide. Step 3: Cross-Link Everything Every article mentions every tool. The footer of a snippet article lists the scaffolder and the scanner. The GitHub repo links to the articles. The npm README links to the articles. The effect is compounding: a reader of article 3 meets four tools, not one. Your content becomes a network instead of a pile. Step 4: Make the GitHub Repo the Hub The repo README is the landing page that never goes stale: One-line description per tool Install/run commands (copy-paste ready) Links to every article A donation link, present but quiet GitHub is where developers actually trust. Stars and forks are the signal that converts "interesting article" into "let me try it". Step 5: Add the Quiet CTA One line at the end of every article: If this saved you time, a Ko-fi keeps the next tool coming. No
AI 资讯
I built an OLX scraper for 24 countries — the boring version that actually ships
I built an OLX scraper for 24 countries — the boring version that actually ships OLX runs classifieds in about two dozen countries. Same brand, different domains, different anti-bot setups. Everyone scraping it does one country at a time. I got tired of forking. So I put 24 countries behind one input. country: "id" or country: "pl" or country: "br" — same schema out. It's live on Apify as primesieve/olx-global-scraper . One file. No browser. Here is the boring part that matters. What it does Input: { "country" : "id" , "keywords" : [ "iphone 13" ], "maxResults" : 50 , "maxPages" : 3 , "proxyConfiguration" : { "useApifyProxy" : true , "apifyProxyGroups" : [ "RESIDENTIAL" ] } } country — two-letter code ( id , pl , in , br , ua , pt , ro , bg , kz , uz , pk , za , ng , ke , eg , lb , ph , co , ar , pe , ec , gt , az , ma ). Default id . keywords — one or more search terms. Each runs sequentially. maxResults / maxPages — caps. Defaults 50 / 3, max 1000 / 30. proxyConfiguration — optional for Indonesia, required for the other 23. Output — same shape every country: { "listingId" : "123456789" , "title" : "iPhone 13 128GB mulus" , "price" : 6500000 , "priceText" : "Rp 6.500.000" , "currency" : "IDR" , "city" : "Jakarta Selatan" , "location" : "Tebet, Jakarta Selatan, DKI Jakarta" , "images" : [ "https://...jpg" ], "thumbnailUrl" : "https://...jpg" , "listingUrl" : "https://www.olx.co.id/item/123456789" , "country" : "id" } Title, price (numeric plus display text), currency, location, images, URL. No seller PII beyond what the listing page shows. No tricks. Try: https://apify.com/primesieve/olx-global-scraper The boring stack // no playwright, no puppeteer // apify + fetch + cheerio. That's it. The scraper is one file. Apify SDK for input, dataset, and pay-per-event. Native fetch for HTTP. cheerio for the HTML path. Undici ProxyAgent when a proxy is configured. Node 20, 512 MB, 600s timeout. I check the endpoint before I write the scraper. Indonesia answered with clean JSO
AI 资讯
Cómo solucionar el error “Enable JavaScript and cookies to continue”
Cómo solucionar el error “Enable JavaScript and cookies to continue” Este mensaje aparece cuando Cloudflare (u otro proxy de seguridad similar) bloquea la solicitud porque detecta que el cliente no cumple con los requisitos mínimos de seguridad: JavaScript deshabilitado o cookies deshabilitadas/expiradas . 🔍 Causa técnica Cloudflare implementa mecanismos de protección como: JavaScript Challenge : El navegador debe ejecutar un script para demostrar que no es un bot. Cookie de verificación : Tras superar el desafío, Cloudflare emite una cookie ( __cf_bm o cf_clearance ) que valida la sesión. Si el cliente (navegador o cliente HTTP personalizado) no ejecuta JavaScript o no maneja cookies correctamente, la validación falla y se muestra este mensaje. ✅ Solución definitiva (por escenario) 🌐 Si eres un usuario final (navegador) Habilita JavaScript : Chrome: Configuración > Privacidad y seguridad > Sitios web no seguros > Habilitar JavaScript . Firefox: Preferencias > Privacidad y seguridad > Permisos > Habilitar JavaScript . Habilita cookies de terceros (si usas extensiones como uBlock Origin o Privacy Badger): Añade el dominio a la lista blanca. Desactiva temporalmente los bloqueadores para probar. Borra cookies y caché del dominio afectado. Reinicia el navegador y vuelve a cargar la página. 🧪 Si eres desarrollador (automatización / scraping / cliente HTTP) ❌ No uses requests o curl sin soporte JS/cookies → fallarán siempre . ✅ Opción recomendada: Usa un navegador headless con soporte JS y cookies # Ejemplo con Playwright (recomendado) from playwright.sync_api import sync_playwright with sync_playwright () as p : browser = p . chromium . launch ( headless = True ) context = browser . new_context () page = context . new_page () # Navega a la URL (Cloudflare se resolverá automáticamente) page . goto ( " https://ejemplo.com " , wait_until = " networkidle " ) # Si aún falla, fuerza espera tras el desafío try : page . wait_for_selector ( " #challenge-error-text " , timeout = 5
AI 资讯
Autonomous AI Study Notes: A Multi-Agent System with LangGraph and Streamlit
This post is my submission for DEV Education Track: Build Multi-Agent Systems with ADK . What I Built I built an Autonomous Multi-Agent Handwritten Notes Generator . Students and educators often need clean, visual study guides that resemble real handwritten notes, but manually summarizing technical subjects and formatting them takes hours. This system solves that by combining autonomous web research, structured note extraction, and headless browser rendering. You enter any topic or question, and a coordinated team of AI agents researches the concept, formats it into a notebook layout using Google handwriting fonts ( Caveat ), and captures a high-resolution .png notebook page screenshot. Deployment & Repository Links: GitHub Repository: himanshuyeolecse-jpg / multi-agent-handwritten-notes An autonomous multi-agent system built with LangGraph, Tavily, and Playwright that researches complex topics and renders handwritten-style student study notes into PNG screenshots. multi-agent-handwritten-notes An autonomous multi-agent system built with LangGraph, Tavily, and Playwright that researches complex topics and renders handwritten-style student study notes into PNG screenshots. 🎓 Multi-Agent Handwritten Notes Generator An autonomous multi-agent workflow built using LangGraph , LangChain , Tavily Search , and Playwright . The system researches complex technical concepts and dynamically compiles the findings into styled, handwritten-notebook PNG screenshots. 🏗️ System Architecture [ User Input / Prompt ] │ ▼ [ Researcher Node ] ── (Tavily Web Search & Summarization) │ ▼ [ Note Renderer Node ] ── (HTML/CSS + Google Caveat Font + Playwright Screenshot) │ ▼ [ Critic Node ] ── (Validation Check: Is Output Complete?) │ Approved? ──► No ──► [ Researcher Node ] │ Yes ▼ [ PNG Screenshot Saved ] ⚡ Features Autonomous Research: Uses Tavily API to fetch up-to-date technical context. Dynamic HTML/CSS Rendering: Formats structured summaries into a paper-notebook layout utilizing… View o