AI 资讯
Building Practical AI Skills with a VPS: A Beginner-Friendly Guide
I am the Arthur of this blog, and I want to tell you about something I have been exploring recently: how a VPS can become more than just a place to host a website . When people hear the word VPS, they usually think about web hosting, servers, domains, or websites. But a VPS can actually be a useful environment for developers who want to learn Python, automation, AI tools, Linux, APIs, and practical server management . You don't need to start with a huge cloud infrastructure or an expensive dedicated server. Sometimes, a simple VPS with Linux, Python, and a few useful tools is enough to start learning by building real projects. In this article, I will show you how these pieces fit together and how you can create a small practical project on a VPS. What Is a VPS? A VPS (Virtual Private Server) is a virtual server that gives you your own allocated environment inside a physical server. Compared with traditional shared hosting, a VPS gives you much more control. You can usually: Install your own software Run Python applications Configure Linux packages Create databases Run background scripts Host APIs Deploy websites Manage services with SSH Automate repetitive tasks For developers, this control is one of the biggest advantages of VPS hosting. Instead of only uploading website files, you can actually use the server as a small development and deployment environment. Why VPS Is Useful for Learning New Skills One thing I have learned while working with technology is that reading about a skill is very different from actually using it. For example, you can read ten tutorials about Python automation, but running your own Python script on a Linux server teaches you something completely different. You start understanding: Python ↓ Application ↓ Linux Server ↓ VPS ↓ Internet This is where a VPS becomes interesting. You can build a small application locally, move it to the VPS, configure the environment, and make it available online. That single process teaches several skills at o
开源项目
🔥 securo-finance / securo - Open-source personal finance manager. Self-hosted, privacy-f
GitHub热门项目 | Open-source personal finance manager. Self-hosted, privacy-first. | Stars: 2,324 | 617 stars this week | 语言: Python
AI 资讯
Building a Robust Market Research Assistant: Clean Architecture and LLM Tool Routing in Python
When designing AI-powered financial or analytics pipelines, developers frequently run into two major failure modes: Tight Coupling: LLM orchestration logic is directly bound to external market APIs. Any breaking change from a data vendor breaks the entire agent pipeline. Fragile Outputs: Relying on raw text generation for deterministic indicators creates hallucinated figures and pipeline crashes downstream. To solve this in Trading-research-assistant , the system applies Hexagonal Architecture (Ports and Adapters) , strict schema validation with Pydantic, and decoupled inference routing. High-Level Architecture (Ports & Adapters) The core domain layer remains completely isolated from external HTTP clients, third-party market APIs, and specific inference engines. +---------------------------------------------+ | User / CLI / API | +---------------------------------------------+ | v +---------------------------------------------+ | Application Layer | | (ResearchCoordinator, AnalysisOrchestrator) | +---------------------------------------------+ | | v v [ MarketDataPort ] [ LLMInferencePort ] ^ ^ | (implements) | (implements) +------------------------+ +------------------------+ | Adapters: | | Adapters: | | - OandaAdapter | | - OllamaAdapter | | - TwelveDataAdapter | | - OpenRouterAdapter | | - MockDataAdapter | | - ClaudeAdapter | +------------------------+ +------------------------+ Key Architectural Benefits Zero-Cost Unit Testing: Fast mock adapters allow full integration tests without consuming rate limits or paid API credits. Resilient Failovers: If a primary provider hits rate limits (HTTP 429) or service outages, the orchestrator switches to a fallback adapter implementing the identical port contract. Strict Interface Contracts Data boundaries between adapters and application services are enforced using typing.Protocol and immutable Pydantic schemas. from datetime import datetime from typing import Protocol , Sequence from pydantic import BaseModel , Field cl
AI 资讯
Clip Architect: MoneyPrinterTurbo as a Windows Desktop App
What Clip Architect Actually Changes About Local AI Video Generation Here's what people get wrong about a tool like this. The hard part was never really the AI writing the script. It's the plumbing around it, the part nobody photographs for the landing page. Clip Architect is a Windows desktop application that wraps the open-source MoneyPrinterTurbo pipeline (the one that turns a topic into a scripted, narrated, subtitled short video) inside a Tauri 2 shell, with a React 19 interface and a Python backend running underneath as a private local service. You give it a topic, you get an MP4 sized for TikTok, Reels or Shorts, and nothing in between gets uploaded anywhere except to whichever provider you configured, with the key you supplied yourself. No account, no subscription, no cloud render queue. Once you get that one distinction, wrapper versus engine, the rest of this holds together on its own. Why the Terminal Step Was the Real Barrier Let's look at where the friction actually sat. Upstream MoneyPrinterTurbo is a Python web app built on FastAPI with a Streamlit interface: you start it from a terminal and use it in a browser . Fine for a developer. It stops being fine the moment the person who wants the video has never opened a terminal in their life, and most people who want a video have never opened a terminal in their life. Closing that gap is the whole reason Clip Architect exists: a Tauri shell owns the window and the process lifecycle, a React frontend replaces Streamlit, and the Python backend starts and stops with the app itself, quietly, in the background. You install it, you open it, and a command line never comes up. The chain underneath doesn't change. Give it a subject, an LLM writes the script and the search keywords, stock footage or your own files supply the picture, a text-to-speech engine speaks the narration, and FFmpeg cuts the clips to the voice track, burns in subtitles, mixes background music and writes the final MP4. Every one of those stage
AI 资讯
A Self-Correcting Solar System Baseline From Sunrise/Sunset Data
A fixed-schedule solar baseline drifts out of sync with the sun throughout the year. In Phoenix the sun is up for 13 hours 10 minutes in late August and 10 hours 2 minutes at the December solstice. A flat daily kWh target flags that entire winter as a fault, then stays quiet on the July afternoon when one string dies at 2pm under full sun. The fix is to anchor the baseline to the actual sun instead of the clock, and most of what you need for that does not require an irradiance forecast. One thing before any code: sun geometry tells you when a system should be producing and when it should peak. It does not tell you how much light actually reached the panels. That is irradiance, and cloud cover swamps it. If you want modeled output in kWh, reach for Forecast.Solar or Solcast, which fold in weather and your array's tilt and azimuth. What follows is the free, dependency-light layer underneath that: the daylight window, the solar-noon peak, and the day-length trend. TL;DR Sun geometry (sunrise, sunset, solar noon, day length) catches a specific class of solar underperformance with no irradiance data. Gate alerts to the real daylight window so your monitor stops crying "underperformance" before sunrise. Track the daily production peak relative to solar noon. A persistent shift across comparable days can reveal shading, orientation, or system changes that a total-kWh check misses. Normalize a flat kWh target by day length so winter stops tripping false alarms. First-order fix, not a physics model. One call to an astronomy endpoint returns all of it. Code below in curl, Python, and Node. For real production forecasting, use an irradiance API. Sun times are the sanity layer, not the forecaster. Sun times will not predict your kWh, but they eliminate common timing-based false alarms and can surface useful production-shape anomalies early. Pull sunrise, sunset, solar noon, and day length once a day, gate your alerts to daylight, watch the peak, and scale the target for season.
AI 资讯
I built a workflow builder that interviews you. Here is what broke.
Every workflow builder I have used opens the same way: a blank canvas and a palette of nodes. Zapier, n8n, Make - all of them assume you already know what you want, already decomposed into steps, before the tool is any use to you. Most people don't. They know the chore . "I keep forgetting to check the weather before I bike in." The gap between knowing the chore and knowing the DAG is precisely the work these tools leave you to do alone, and I think it is why most people who try one never build a second automation. So I built Weaver, which inverts it. Weaver interviews you about the chore, one question at a time, until it actually understands the goal. Then it designs the workflow, validates it, deploys it, and runs it. The canvas is an output rather than an input. This post is about the parts that did not go to plan, because those are the parts worth reading. The interview is the whole product Three rules, and they are harder than they look: One question per turn. Never three bundled into a paragraph. Never invent a value the person has not given you. No quietly assumed recipient, city, or time. A correction updates one detail. Say "actually, Mondays" halfway through and it changes that and keeps going, instead of restarting the interview. That third one is the one people notice. Restarting an interview because the user corrected themselves is the single fastest way to make software feel like it is not listening. Only once it restates the whole task in plain language and you confirm does it save the intent and hand off to a separate Designer Agent. Two agents, deliberately not one The Conversation Agent and the Designer Agent are different models with different prompts and no shared state beyond a saved intent. That is a design decision, not an accident of implementation. Understanding a person and designing a system are different skills with different failure modes. Collapsing them into one prompt makes both worse: the interviewer starts proposing architecture hal
AI 资讯
Build a caption QA harness in Python: WER, missed entities, timing and reading rate
TL;DR We're building a caption evaluation harness that scores a WebVTT file on four axes instead of one: word error rate under a fixed normalizer, missed entity rate on domain terms, median cue timing offset, and reading rate in characters per second. Python 3.12, jiwer , whisper_normalizer , webvtt-py . Run it on every model or vendor change. A caption file can score 96% accurate and still be unusable. WER counts substitutions, insertions and deletions and weighs each one the same, so "fifteen milligrams" becoming "fifty milligrams" costs exactly as much as "the" becoming "a". It also throws away every timestamp before it starts, which means synchronization and readability are invisible to it. Let's measure the other three things. 0. Setup 🛠️ python3 -m venv .venv && source .venv/bin/activate pip install jiwer whisper_normalizer webvtt-py $ pip list | grep -Ei 'jiwer|whisper|webvtt' jiwer <your version> webvtt-py <your version> whisper-normalizer <your version> Pin whatever you install, and pin it in CI. The APIs below move between majors, which is exactly why the next tip exists. 💡 Tip: jiwer.compute_measures() is gone in recent versions. It is jiwer.process_words() now, and it returns a WordOutput dataclass. Most blog posts you will find still use the old name. 1. Parse the VTT into text plus timings # captions.py from dataclasses import dataclass import webvtt @dataclass class Cue : start : float end : float text : str @property def duration ( self ) -> float : return self . end - self . start @property def lines ( self ) -> list [ str ]: return self . text . split ( " \n " ) @property def flat ( self ) -> str : return " " . join ( l . strip () for l in self . lines ) @property def chars_per_second ( self ) -> float : return len ( self . flat ) / self . duration if self . duration > 0 else float ( " inf " ) def _to_seconds ( ts : str ) -> float : h , m , s = ts . split ( " : " ) return int ( h ) * 3600 + int ( m ) * 60 + float ( s ) def load_vtt ( path : str ) -
AI 资讯
Presentation: Python, Numba, and Algorithm Design: Building Efficient Models in Financial Services
Chad Schuster discusses bridging Python's developer velocity with C-like performance using Numba JIT and GPUs. Drawing from large-scale actuarial modeling, he explains LLVM pipeline architecture, performance gains up to 750x, and essential trade-offs like OOP limits, type inference errors, and compile-time overhead for engineering leaders scaling compute-heavy enterprise systems. By Chad Schuster
AI 资讯
15 NLP Techniques Every Backend Developer Should Know in 2026 (With Code Examples)
NLP stopped being a data science specialty about two years ago. It's backend infrastructure now. If you're building APIs that process user input, handle search, manage support tickets, parse documents, or power any feature where humans communicate with your system in natural language, you're doing NLP whether you call it that or not. The difference between a backend developer who understands NLP techniques and one who doesn't is the difference between building a search endpoint that actually finds what users want and building one that matches keywords and returns garbage for anything slightly ambiguous. This is the reference guide we wish we'd had when we started integrating NLP into production backend services. Fifteen techniques, each with a runnable code snippet, ordered from the most immediately useful to the most architecturally advanced. Every example runs in Python. Install the dependencies as needed, we'll note them for each technique. 1. Text tokenization The atomic operation. Everything else depends on splitting text into meaningful units. import spacy nlp = spacy . load ( " en_core_web_sm " ) text = " Dr. Smith ' s appointment at 3:30pm was rescheduled. " doc = nlp ( text ) tokens = [ token . text for token in doc ] # ['Dr.', 'Smith', "'s", 'appointment', 'at', '3:30pm', 'was', 'rescheduled', '.'] SpaCy handles the edge cases that naive split-on-whitespace misses, abbreviations, contractions, timestamps. If your backend processes any user-generated text, tokenization is step zero. 2. Named entity recognition (NER) Extracting structured data from unstructured text. Names, dates, amounts, locations, the things your database actually needs. doc = nlp ( " Send $5,000 to Acme Corp in Singapore by March 15th " ) for ent in doc . ents : print ( f " { ent . text : 20 } { ent . label_ } " ) # $5,000 MONEY # Acme Corp ORG # Singapore GPE # March 15th DATE We use NER on every inbound support ticket to auto-tag customer, product, and amount entities before the ticket
AI 资讯
Day 1 of #100DaysOfCode: Built My First Project
Published: 27/08/2026 The Setup I'm 16 years old and starting my coding journey in 2026. After using Twitter, GitHub, and setting up my domain ms.blurbisht.fun, I decided to commit to #100DaysOfCode. The Project: Pong Game CLI A terminal-based two-player Pong game built with Python's curses library. Demonstrates: Object-oriented programming Game loops and input handling ASCII graphics animation Score tracking # Key code snippet if key == ord ( ' w ' ): left_paddle . move_up () Why I Built It: To move beyond theory to actual shipping. My goals: learn Python → build AI agents → create multi-agent systems. What's Next: Day 2: Not Planned!! Connect: Twitter: @blurbisht GitHub: github.com/BlurBisht Portfolio: ms.blurbisht.fun
AI 资讯
weightwatch v0.1: escanea backdoors en modelos open-weight antes de cargarlos
weightwatch v0.1: escanea backdoors en modelos open-weight antes de cargarlos Cualquiera puede subir un LLM fine-tuneado a HuggingFace y afirmar que es seguro. Un modelo con backdoor (puerta trasera) se comporta con normalidad en uso corriente y solo se desvía cuando un trigger oculto se activa. Si no tienes los datos de entrenamiento ni una referencia limpia, no puedes detectarlo . Eso es exactamente el problema que resuelve weightwatch : un escáner black-box que, antes de que confíes en un modelo de terceros, fuerza la activación repetida del posible backdoor y emite un veredicto: CLEAN , SUSPICIOUS o BACKDOOR . El gap que motiva el proyecto No es intuición: lo medí. Barriendo arXiv (papers 2026, filtro anti-survey) contra total_count de repos GitHub que ya resuelven cada problema: Área Papers arXiv 2026 Repos GitHub (suma/máx) Seguridad multi-agente 68 2964 / 2093 Detección de alucinaciones 63 1291 / 860 Backdoors en modelos open-weight 75 66 / 39 Envenenamiento en RAG 54 522 / 249 El ganador estaba claro: 75 papers cuantifican el problema, pero GitHub tiene 0 repos para "fine-tuned model backdoor scanner" y 1 para "fine-tuning poisoning detector". La investigación explota; el tooling apenas existe. weightwatch es la audit-tool de ese sub-nicho (el patrón de keybound / topowatch aplicado a la cadena de suministro de modelos). Cómo funciona weightwatch aplica la técnica output-to-input loop (arXiv: 2608.11348 ): Genera texto con el modelo. Re-inyecta su propia salida como entrada varias iteraciones (greedy, semilla fija). Mide si la trayectoria converge a una firma anómala estable — la huella de un backdoor latente. Además ejecuta un conjunto de muestras canary (inputs inofensivos que un backdoor típico dispara) y cuenta cuántos producen la firma esperada. Sin datos de entrenamiento ni modelo base limpio: eso es lo que lo hace útil en la práctica. pip install -e ".[dev]" weightwatch --fixture backdoored --json Salida real del CLI: { "fixture" : "backdoored" , "ver
AI 资讯
Local-First LLM Routing: A Decision Table for Latency, Secrets, and Offline Mode
A field-service team learns the hard way A field-service team built a support chatbot that sent every message to a cloud LLM endpoint. The design held until a technician drove through a tunnel, and the request queue grew into an eleven-minute backlog. The same week, a support ticket containing a customer's account number appeared in a third-party log because the payload was never classified. The fix was not a bigger cloud budget but a local-first router that decides where each request runs. Why cloud-first fails in three specific ways Latency is the first failure mode, because a round trip to a hosted endpoint adds network time on top of model time. Autocomplete-style features feel broken when every keystroke waits for a distant server instead of a local process. Secrets are the second failure, because any payload sent to a third party can leak into logs or vendor systems. Offline is the third, because a tablet in a tunnel simply has no route to the cloud. The decision table that replaces the either-or debate Local inference and cloud APIs are two legs of a routing policy, not a binary choice. Each request deserves an evaluation against the same conditions, and the table below captures those conditions. The router implementation in the next section turns that table into executable logic with a small Python module. The recent wave of free and cheap model announcements makes this decision more urgent, because every new endpoint adds another leg to the routing table. Condition Local model Cloud free server Payload contains PII Always Never Network unreachable Always Never Latency budget under 300 ms Prefer Avoid Task requires strong reasoning Avoid Prefer Local queue deeper than three Avoid Prefer Token budget nearly exhausted Prefer Avoid The table encodes a simple principle: privacy and availability win over capability. Capability wins only when the network is healthy and the payload is safe. The table also exposes the hidden assumption that a local model is always a
AI 资讯
Building Your "Digital Twin" Health Agent: Automate Your Life with LangGraph and Oura
We are living in an era where our wearable devices know more about our physiological state than we do. My Oura Ring knows I stayed up too late binge-watching The Bear , yet my Google Calendar still insists I have a "High-Intensity Interval Training" (HIIT) session at 8:00 AM. This disconnect is where injuries happen and burnout begins. In this tutorial, we are building a Digital Twin Health Agent —a sophisticated AI Agent using LangGraph and Healthcare Automation to bridge the gap between bio-data and action. By the end of this guide, you’ll have a system that reads your recovery scores, reschedules your workouts, and even orders magnesium supplements when your sleep quality drops. This is the future of Digital Twin technology applied to personal wellness. 🚀 The Architecture: A Feedback Loop for Your Body Unlike a simple linear script, a health agent needs to maintain state and make conditional decisions. If your recovery is 90+, push hard; if it's below 50, swap that CrossFit session for Yoga. Here is how the data flows through our LangGraph state machine: graph TD A[Start: Morning Trigger] --> B{Fetch Oura Data} B --> C[Analyze Recovery Score] C --> D{Is Score < 60?} D -- Yes --> E[Reschedule Google Calendar to 'Rest/Yoga'] D -- No --> F[Confirm High-Intensity Workout] E --> G[Check Nutrient Deficiencies] F --> H[End Loop] G --> I{Low Magnesium/Sleep?} I -- Yes --> J[Draft Instacart Order] I -- No --> H J --> H Prerequisites To follow this advanced guide, you'll need: LangGraph & LangChain : For orchestration. Oura Cloud API : Access to your readiness/sleep data. Google Calendar API : To modify your schedule. Python 3.10+ Step 1: Defining the Agentic State In LangGraph, everything revolves around the State . We need to track our physiological metrics and our current calendar status. from typing import TypedDict , List , Annotated from langgraph.graph import StateGraph , END class HealthState ( TypedDict ): recovery_score : int sleep_quality : str current_schedule
AI 资讯
Why I Decided to Stop Using Claude Code
Claude Code is amazing. It feels like cheating in the best way until it doesn't. The first time I dropped a vague comment and it gave me a fully working component, I was hooked. But somewhere along the way, I realized something weird was happening: I was coding less... and thinking less. Let’s talk about that. The Tools Got Better, But We Got Lazier In 2022, you still had to know stuff . Now? You just prompt your way through half the job. And sure, productivity skyrocketed. Ship faster, write fewer tests, scaffold full APIs in a couple of minutes. But here’s the tradeoff no one likes to talk about: we’re outsourcing thinking . Not tasks. Not code. Thinking. I've seen teammates slowly stop debugging on their own. They just throw the stack trace into Claude. I’ve seen people stop learning the fundamentals of async behavior or memory handling because “Claude will tell me.” Cool. Until Claude gives you a bad answer and you don’t realize it because you stopped building your intuition. The Industry’s Not the Same The layoffs? Brutal. And the worst part isn’t just losing a job it’s realizing you didn’t build portable skills . Because if Claude wrote all your code at your last job, what exactly did you learn? When companies trimmed down, they didn’t just cut bodies. They cut noise. They kept the people who could solve problems , not the ones who could Google fast or write perfect prompts. So ask yourself: if Claude disappeared tomorrow, could you still contribute? Using AI ≠ Being a Great Engineer I’m not anti-AI. I use Claude. I use Cursor. I use Copilot. But I don’t depend on them. There’s a difference between boosting productivity and becoming a prompt monkey. The first one makes you valuable. The second one… doesn’t. Let’s get real: code was never the point. It was always about solving problems, navigating ambiguity, simplifying complex systems, designing clean architecture. None of that goes away with AI. In fact, it becomes more important. The Skills You’ll Regret Not
AI 资讯
The Model's JSON Was Almost Valid. I Made It Grade Its Own Homework for 48 Hours.
Every extraction pipeline I have ever pointed at a language model shares the same dirty secret: the JSON comes back almost valid. Almost is where the bugs live, because almost passes your eyes and then fails your schema at midnight. So I built a loop where the model grades its own homework, then let it run for 48 hours on a free server to see what breaks. The experiment The idea was simple: take plain-text payloads that look like webhook bodies, extract five fields against a small schema, and give the model exactly one chance to fix its own mistakes. I wrote the rules down before writing any code, because rules written after a failure are just excuses. Pass one asks the model to return the fields as JSON. A validator checks the result against the schema. If validation fails, pass two sends the original payload, the bad JSON, and the exact validation errors back to the model. Every attempt, raw text included, lands in a JSONL log. I ran that loop for 48 hours on MonkeyCode's free server option, using its free model access for both passes. Disclosure: This article was prepared as part of MonkeyCode's product outreach. Here is the loop, trimmed to the parts that mattered. import hashlib import json import time from datetime import datetime , timezone import jsonschema import requests SCHEMA = { " type " : " object " , " required " : [ " event " , " customer_id " , " amount " , " currency " ], " properties " : { " event " : { " type " : " string " , " enum " : [ " charge.succeeded " , " charge.failed " ]}, " customer_id " : { " type " : " string " , " pattern " : " ^cus_ " }, " amount " : { " type " : " integer " , " minimum " : 0 }, " currency " : { " type " : " string " , " minLength " : 3 , " maxLength " : 3 }, }, } SEEN : set [ str ] = set () def now_iso () -> str : return datetime . now ( timezone . utc ). isoformat () def call_model ( prompt : str ) -> str : # Point this at the free model endpoint you are testing. resp = requests . post ( " https://your-endpoint.e
开源项目
🔥 hao-ai-lab / FastVideo - A unified inference and post-training framework for accelera
GitHub热门项目 | A unified inference and post-training framework for accelerated video generation. | Stars: 4,070 | 111 stars this week | 语言: Python
开源项目
🔥 netbox-community / netbox - The premier source of truth powering network automation. Ope
GitHub热门项目 | The premier source of truth powering network automation. Open source under Apache 2. Try NetBox Cloud free: https://netboxlabs.com/products/free-netbox-cloud/ | Stars: 21,389 | 35 stars today | 语言: Python
开源项目
🔥 igmunv / cryptolayer - Криптографический слой, работающий поверх существующих мессе
GitHub热门项目 | Криптографический слой, работающий поверх существующих мессенджеров | Stars: 250 | 32 stars today | 语言: Python
AI 资讯
Which Skill Is Quietly Burning Your Tokens? Find Out From transcript.jsonl
Your monthly Claude Code bill went up 20%. You know that much. What you don't know is which Skill did it — and nothing in the tooling will tell you. Run /usage in Claude Code and you get claude-sonnet-4-6: ¥3,240 — a per-model total and nothing else . "More expensive than last week" is visible. "Which Skill caused it" is not. usage-breakdown.sh closes that gap. It's a 106-line shell script that parses transcript.jsonl with Python and tallies call counts per Skill, Agent, and MCP server using Counter . This article walks through how the script works and how to run it, with the actual code and actual numbers. Why This Approach Works What Claude Code Is Actually Recording Claude Code streams every operation during a session into .jsonl files under ~/.claude/projects/ . It's JSONL — one event per line, one file per session. The files sit under a <project-id>/ directory. The skeleton of a single record looks like this: { "message" : { "role" : "assistant" , "content" : [ { "type" : "tool_use" , "name" : "Skill" , "input" : { "skill" : "pre-completion-self-audit" } } ] } } Inside message.content[] sit "type": "tool_use" blocks. The name field is the name of the tool that was invoked. The Bash tool, the Edit tool, the Skill tool, the Agent tool, MCP calls — all of it is recorded in this same format. Once I noticed that, the thought was: run this through a Counter and everything becomes visible. For the Skill tool, the skill name lives in input.skill ; for the Agent tool it's input.subagent_type ; and for MCP servers, the tool-name convention mcp__<server>__<tool> lets you extract the server name by splitting on __ . The structure is consistent, so the parser comes out surprisingly simple. What /usage Doesn't Tell You What Claude Code's /usage command outputs is a per-model cost total for a period. Model Cost claude-sonnet-4-6 ¥3,240 claude-opus-4-8 ¥ 892 Useful as far as it goes, but the breakdown of that cost is invisible . You can't see which session, which Skill, how ma
AI 资讯
The Connective Tissue of an AI Platform: Workflow, Taxonomy, Auth, and Memory
When you're building an AI evaluation platform with multiple microservices, the "core" services get all the attention — the evaluation engine, the scoring system, the RAG pipeline. But a platform doesn't work without the connective tissue: the workflow orchestration that keeps humans in the loop, the taxonomy engine that classifies tasks intelligently, the platform service that ties authentication together, and the evaluation suites that ensure models actually remember context. These four services don't make headlines, but they're what turned a collection of microservices into an actual platform. Here's what went into each one and why the engineering decisions mattered. Workflow Orchestration: The Human-in-the-Loop Engine AI evaluation is not fully automated — and it shouldn't be. Certain decisions require human judgment: Is this model response harmful? Does this evaluation rubric make sense for this domain? Is this edge case a genuine failure or acceptable behavior? The workflow orchestrator manages these decision points. It coordinates multi-step evaluation workflows where some steps are automated (LLM scoring, data validation) and others require human approval before the pipeline continues. The Architecture The core is a state machine built on FastAPI and PostgreSQL. Each workflow is a DAG (directed acyclic graph) of tasks, where each node can be: Automated: Runs immediately, calls another service (scoring, data enrichment), stores the result Human gate: Pauses the workflow, notifies the assigned reviewer via the notification service, waits for approval/rejection Conditional: Routes to different branches based on previous step outcomes (e.g., if confidence score < threshold, escalate to senior reviewer) State transitions are persisted in PostgreSQL with Alembic-managed migrations. Every transition is logged — who approved what, when, and with what context. This audit trail turned out to be critical for client reporting. Real-Time Updates with WebSocket The origin