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

标签:#ia

找到 1567 篇相关文章

开源项目

Docs as Code: Build a CI/CD Pipeline for Your Documentation

Your code has CI/CD. Your docs don't. Every modern engineering team has automated builds, tests, and deployments for their code. But documentation? That's still someone manually exporting a PDF, uploading it to Confluence, and hoping it's the latest version. This post shows you how to treat documentation like code: version-controlled Markdown in a Git repo, automatically rendered to branded PDFs on every push. No manual steps, no stale documents. The stack PaperQuire gives you three tools that work together: .paperquire.yml — project config that locks in your template, branding, and document options CLI — paperquire render and paperquire batch for scripting and local builds GitHub Action — paperquire/render-action for automated builds in CI Each one builds on the previous. The config file means no one has to remember flags. The CLI means you can test locally. The action means it happens automatically. Step 1: Add a project config Drop a .paperquire.yml in your repo root. Every render — GUI, CLI, and CI — picks up these settings automatically: template : corporate toc : true toc-depth : 3 h1-page-break : true cover : title : " Project Documentation" author : " Engineering Team" branding : primary-color : " #2563eb" This is your single source of truth for how documents look. Change it once, and every PDF across every environment updates. Step 2: Test locally with the CLI Before committing, verify your docs render correctly: # Render a single file paperquire docs/architecture.md -o out/architecture.pdf # Batch render the entire docs directory paperquire batch ./docs -o ./out # Dry run — validate without producing output paperquire batch ./docs --dry-run The CLI reads .paperquire.yml automatically. The output is identical to what CI will produce. Step 3: Automate with the GitHub Action Add one workflow file and your docs build themselves: # .github/workflows/docs.yml name : Build Documentation on : push : paths : - ' docs/**/*.md' - ' .paperquire.yml' jobs : render : ru

2026-06-26 原文 →
AI 资讯

How to Stream & Flatten 1GB+ JSON to CSV in the Browser Without Memory Leaks

As developers, data engineers, or analysts, we’ve all been there: you download a massive database export, a logging stack dump, or a transaction archive, only to find it's a multi-gigabyte JSON file. You try to import it into a spreadsheet or run it through a standard online converter, and boom—your browser tab freezes, crashes, or shows the dreaded "Out of Memory" screen. Even worse, if you try to use standard cloud-based online tools, you might have to wait for a 500MB upload to complete, only to hit a rigid file-size cap or, worse, compromise sensitive data privacy by uploading corporate logs or database records to a third-party server. In this guide, we will explore: Why large JSON files crash standard parsers (the V8 heap limit problem). How streaming architectures solve this by reading data chunk-by-chunk. NDJSON (JSON Lines) vs. JSON Arrays and how to stream them. A browser-native, 100% offline tool to convert large JSON to CSV instantly: Parsify's Large JSON Stream Converter . How to implement your own basic browser-based JSON streaming parser in JavaScript. 1. The Anatomy of a Memory Crash (Why JSON.parse Fails) If you are using JavaScript or Node.js, the simplest way to read and parse a JSON file is to load the file into memory and run JSON.parse(). const fs = require ( ' fs ' ); // Naive approach: Will crash on a 1GB+ file fs . readFile ( ' database-dump.json ' , ' utf8 ' , ( err , data ) => { if ( err ) throw err ; // POINT OF FAILURE: V8 Heap Out of Memory const records = JSON . parse ( data ); records . forEach ( record => { // Process record... }); }); This works fine for small config files. But once your JSON file reaches 100MB, 500MB, or 1GB+, this approach is guaranteed to trigger a fatal crash: FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory Why does this happen? The String Duplication Overhead: When you load a 1GB file into memory, you first allocate ~1GB of RAM for the raw text string. The

2026-06-26 原文 →
AI 资讯

Creating Short Links with PHP: A Practical Guide

