AI 资讯
Cloudflare Workers Accept Inbound TCP, with gRPC the First Protocol on Top
Cloudflare Workers can now accept inbound TCP connections through a new connect(socket) handler routed via Spectrum, ending an eight-year restriction to HTTP. Containers get full-duplex gRPC in any language, while Workers get unary and server-streaming through automatic gRPC-web translation. Everything is private beta. By Steef-Jan Wiggers
AI 资讯
okf-guard: A Security Layer for Open Knowledge Format (OKF) Pipelines
Catching Prompt Injection Before It Enters a Trusted Knowledge Base AI agents increasingly consume knowledge from sources they did not author and cannot independently verify: a PDF policy document, a scraped web page, a spreadsheet exported from another team's system. The prevailing approach — extract the text, write it into a knowledge base or context window, let the agent treat it as fact — has an underexamined weakness. Extraction tools capture everything present in a source document, including content a human reviewer would never see. The Mechanism Several ordinary, well-documented features of common file formats allow text to be present in a document while remaining invisible to anyone reading it normally: A PDF can render text in a rendering mode that instructs viewers not to display it, or set its fill color identical to the page background. A Word document has an explicit "hidden" attribute on any run of text, independent of color or size. A PowerPoint file's speaker notes are parsed by most extraction tools but never appear to an audience watching the presentation. A spreadsheet can mark entire rows, columns, or sheets as hidden, or attach a comment to a cell that is invisible unless hovered. An HTML page can hide an element from a browser's rendering entirely via a handful of standard CSS properties. None of these are obscure edge cases. They are common, legitimate formatting features, used constantly for entirely benign reasons — a hidden helper column in a spreadsheet, a private note to a presenter, draft text a Word user hid rather than deleted. The problem is not that these features exist; it is that an extraction pipeline has no reason to distinguish "this text is legitimate content" from "this text was deliberately hidden" unless something is specifically checking for the difference. Why This Matters for AI Pipelines Specifically If an attacker can place text anywhere in this chain — inside a PDF a company will later ingest, inside a web page a scrap
AI 资讯
Treat Voice-Companion Memory as a Consent Ledger, Not Prompt History
A personalized voice companion creates an uncomfortable trade-off: users do not want to repeat themselves, but they also do not want a misheard sentence to become a permanent “fact.” That tension is often hidden by calling conversation history memory . The implementation then retrieves old text, inserts it into a prompt, and trusts the LLM to interpret it correctly. A safer design gives memory to the application, not the model: The model may propose a typed fact. The companion must ask whether it should remember that fact. The user may confirm, reject, correct, or later revoke it. Only active, confirmed records can enter an LLM request. This tutorial builds that boundary in TypeScript and shows how it fits a Tencent RTC Conversational AI voice companion. We will use a social companion that can remember a preferred name, music genre, and conversation style—but not arbitrary instructions. Start with the trust boundary Keep the live-media pipeline and the memory lifecycle separate: Microphone │ ▼ Real-time voice session / speech recognition │ recognized turn ▼ Application turn coordinator ─────► LLM provider │ │ │ proposed typed memory │ response text ▼ ▼ Consent ledger Speech synthesis │ └──── confirmed facts only ────────► future LLM prompts Tencent RTC's Conversational AI documentation describes real-time voice interaction with multiple LLM providers. Its LLM configuration guidance also covers OpenAI-compatible models, agent platforms such as Dify and Coze, and request identifiers for routing and observability: Tencent Conversational AI overview Large Language Model configuration Social Entertainment solution The RTC layer can carry the live conversation, but your application should remain authoritative over what becomes durable memory. What the LLM is allowed to do For this example, the model can suggest one of three bounded slots: Slot Accepted values Suggested lifetime preferred_name A short name Until revoked music_genre An application-owned enum 30 days chat_st
AI 资讯
AI Harness: the worst and the best buzzword in the industry
--- title : " AI Harness: the worst and the best buzzword in the industry" published : false tags : [ ai , harness , middleware , finops , aws , bedrock , opensource ] series : " TokenOps on AWS" cover_image : # TODO: circuit-breaker / middleware diagram --- AI Harness: the worst and the best buzzword in the industry "El mercado habla de 'AI Harness' como si fuera magia. El verdadero arnés de un LLM es un Proxy Inverso y un Middleware Transaccional determinístico. Es el código tradicional (styrr-llm y sayay-guard) el que confina, audita y presupuesta la inferencia probabilística antes de que toque tu infraestructura en la nube." — TokenOps raw research, Turno 8 The Hook "Harness" is the most polarizing word in AI engineering right now. Depending on who you ask it's either the industry's worst buzzword or the best technical concept ever packaged badly. It's both — and the difference is whether you can name the actual engineering underneath. Why It's the WORST Buzzword (the smoke) It's a wrapper. 90% of the time, "we built an Enterprise AI Harness" means someone wrote a Python requests script or an Express server that wraps the OpenAI or Bedrock API. Language appropriation. "Harness" literally means arnés — a tether. Marketing sells it as "an intelligent structural armor that tames the wild energy of AI." In systems engineering it's a middleware, or a glorified try/catch with JSON schema validation. No standard. No rigorous CS definition exists, so anyone calls anything "harness" — a log interceptor, a proxy, a YAML config file — inflating expectations without delivering real value. Why It's the BEST Buzzword (the engineering) Strip the LinkedIn marketing and the original test harness metaphor becomes genuinely powerful for generative AI: electrical isolation of uncertainty. An LLM is a highly unstable, probabilistic component. You cannot wire it directly into a bank's production database. You need a physical code "harness" that isolates it. When the model goes crazy
AI 资讯
How a WhatsApp Web Extension Interacts With the Chat Interface
When people see a browser extension add translation controls, a side panel, or a sending workflow to WhatsApp Web, a common question is: how does the extension actually interact with the page? The short answer is that a modern Chrome extension is split across several execution environments. No single script should be responsible for the interface, persistent state, task scheduling, and access to the page at the same time. This article explains the architecture at a practical level without depending on private implementation details that may change whenever WhatsApp Web changes. A browser extension does not run as one program The simplest mental model is to divide the extension into four parts: The extension interface A background service worker A content script attached to WhatsApp Web A small bridge running in the page's own JavaScript context Each part has a different job and a different level of access. The extension interface is what the user sees: forms, task history, translation settings, saved scripts, and media selection. It should focus on interaction rather than long-running work. The background service worker coordinates tasks and stores state. It can receive a request from the interface, keep track of progress, and send commands to the correct WhatsApp Web tab. The content script lives alongside the webpage. It can inspect the rendered document, inject controls, and communicate with the extension runtime. Chrome isolates it from the page's own JavaScript environment for security. The page bridge exists because isolation is sometimes a limitation. A content script can see the DOM, but it does not automatically share the same JavaScript objects as WhatsApp Web. When deeper page integration is required, a carefully scoped bridge can exchange explicit messages between the isolated extension world and the page world. Why not put everything in the content script? It is tempting to keep the entire feature in one file because the content script is already attach
AI 资讯
Mechanically Eliminating FutureBuilder & StreamBuilder: Universal Signal, Future, and Stream Adapters in BlocSignal
Making the Migration from In-View Asynchrony to Synchronous State Management Truly Mechanical After our recent discussions on why FutureBuilder and StreamBuilder are architectural anti-patterns when placed inside Flutter widget trees, I started thinking: how can we make it even easier—even completely mechanical—to convert from a FutureBuilder or StreamBuilder to a BlocSignalBuilder ? Every Flutter developer knows the history. Years ago, I recorded a video breaking down the hidden traps of placing asynchronous builders in UI views: Why you shouldn't put FutureBuilder in your build method . Even the original official Flutter video on FutureBuilder initially instantiated the network future directly inside the build() method, until I filed an issue to get it corrected (which is why the official Flutter YouTube video still proudly bears "Take 2" on its clapperboard!). The fundamental issue has never been that developers want bad architecture. The issue was friction . FutureBuilder was simply the path of least resistance. To do it "properly" in traditional state management, developers had to create an entire BLoC or Cubit, declare separate Event and State classes (or union types), write boilerplate event handlers, wire asynchronous repository methods, manage subscription lifecycles, and inject everything into the widget tree. With bloc_signals 1.1.0 , that friction disappears completely. We have introduced universal, symmetrical adapter extensions that allow any Dart Future , Stream , ReadonlySignal , or lifted primitive ( value.$ ) to adapt into a synchronous BlocSignalBase container with a single method call. 🧭 The Universal Dual-Track Mental Model When bridging asynchronous sources into synchronous state management, developers typically have one of two distinct intents: Raw Domain Values ( T ): You want raw domain objects (for example int , UserProfile , ThemeMode ) with zero wrapper ceremony, and you have an immediate default or fallback value for frame 0. Rich Asynch
AI 资讯
Go Doesn't Force Clean Architecture. That's Your Job.
The criticism of this is everywhere. Open any Go thread long enough and someone will show up to perform the same ritual: "Go projects become messy. There's no framework to guide you. Nest, Django, Spring, they all tell you exactly where to put things. Go? It just says 'organize it somehow.'" It's a fair criticism. Go is unusually permissive about structure. I just think blaming Go for a messy codebase is like blaming the empty document for the bad essay. I don't think Go encourages bad architecture but rather it exposes it. The Hell Is A Perfect Folder Structure?? Ask a hundred Go developers where to put business logic and you'll get a hundred answers (and 200 opinions). "Should I use internal/ ?" "Is everything supposed to live under pkg/ ?" "Should I follow Clean Architecture?" "What about the cmd/ directory?" We spend so much time debating folder structures as if the arrangement of directories somehow determines code quality. As if renaming utils/ to pkg/shared/ is going to save us. God. folders don't create architecture. Dependencies do. You can meticulously organize your project like this: my-app/ cmd/main.go internal/ handler/ service/ repository/ pkg/domain/ pkg/utils/ And still write tightly coupled garbage. Handlers calling repositories directly. Services importing database drivers. Business logic mixed with HTTP concerns. Everything circular. Beautiful folders, though. Very organized looking on GitHub. There are better projects I've seen with just 5 packages, they just don't screenshot as well. Architecture Is About Dependency Direction The architecture is about making intentional decisions about how code depends on other code. Have a look at this: HTTP Handler ↓ Business Service ↓ Data Repository This isn't sacred because of folder names. It's valuable because of what it represents: The handler only knows how to translate HTTP The service only knows business rules The repository only knows how to fetch data Each layer depends on the layer below, never upw
AI 资讯
Meta Expands Its Custom Silicon Strategy From Compute Into Networking
Meta has detailed MTIA 300, its first in-house accelerator optimized for training ranking and recommendation models. By Matt Foster
AI 资讯
Your AI Remembers Everything and Trusts All of It
I think we are still talking about AI memory in the wrong way. Most implementations are variations of...
AI 资讯
Speaker - Designing Systems That Contain Failure - CS Week Perú 2026
Designing Systems That Contain Failure — CS Week Perú 2026 On August 13, 2026, I had the opportunity to speak at CS Week Perú 2026 , an event organized by IEEE Computer Society student chapters across Peru. My session was: “Isolation and Trust Boundaries in Production: Designing Systems That Contain Failure” The talk explored how production systems can be designed to limit the impact of failures through explicit trust boundaries, architectural invariants, and evidence-based validation. The central idea was simple: The goal isn't to prevent every failure. The goal is to control its blast radius. Production systems fail. Requests overlap, processes crash, memory is exhausted, credentials can be compromised, and dependencies can become unavailable. Reliable engineering is not about assuming that none of these things will happen. It is about deciding what can be affected when they do . From Unit Tests to System Properties A green unit-test suite demonstrates that the tested units behave correctly under the conditions we defined. But it does not necessarily demonstrate that the system as a whole preserves its architectural properties under concurrency, multiple tenants, resource exhaustion, or real deployment conditions. A function can be correct in isolation while the system still violates an important invariant. That led to one of the central questions of the talk: What properties must never be violated? Trust Boundaries I used the concept of a Trust Boundary to make architectural assumptions explicit. For each boundary, we can ask three questions: What are we protecting? What is allowed to cross the boundary? What happens if the condition is violated? From there, we can define invariants : properties that the system must preserve under the conditions established by its design. In the architecture discussed during the session, three dimensions were particularly important: Context → Logical isolation Identity → Cryptographic isolation Execution → Physical/process isolat
AI 资讯
Structured API Logging in 2026: Correlating Response Status and Delivery Latency
Short answer: record one structured completion event at the request boundary, emit separate events for every asynchronous notification attempt, and join them with a stable notification ID; middleware latency and status code alone cannot reconstruct a delivery failure. For a gaming notification service, the deciding constraint is time. An API response may say that a guild invite was accepted while the actual push attempt occurs seconds later, perhaps on another process. Treating those two facts as one log event produces a comforting dashboard and a weak incident record. The architecture decision is to preserve both boundaries, give each event a precise meaning, and ship them outside the request's success path. This is deliberately an evidence design, not a logging-library choice. Express and Pino can implement the request-side contract in Node.js, but changing a serializer does not repair a missing correlation key or an ambiguous definition of completion. Decision, invariants, and failure boundaries The request completion event answers a narrow question: what did this process observe at its HTTP boundary? It should carry a timestamp, severity, service and environment, request ID, normalized route, method, response status code, and elapsed duration. If the request creates or addresses a notification, add a notification ID that remains stable across the queue and delivery worker. Do not make raw request or response bodies part of the default schema; tokens, chat text, player identifiers, and device data have different retention and access requirements from operational metadata. The delivery attempt event answers a different question: what happened when a worker tried to deliver that notification? Its useful fields include the same notification ID, an attempt number, channel, destination class rather than raw destination, outcome, and a bounded error category. A retry is another attempt event, not an edit to an old record. That append-only shape matters because the inte
AI 资讯
Webhooks vs Polling: Why Real-Time Integrations Matter in 2026
Webhooks vs Polling: Why Real-Time Integrations Matter in 2026 In modern software, knowing that something happened is often just as important as knowing what happened. A customer completes a payment. An order changes from pending to shipped. A user creates an account. A GitHub pull request is opened. A subscription is renewed. An AI workflow needs to start processing a new request. The question is simple: How does your application know that something changed? For years, developers have relied on two common approaches: polling and webhooks. Both solve the same fundamental problem—keeping systems synchronized—but they do it in completely different ways. Polling repeatedly asks an API whether something has changed. Webhooks allow the external system to notify your application when something actually happens. That difference can have a major impact on performance, scalability, API usage, responsiveness, reliability, and overall system architecture. And as applications become increasingly connected in 2026, understanding when to use each approach is more important than ever. What Is Polling? Polling is the traditional approach to checking for changes. Your application periodically sends a request to another system: “Has anything changed?” For example, imagine an e-commerce application that needs to know when an order has been paid. It might call an API every 30 seconds: GET /orders/12345 The response might say: status: pending Thirty seconds later, the application asks again. Then again. And again. Eventually: status: paid The application finally discovers that the payment has been completed. The basic workflow looks like this: Application → API → “Anything new?” API → Application → “No.” Thirty seconds later: Application → API → “Anything new?” API → Application → “No.” Eventually: Application → API → “Anything new?” API → Application → “Yes, the order has been paid.” The approach is straightforward and easy to understand. But there is a problem. Most of those requests
AI 资讯
Indexar o código fora do repo: como economizar tokens sem jogar o projeto no contexto
Indexar o código fora do repo: como economizar tokens sem jogar o projeto no contexto Pessoal, o agent precisava achar um símbolo. Trabalho de um minuto. Na prática, ele abria arquivo atrás de arquivo, colava dump de teste no papo e a janela sumia. Às vezes a fatura também. Não era o modelo burro. Era eu pagando o monorepo inteiro pra responder a pergunta errada. A pergunta mudou. Deixei de ser “qual tool faz o agent entender o repo?” e virei: o que é memória de domínio, e o que é só custo de ler código nesta sessão? Tem um segundo motivo, e ele não é economia. Um índice de símbolos é um mapa do seu sistema : quem chama o quê, onde está o fluxo crítico. Se esse mapa mora no git, no cache de CI ou num serviço que o agent também escreve, o blast radius não é só token. É superfície. Duas contas, um prompt Memória de domínio é política. O que pode ser lembrado, por qual porta se entra, o que é canônico. Notas, contratos, “onde a gente decide X”. Indexer de código não resolve isso. Code-read barato é custo de sessão. Achar caller e símbolo sem despejar o working tree no prompt. Isso não deveria virar a sua base de conhecimento. Eu misturava. O indexer virava KB. O vault virava grep sem porta. Os dois falhavam, e a sessão inchava igual. Economizar token aqui não é trocar de modelo da semana. É separar camada. E decidir onde o mapa vive . O que eu mudei na mesa O mapa de símbolos saiu do working tree. Cache local, fora do repo , fora do git. Reindex é operação de máquina, não de PR. O agent consulta o índice; não precisa reler o monorepo pra “quem chama essa função?”. Quatro perguntas que eu faço antes de indexar um repo (vale colar no README do setup): O índice vive na minha máquina ou sai dela (cloud, CI, cache compartilhado)? Entra em contexto de agent que também tem tool de escrita ? Como eu apago e revogo? Quem mais lê isso? Índice ≠ fonte de verdade versionada. Least privilege no que entra no contexto continua valendo. Depois, parei de mandar firehose de CLI cru. tes
AI 资讯
How to Host OpenClaw for Multiple Clients in Production
The first OpenClaw deployment is usually straightforward. You provision a machine, configure one agent, connect a few tools, and watch it complete a real task. If something breaks, you inspect the logs, fix the configuration, and restart the process. That is a valid way to prove the use case. It is not yet a production architecture. The category changes when an agency, SaaS company, consultant, or internal platform team needs to run OpenClaw for multiple clients. Every agent now belongs to a tenant, holds state, uses credentials, controls browser sessions, changes files, and can create external side effects. A failure is no longer just a failed process. It can become a missed client task, a duplicated email, a corrupted workspace, or an access-control incident. The right question is therefore not, "How many OpenClaw containers can this server run?" It is, "How many client environments can our team operate safely, recoverably, and without adding one human babysitter for every few agents?" This guide presents a practical architecture and deployment checklist for answering that question. Start with the correct unit of architecture Do not model an OpenClaw fleet as a list of processes. Model it as a list of client cells. A client cell is the complete operating boundary for one tenant or one agent. It includes: the OpenClaw process and its configuration; its resource envelope: reserved and maximum RAM, CPU cores, burst allowance, and priority; the persistent workspace and task artifacts; credentials and integration permissions; browser profiles, cookies, and active sessions; email, phone, or chat identity; logs, events, and audit history; recovery policy and human owner. This distinction matters because a process can be healthy while the client cell is broken. The daemon may still respond, but its CRM credential has expired. The container may be running, but the browser session is stuck behind a login prompt. The agent may have restarted successfully, but its workspace c
AI 资讯
One Gigabyte per Survey, of Which 108 KB Goes in the Database
Here is the disk layout of one mobile mapping survey — a vehicle with a LiDAR scanner and a panoramic camera, driven along a road: data/001_MMS/ 507 MB point cloud orbit/oblak/ 566 MB spherical photos trajectory/*.gpkg 108 KB the path the vehicle drove Just over a gigabyte. The database this feeds holds 2.3 GB in total — for 2.7 million road features across a hundred layers. Two more surveys and the binary data outweighs everything the database has ever stored. So the question isn't how to put a point cloud in Postgres. It's what you put in Postgres instead . The trajectory is the index Of that gigabyte, one file goes into the database: the 108 KB trajectory, a GeoPackage holding the line the vehicle drove. That line is what makes the survey findable. It draws on the map with everything else. You can ask which surveys cover a junction, which are newest, whether a stretch of road has been captured since the resurfacing. All the questions people actually ask are questions about where and when , and the trajectory answers every one of them at 0.01% of the storage. The heavy files never enter the database. The row holds paths: class Cloud ( models . Model ): name = models . CharField ( max_length = 120 , db_index = True ) path_name = models . CharField ( max_length = 120 ) # -> octree metadata JSON orbit_url = models . CharField ( max_length = 255 ) # -> spherical photo index spherical_photo = models . BooleanField ( default = False ) recording_date = models . DateField ( null = True ) source_srid = models . IntegerField ( null = True , choices = SOURCE_SRID_CHOICES ) available = models . BooleanField ( default = True ) Metadata, geometry, and pointers. That's the whole trick, and it isn't clever — it's just the discipline to not reach for a bytea column. Why not in the database Postgres will happily store a gigabyte. It's the access pattern that kills you. A browser point cloud viewer doesn't fetch a point cloud. It fetches an octree : a tree of small files, and as the
AI 资讯
Retries Are Not a Recovery Strategy
A retry answers a narrow question: might the same operation succeed if I attempt it again? Recovery has a harder job. It must bring the original business operation to a known, valid outcome after something went wrong. Getting there may require another attempt, a status lookup, resuming from persisted state, or compensation. If the system cannot resolve the operation safely, it must hand it to a person. This difference matters as soon as an AI workflow does more than return text. If it retrieves data, calls tools, writes state, or continues after the HTTP request ends, adding three retries around the workflow is not a recovery design. It is three more chances to spend money, repeat a side effect, or lose track of what already happened. A retry repeats an attempt Suppose a support feature performs this workflow: load the ticket and approved policy -> generate a reply -> validate the reply -> save it as a draft The policy read returns 503 Service Unavailable with an applicable Retry-After response, and the dependency contract classifies it as transient. No application business state changed, and the request still has time left. A delayed retry may be reasonable. Now suppose the draft save times out after the request reached the database. The caller cannot tell whether the write committed. Repeating the complete workflow creates a new model response and may save a second draft. Retrying only the write is safe when the write is naturally idempotent, or when the boundary can recognize the retry as the same logical operation. Otherwise, the second attempt may create another draft. Both failures may appear as a timeout or dependency exception in application code. They do not have the same effect. What happened What is known Suitable response A transient policy read failed before returning data No application business state changed Retry the read within its budget The model endpoint rejected an invalid request The same request will fail again Stop and fix the request or cont
AI 资讯
Should Your Prompt Store Pick Your Model
Langfuse with Microsoft.Extensions.AI has an appealing story: update prompts without redeploying. A prompt fetches its config blob—model, tokens, temperature—which the code passes straight to the LLM. It works. But it puts a boundary in what I'd suggest might be better placed elsewhere — and moving it is a small enough change to be worth exploring. This post is about where to move that line in a .NET codebase using Microsoft.Extensions.AI against OpenAI or Azure OpenAI, with Langfuse as the source of prompts. What the current setup buys you Let me be fair to it first, because the coupling is a deliberate design, not an accident. Langfuse's prompt config is an optional JSON object versioned alongside the prompt. That means someone can open the Langfuse UI, change the model or a parameter, and ship it — no code change, no redeploy. Combined with labels (pointers to specific versions that your code references), a rollback is just moving the production label back to an earlier version. For prompt content iteration, that story is genuinely good, and there is a real audience of people who want model config coupled to prompt versions more tightly so each version is fully self-describing and reproducible. So this is a trade-off, not a bug. The question is whether the thing you are optimizing for — non-engineers tuning prompts without a deploy — is worth what the coupling costs. Why I think this deserves consideration Three points stand out. It is an untyped blob feeding provider selection. The Langfuse config is arbitrary JSON without schema enforcement. On the other end, whatever LLM plumbing you use will treat that model string as authoritative. A missing key, a stray max_tokens , or a gpt4o typo might not fail at build time or deploy time — it could fail on a live request, or silently do something unintended. You have a loosely-typed value driving an infrastructure decision, and the mistake may not surface until traffic hits it. It conflates two change lifecycles with di
AI 资讯
Offline-First in React Native: Building an Auto-Sync Engine That Users Never Think About
By Shivkrishna Shah · Engineer Philosophy — @shivkrishnashah · @engineerphilosophy Your app shouldn't have a "no internet" screen. Here's the architecture I use to make mobile apps write locally, sync automatically, and survive the messy reality of field connectivity. Every mobile developer has shipped this screen at least once: a sad cloud icon and the words "No internet connection. Please try again." For consumer apps, that's an annoyance. For enterprise field apps — sales reps in hospital basements, auditors in warehouses, technicians in rural areas — it's a dealbreaker. If the app stops working when the signal drops, people stop trusting it. And once field users stop trusting an app, they go back to paper and WhatsApp. I spent the last few years building and maintaining an offline-first React Native platform used daily by field teams across multiple countries. This post is the architecture I wish someone had handed me on day one: how to structure local storage, detect connectivity, queue writes, auto-sync in the background, and avoid the two bugs that will absolutely bite you (duplicates and conflicts). Everything here is generic — I'll use Realm DB and NetInfo in the examples, but the pattern maps cleanly onto WatermelonDB, SQLite, or MMKV-backed queues. The one rule that changes everything The local database is the source of truth. The server is just a replica you happen to reconcile with. Most apps are built the other way around: the server is the truth, and the app is a thin cache over fetch() . Offline-first inverts this. Every read comes from the local DB. Every write goes to the local DB first. The network is an implementation detail that a background service worries about — never the UI. This single inversion gives you three things for free: Zero-latency UX. Saves are instant because they're local writes. No spinners on submit. Airplane-mode parity. The app behaves identically online and offline, because the UI never talks to the network. Crash safety. D
AI 资讯
Scalable Guardrail Service ASP.NET Core Kubernetes: Architecture, Code, and Ops
Scalable Guardrail Service ASP.NET Core Kubernetes: Architecture, Code, and Ops Quick Answer Scalable Guardrail Service ASP.NET Core Kubernetes: A dedicated ASP.NET Core guardrail microservice on Kubernetes validates LLM requests, enables instant policy updates via Redis, and scales with custom HPA for high‑throughput. Scalable Guardrail Service ASP.NET Core Kubernetes: Why a Dedicated Guardrail Microservice Matters When you expose an LLM‑powered API to the world, every request is a potential compliance risk. A single malformed prompt can surface PII, trigger a policy violation, or even cause a brand‑damaging output. In my experience, the first version of such a system is a set of ad‑hoc filters sprinkled across controllers. Under load, those filters become latency bottlenecks, policy updates race, and audit trails vanish. The root cause is a missing architectural layer that treats guardrails as a first‑class microservice that can scale horizontally, be updated live, and be observed independently. Guardrail Layer Requirements We need a guardrail layer that: Validates every request before it hits the LLM engine. Can be updated without redeploying the entire API surface. Provides per‑tenant isolation and versioning. Logs every decision for compliance and red‑team analysis. Runs at the same scale as the LLM inference service. When This Fails in Production Policy updates are applied via a shared ConfigMap and the pods do not reload, so new rules are never enforced. The guardrail service is single‑instance; a spike in requests triggers a queue that exceeds the LLM engine’s rate limit, causing a cascading failure. Audit logs are written to local disk; a pod crash loses events. Latency spikes because each request performs a synchronous Redis lookup for every policy. Common Mistakes Engineers Make Embedding guardrail logic inside the API controller rather than a dedicated middleware. Using in‑memory policy caches without a TTL, leading to stale rules. Ignoring the fact that
AI 资讯
When pgvector Outshines Dedicated Vector Stores at Scale
Key takeaways pgvector can reduce vector storage costs by 50% or more. Utilizing PostgreSQL's indexing capabilities enhances performance. Operational simplicity with a unified database reduces overhead. Cost-effective scaling is achievable with the right configurations. The problem Startups leveraging AI and machine learning often face skyrocketing costs associated with dedicated vector databases as they scale. These costs can escalate quickly due to the pricing structures of specialized services, which charge based on storage and query volume. Founders typically hit this wall when user growth surges or when the complexity of vector retrievals increases, leading to budget overruns and performance bottlenecks. What we found Interestingly, many startups overlook the capabilities of pgvector, a PostgreSQL extension that supports vector similarity search. With proper indexing and configuration, pgvector can match or even exceed the performance of dedicated vector stores while significantly reducing costs. The non-obvious insight is that by leveraging existing PostgreSQL infrastructure, startups can avoid the pitfalls of vendor lock-in and unpredictable scaling costs associated with specialized vector databases. How to implement it Begin by integrating pgvector into your existing PostgreSQL setup. First, install the pgvector extension using the command: CREATE EXTENSION vector; . Next, define your vector columns with the appropriate dimensionality, for example, CREATE TABLE items (id SERIAL PRIMARY KEY, embedding VECTOR(300)); . Utilize PostgreSQL's GiST or ivfflat indexing for efficient similarity searches. Implement batch insertion techniques to optimize write throughput, and consider partitioning your data to manage large datasets effectively. Regularly monitor query performance and adjust your indexing strategy based on usage patterns. How this makes life easier By utilizing pgvector, startups can expect to reduce their vector storage costs by 50% or more compared to