Creating Short Links with PHP: A Practical Guide URL shorteners are everywhere. They're used in marketing campaigns, email newsletters, QR codes, social media posts, affiliate links, and analytics platforms. While most developers are familiar with services like Bitly, integrating a URL shortener directly into your application is often much more useful. In this article, we'll build short links from PHP using an API. Why Create Short Links Programmatically? Creating links through a dashboard works for occasional usage. But applications often need to generate links automatically. Common examples include: Email campaigns User invitations Affiliate systems QR code generation Marketing automation Analytics tracking Customer portals An API allows applications to create and manage links without human interaction. The Traditional HTTP Approach Most URL shortener APIs work through simple HTTP requests. For example: $client = new GuzzleHttp\Client (); $response = $client -> post ( 'https://example.com/api/links' , [ 'headers' => [ 'X-Api-Key' => $apiKey , 'Content-Type' => 'application/json' , ], 'json' => [ 'url' => 'https://example.com/article' ] ] ); $data = json_decode ( $response -> getBody (), true ); echo $data [ 'short_url' ]; This works. But once your application creates dozens or hundreds of links, the amount of boilerplate code starts growing. Using a PHP SDK A PHP SDK removes most of the repetitive work. Installation is usually straightforward: composer require lix-url/php-sdk Creating a link becomes much simpler: $link = $client -> links () -> create ([ 'url' => 'https://example.com/article' ]); echo $link -> shortUrl ; The SDK handles: Authentication HTTP requests Response parsing Error handling DTO mapping This allows your application code to remain clean. Creating Your First Short Link Let's imagine an application that sends invitation emails. $inviteLink = $client -> links () -> create ([ 'url' => 'https://myapp.com/invite/abc123' ]); echo $inviteLink -> short

2026-06-26 原文 →
AI 资讯

Cara pakai API Claude & DeepSeek dari Indonesia — bayar Rupiah via QRIS (tanpa kartu kredit)

Disclosur: Ini dari tim Nexotao — saya bahas gateway kami sendiri di bawah. Saya jaga sebatas fakta yang bisa kamu cek sendiri: semua nama model, context window, dan harga ada di halaman pricing kami, dan saya kasih linknya. Kalau kamu developer di Indonesia, kemungkinan besar pernah kejedot ini: API OpenAI dan Anthropic minta kartu kredit luar negeri . Nggak punya kartu, nggak bisa pakai API. Banyak dari kita mentok di situ. Solusi yang jalan sekarang: gateway lokal yang nerima QRIS / Rupiah . Ini versi jujurnya — gimana cara kerjanya, berapa biayanya, dan apa yang belum bisa. Dua model live, satu API yang kompatibel Lewat Nexotao kamu pakai dua model teks: Claude Opus 4.8 ( claude-opus-4-8 ) — context window 350.000 token DeepSeek-V4-Pro — context window 131.072 token Itu angka context window yang dipublikasikan apa adanya — tanpa pemotongan diam-diam. Endpoint-nya kompatibel dengan OpenAI dan Anthropic , jadi biasanya cukup ganti base URL sama key-nya. Format OpenAI: from openai import OpenAI client = OpenAI ( base_url = " https://api.nexotao.com/v1 " , api_key = " sk-nexo-... " ) resp = client . chat . completions . create ( model = " claude-opus-4-8 " , messages = [{ " role " : " user " , " content " : " Halo " }], ) print ( resp . choices [ 0 ]. message . content ) Format Anthropic: curl https://api.nexotao.com/v1/messages \ -H "x-api-key: sk-nexo-..." \ -H "anthropic-version: 2023-06-01" \ -H "Content-Type: application/json" \ -d '{"model":"claude-opus-4-8","max_tokens":256, "messages":[{"role":"user","content":"Halo"}]}' Cara bayarnya Top up saldo Rupiah via QRIS , mulai Rp10.000 . Tanpa kartu luar negeri. Bayar sesuai pakai — dipotong per token. Tanpa langganan , dan saldo nggak hangus. Tiap response ada header X-Cost-Rp , jadi kamu lihat biaya rupiah persis tiap request. Berapa biayanya Saat tulisan ini dibuat, Claude Opus 4.8 lewat gateway sekitar 70% lebih murah dari harga retail resmi (input) — tapi jangan percaya saya gitu aja. Halaman perbandingan har

2026-06-26 原文 →
AI 资讯

How to use the Claude & DeepSeek APIs from Indonesia — pay in Rupiah via QRIS (no credit card)

Disclosure: This is the Nexotao team — I'm describing our own gateway below. I've kept it to facts you can verify yourself: every model name, context window, and price here is on our live pricing page, and I link it. If you're an Indonesian developer, you've probably hit this wall: the OpenAI and Anthropic APIs want a foreign credit card . No card, no API. A lot of us get stuck right there. The fix that works today: a local gateway that takes QRIS / Rupiah . Here's the honest version of how it works, what it costs, and what it doesn't do. Two live models, one compatible API Through Nexotao you call two text models: Claude Opus 4.8 ( claude-opus-4-8 ) — context window 350,000 tokens DeepSeek-V4-Pro — context window 131,072 tokens Those are the real, published context windows — no silent truncation. The endpoint is OpenAI- and Anthropic-compatible , so you usually just change the base URL and key. OpenAI format: from openai import OpenAI client = OpenAI ( base_url = " https://api.nexotao.com/v1 " , api_key = " sk-nexo-... " ) resp = client . chat . completions . create ( model = " claude-opus-4-8 " , messages = [{ " role " : " user " , " content " : " Hello " }], ) print ( resp . choices [ 0 ]. message . content ) Anthropic format: curl https://api.nexotao.com/v1/messages \ -H "x-api-key: sk-nexo-..." \ -H "anthropic-version: 2023-06-01" \ -H "Content-Type: application/json" \ -d '{"model":"claude-opus-4-8","max_tokens":256, "messages":[{"role":"user","content":"Hello"}]}' How you pay Top up your Rupiah balance via QRIS , from Rp10,000 . No foreign card. Pay-as-you-go — deducted per token. No subscription , and the balance never expires. Every response carries an X-Cost-Rp header, so you see the exact rupiah cost of each request. What it costs At the time of writing, Claude Opus 4.8 runs roughly 70% below official retail input pricing through the gateway — but don't take my word for it. The comparison page shows live per-token rates and computes "vs official" automati

2026-06-26 原文 →
AI 资讯

Deploying a Containerized Backend to a VPS with Docker Compose + GitHub Actions (A Beginner's Runbook)

This is a complete, copy‑pasteable guide for shipping a backend app to a single Linux server using Docker Compose , with a GitHub Actions pipeline that builds the image, scans it, and deploys it over SSH. It is written to be language- and framework-agnostic . The examples use a Node/TypeScript API with PostgreSQL, Redis, and a background worker, but the same shape works for Python/Django, Go, Java/Spring, Ruby, etc. Anywhere you see your-app , your-org , your-server-ip , or example.com , substitute your own values. Every file is included in full, and every non-obvious line is explained. The last section — Common errors and how to fix them — is the part most guides skip, and it is the part that will actually save your afternoon. All of it comes from a real deployment, mistakes included. 1. The mental model (read this first) Before any YAML, understand the shape of what we're building. There are only three places anything lives: Your Git repository the single source of truth. Your code, your Dockerfile , your docker-compose.prod.yml , and your CI/CD workflows all live here. You only ever edit things here. A container registry (we use GHCR, GitHub's built-in registry) — a warehouse for the built application image. CI builds the image and pushes it here. Your server (a plain Linux VPS) pulls the image from the registry and runs it. It holds exactly two files: the compose file (copied from your repo by the pipeline) and a secrets file ( .env ) that never leaves the server. The flow, end to end: You push to main │ ▼ GitHub Actions: build image ──► push to registry ──► scan image │ ▼ GitHub Actions: SSH to server ──► pull image ──► run migrations ──► start app ──► health-check The single most important rule: the server is disposable . You never hand-edit files on the server, because the pipeline overwrites them from the repo on every deploy. If you fix something by editing on the server, the next deploy silently erases your fix. Edit in the repo, commit, push. (I learned t

2026-06-26 原文 →
开发者

🍼 宝宝的小仓库 —— 幼师带你认识"NAS"

🌟 开场白:你有没有这样的烦恼? 小朋友们,有没有遇到过这种情况: 📱 手机里的照片太多, 装不下了 ! 💻 电脑里的视频, 换了电脑就找不到了 ! 👨‍👩‍👧 爸爸妈妈爷爷奶奶,想看同一个视频, 要互相发来发去 ! 有没有一个地方, 所有人都能存东西、随时取东西 ? 有!那就是 —— 🏠 NAS N etwork A ttached S torage 网络附加存储 (但老师觉得叫它 "家庭小仓库" 更好懂!) 🎒 第一课:NAS到底是个啥? 先想象一个场景 👇 幼儿园有个 大储物柜 🗄️ 每个小朋友都有 自己的格子 在教室里、在走廊里、甚至在家里 只要知道密码,随时可以取东西! 老师也可以把作业放进去,大家一起看 这个 "随时随地都能访问的大储物柜" ,就是 NAS ! 👩‍🏫 老师比喻总结: 普通硬盘 NAS 只插在一台电脑上用 接在路由器上,全家都能用 只有这台电脑能访问 手机、平板、电脑都能访问 出门就用不了 出门在外也能访问 🌍 像你自己的小书包 🎒 像幼儿园的公共储物柜 🗄️ 🏗️ 第二课:NAS长什么样? NAS其实就是一台 特别的小电脑 🖥️ 普通电脑 = 有屏幕、键盘、鼠标 NAS = 没有屏幕!没有键盘!没有鼠标! 只有一个"装硬盘的盒子" + 网线插口 ┌─────────────────┐ │ NAS 小盒子 │ │ ┌───┐ ┌───┐ │ │ │硬 │ │硬 │ │ ← 装了好几块硬盘 │ │盘1│ │盘2│ │ │ └───┘ └───┘ │ │ 💡 小灯灯 │ └────────┬────────┘ │ 网线 │ 📡 路由器 / | \ / | \ 手机 电脑 平板 👩‍🏫 老师比喻: NAS = 一个 装了很多大肚子的小机器人 🤖 它不需要眼睛(屏幕)、不需要手(键盘) 它只需要 网线 ,就能默默给全家服务 💪 🤯 第三课:重点来了! NAS 其实就是一个"网页操作系统"! 小朋友们先回忆一下上次学的 👇 网页 = HTML骨架 + CSS衣服 + JavaScript动作 然后放在 服务器 上,用 浏览器 访问 现在老师告诉你一个秘密 🤫 NAS 本身就是一台服务器! 你管理NAS,不需要接显示器 直接打开浏览器,输入地址 NAS就把它的"控制面板"当网页显示给你! 就像这样 👇 你打开浏览器,输入:http://192.168.1.100 ↓ NAS的"网页控制面板"出现了! 有文件管理、有设置、有相册... 跟用网站一模一样! 👩‍🏫 老师比喻: NAS = 幼儿园的 全自动智能储物柜 🗄️✨ 你不用去柜子跟前 在家用手机扫一下 → 柜子的 控制屏幕传到你手机上 你在手机上点点点 → 柜子乖乖开门取东西 这个"控制屏幕",就是NAS的 网页界面 ! 🍳 第四课:前端和后端 —— NAS版本! 还记得上次说的"大厨房"吗? 你(浏览器)点菜 → 厨房(服务器)做好送来 NAS也是一样的,分成 前端 和 后端 两个部分! 🎨 前端 —— 你看见的那一面 ┌─────────────────────────────────┐ │ NAS 网页控制台 │ │ ┌─────┐ ┌─────┐ ┌─────┐ │ │ │📁文件│ │🖼️相册│ │🎬视频│ │ │ └─────┘ └─────┘ └─────┘ │ │ ┌─────────────────────────┐ │ │ │ 这里显示你的文件列表 │ │ │ └─────────────────────────┘ │ │ [上传] [下载] [删除] │ └─────────────────────────────────┘ 这些你能看见的 = 前端 🎨 👩‍🏫 老师比喻: 前端 = 储物柜 正面的触摸屏 📱 漂漂亮亮的按钮、图标、列表 你能看见、能点的,都是 前端 ⚙️ 后端 —— 藏在里面干活的 你点击"上传文件" 👆 ↓ 前端说:"收到!我去通知后端!" ↓ 后端收到指令 ⚙️: 1. 检查你有没有权限 🔐 2. 找到硬盘上空的位置 💾 3. 把文件存进去 ✅ 4. 告诉前端:"存好啦!" ↓ 前端显示:"上传成功!✅" 👩‍🏫 老师比喻: 后端 = 储物柜 里面的机械手臂 🦾 你在触摸屏上点"放东西进去" 机械手臂默默把东西码放整齐 你看不见它,但它一直在努力工作! 🔄 前端和后端怎么说话? 前端(网页) ←→ 后端(NAS系统) ↑ ↑ 你能看见的界面 藏在机器里的程序 它们用"API"互相说话 API = 两个人之间的"对讲机" 📻 👩‍🏫 老师比喻: 角色 NAS里是谁 幼儿园比喻 前端 网页控制台界面 储物柜的触摸屏 📱 后端 NAS的操作系统程序 里面的机械手臂 🦾 API 前后端通信接口 触摸屏和手臂之间的对讲机 📻

2026-06-26 原文 →
AI 资讯

AI and Liability

Earlier this month, a German court ruled that Google is liable for its AI search summaries. Rejecting defenses like “users can check for themselves,” and that they generally know “that information generated with AI should not be blindly trusted,” the court held that the AI’s summaries are reflections of the company and “above all an expression of Google’s business activities.” This is the latest skirmish in a decades-old battle over internet publishing. Historically, there were two different types of information distributors: carriers and publishers. A phone company is a carrier. It’ll transmit whatever you say, even discussions about committing a crime. Words are words, and the phone company does not know—nor is it liable for—the words you choose to speak. A newspaper, on the other hand, is a publisher. It decides the words it publishes, and what quotes to include in its articles. If those words or quotes are defamatory or otherwise illegal, it’s liable...

2026-06-26 原文 →
AI 资讯

Where AI code intelligence fits in your AI developer roadmap 2026

Code generation tools are powerful and can significantly accelerate development work. Their main limitation is not capability, but context. Without access to organizational knowledge, internal conventions, and system-specific patterns, generated output often requires careful verification. This is why generation tools work best when paired with AI code search, as the latter provides immediate visibility into the existing codebase, making it easier to align AI-generated changes with the realities of the system. In regulated environments, the adoption model may look different. Security or compliance constraints can restrict the use of cloud-based code generation. AI code search still improves developer efficiency across implementation, review, and documentation workflows by enabling fast navigation and comprehension of large multi-repository codebases. What is AI code intelligence, and how does it help in practice? Code intelligence tools help developers find and understand existing code. If a search returns a poor result, the developer simply searches again. Nothing changes in your codebase. Code search also integrates without friction. No new review processes, no changes to CI/CD, no new permissions. Generation tools require policies for AI-written code that stall many pilots before they produce data. Clear metrics for measuring AI code intelligence An AI code search assistant only reads your code, which makes it much easier to measure its impact. You can track simple things like: • how long it takes to find the right piece of code • how quickly new developers get up to speed • how many hours the team spends searching each week If your team of 20 developers each spends 5 hours weekly understanding code, that equals 100 hours of engineering time. At $75 per hour, that’s $360,000 per year. Assume 10% reduction recovers $36,000, a realistic input for an AI ROI framework for tech teams. Faster path to Phase 3 expansion Code generation tools face tough questions from secu

2026-06-25 原文 →
AI 资讯

From Root CA to User Authorization in nginx+apache. Part 2: Certificate Revocation, CRL and OCSP

A follow-up to Part 1 ( EN on LinkedIn · RU on Habr ), where we stood up a two-tier PKI: a Root CA and three intermediate CAs — Person, Server and Code. At the end of Part 1 I promised we'd learn to revoke certificates and run OCSP. That's what we'll do here. Like Part 1, this article is meant as a hands-on manual : for every command and extension we touch, there's an extended reference of the parameters you can actually use — with syntax, allowed values, defaults and gotchas. If you don't need a given option right now, just skim past the table; it's there so you don't have to dig through man later. Each section has the same shape: first the working commands for the common case, then the full parameter reference. Tested on versions. Flag names, defaults and extension syntax were verified against the official documentation of OpenSSL master , plus nginx and Apache mod_ssl. OpenSSL evolves per branch: anything marked "OpenSSL 4.0 / master" (for example the nonss qualifier on authorityKeyIdentifier ) is not yet available in the stable 3.x line. If you're on OpenSSL 3.0–3.6, double-check the disputed options with openssl <cmd> --help or your version's man before copy-pasting config. The numeric openssl verify error codes above 40 also shifted between branches — confirm them against your version's header. In this part: How a revoked certificate differs from an expired one, and why we need two mechanisms — CRL and OCSP. Adding the distribution points (CDP) and AIA to the config so issued certificates "tell" verifiers where to check them. Revoking a certificate and working with the CA database. Generating a CRL and inspecting it with openssl crl . Checking revocation with openssl verify . Running an OCSP responder: issuing its certificate, starting the daemon, querying status. Publishing the CRL and OCSP over HTTP (nginx), configuring OCSP stapling and revocation checking on the web server. All paths, file names and config sections are the same as in Part 1. Where you name

2026-06-25 原文 →
AI 资讯

Repositioning retail for the AI era

Artificial intelligence is rapidly reshaping retail, but not in the ways consumers might immediately notice. The biggest transformation may not be flashy virtual try-ons or chatbot shopping assistants, but in how decisions are made behind the scenes: how products surface in search results, how inventory moves through supply chains, how engineers ship code faster, and…

2026-06-25 原文 →
开发者

Type-Safe Env Vars Without Zod

Most TypeScript projects treat environment variables like second-class citizens. They're string | undefined everywhere, asserted with ! and parsed with parseInt() . TypeScript can't help because process.env is typed as Record<string, string | undefined> . Schema-based validation fixes this. But most solutions bring zod, which adds 50 KB to your bundle. CtroEnv does it with zero dependencies and 6.5 KB gzipped. How Inference Works The type system reads each validator's configuration at compile time: type InferredValue < V > = V extends Validator < infer T > ? V [ " metadata " ] extends { hasDefault : true } ? T // .default() → non-nullable : V [ " metadata " ] extends { optional : true } ? T | undefined // .optional() → nullable : T // required → guaranteed present : never This means the schema defines the type: const env = defineEnv ({ PORT : number (). port (). default ( 3000 ), // ^? number — default makes it always present DB_URL : string (). url (), // ^? string — required DEBUG : boolean (). optional (), // ^? boolean | undefined — optional NODE_ENV : pick ([ " dev " , " prod " , " staging " ] as const ), // ^? "dev" | "prod" | "staging" — exact union }) No interface Env { ... } . No z.infer<typeof Schema> . Add a new validator, and the type updates automatically. Default vs Optional vs Required The three states and their types: Declaration Type Runtime behavior string() string Required — throws if missing string().optional() `string \ undefined` string().default("x") string Falls back to "x" string().optional().default("x") string Default overrides optional TypeScript reflects this exactly. Optional gives you | undefined . Default removes it. The as const Requirement pick() needs as const to preserve literal types: pick ([ " dev " , " prod " ]) // type: string — widened pick ([ " dev " , " prod " ] as const ) // type: "dev" | "prod" — exact union Without as const , TypeScript widens the array to string[] and you lose the union. Exhaustive Checking With exact l

2026-06-25 原文 →