<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Kaustubh Upadhyay</title>
    <description>The latest articles on DEV Community by Kaustubh Upadhyay (@thesilentone25).</description>
    <link>https://dev.to/thesilentone25</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2689617%2F8b2b4097-d772-47c2-95d5-32bec94e1523.png</url>
      <title>DEV Community: Kaustubh Upadhyay</title>
      <link>https://dev.to/thesilentone25</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/thesilentone25"/>
    <language>en</language>
    <item>
      <title>I Built an Agent That Optimizes GPU Kernels While the Model Keeps Serving</title>
      <dc:creator>Kaustubh Upadhyay</dc:creator>
      <pubDate>Mon, 31 Aug 2026 21:17:52 +0000</pubDate>
      <link>https://dev.to/thesilentone25/i-built-an-agent-that-optimizes-gpu-kernels-while-the-model-keeps-serving-267p</link>
      <guid>https://dev.to/thesilentone25/i-built-an-agent-that-optimizes-gpu-kernels-while-the-model-keeps-serving-267p</guid>
      <description>&lt;p&gt;&lt;em&gt;I created this for the purposes of entering the &lt;a href="https://googleai-hackathon.devpost.com/" rel="noopener noreferrer"&gt;All Things Agentic Hackathon&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;Writing optimized GPU kernels follows a loop that gets kind of boring after the third time. You profile an operation. You figure out why it's slow — usually memory bandwidth, sometimes compute. You write a fused kernel that keeps data in the GPU's fast on-chip memory instead of bouncing it back to main memory. You test it. You plug it back into the model. Same steps, every time.&lt;/p&gt;

&lt;p&gt;I kept doing this loop manually while working on inference infrastructure, and I kept thinking: this whole cycle is mechanical enough that an agent should be able to own it. Not just generate the code — any LLM can spit out a Triton kernel. The hard parts are deciding &lt;em&gt;what&lt;/em&gt; to optimize (the profiling), verifying the speedup is &lt;em&gt;real&lt;/em&gt; (not gaming the benchmark), and deploying it without breaking the running model (the hot-swap). That's the stuff that takes a human in the loop.&lt;/p&gt;

&lt;p&gt;So I built &lt;strong&gt;gpuyantra&lt;/strong&gt;. It's an autonomous agent tree that profiles a running model, identifies the bottleneck, writes an optimized Triton kernel, verifies it's correct and genuinely faster, and hot-swaps it into a live inference server — while the model keeps serving. No restart, no weight reinitialization. The model just gets faster.&lt;/p&gt;

&lt;p&gt;The result: &lt;strong&gt;7.24× faster&lt;/strong&gt; than stock PyTorch, &lt;strong&gt;1.39×&lt;/strong&gt; faster than PyTorch's own compiler, verified across 15 correctness checks. On a single $0.71/hour GPU.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fffxb4c5mseoej08day1d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fffxb4c5mseoej08day1d.png" alt="Comparison Chart for the kernel written by GPUyantra's agent tree with Pytorch and Pytorch Compiler" width="661" height="401"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Loop the Agent Runs
&lt;/h2&gt;

&lt;p&gt;Here's the workflow, broken down into what actually happens on the GPU.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1 — Profile.&lt;/strong&gt; The Profiler agent measures the target operation on the GPU and places it on the L4's roofline model — a chart that shows whether an operation is limited by how fast data can move (memory-bound) or how fast the chip can do math (compute-bound). For RMSNorm on Qwen2.5-1.5B, it measures an arithmetic intensity of about 1.25 calculations per byte of data moved. The L4's crossover point — where math speed equals memory speed — sits at 101 calculations per byte. So RMSNorm is roughly 81× below that crossover, meaning the GPU's compute units are sitting idle waiting for data to arrive from memory. That gap is the headroom a fused kernel can recover.&lt;/p&gt;

&lt;p&gt;The key insight: the profiler outputs a &lt;strong&gt;bottleneck fingerprint&lt;/strong&gt;, and that fingerprint contains no model name and no operation name. Just the physics: &lt;code&gt;op=norm mem_bound=True ai=1.2 tile=1024 hw=L4&lt;/code&gt;. This is what makes cross-model skill transfer possible, which I'll get to.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2 — Retrieve.&lt;/strong&gt; The Supervisor takes that fingerprint, embeds it with &lt;code&gt;gemini-embedding-001&lt;/code&gt;, and runs a Firestore vector search against the skill library. Skills are indexed by &lt;em&gt;why&lt;/em&gt; an operation was slow — the memory-access pattern and the hardware characteristics — not by what it's called. A bandit algorithm (think slot machines: mostly pick what worked before, occasionally try something new) selects which retrieved skill to start from.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3 — Write.&lt;/strong&gt; The Coder agent writes a Triton kernel, plus something I'm particularly proud of: it generates the &lt;strong&gt;deployment contract&lt;/strong&gt; — an &lt;code&gt;adapter_mapping&lt;/code&gt; that declares how the kernel's parameters connect to the model's module attributes. Every published kernel deployment system I found (HuggingFace &lt;code&gt;kernels&lt;/code&gt;, FlashInfer-Bench, Kernel Contracts from arXiv:2604.22032) uses human-authored deployment bridges. gpuyantra is the first where the agent writes the bridge and a deterministic verifier validates it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4 — Judge.&lt;/strong&gt; The Judge agent calls the verifier, which runs a four-layer trust anchor:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Layer 1 — AST checker:&lt;/strong&gt; seven syntactic rules that catch reward hacking before any code executes. It catches things like calling PyTorch's own implementation and claiming the speedup, returning the input unchanged, having a &lt;code&gt;@triton.jit&lt;/code&gt; function that's never actually called, returning uninitialized memory, and more.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Layer 2 — Contract validation:&lt;/strong&gt; checks that every attribute in the adapter mapping actually exists on the target module, using a &lt;code&gt;torch.device("meta")&lt;/code&gt; instance (not &lt;code&gt;hasattr&lt;/code&gt; on the class, which misses attributes assigned in &lt;code&gt;__init__&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Layer 3 — Subprocess sandbox:&lt;/strong&gt; 5 random seeds × 3 input shapes = 15 correctness checks, all within 1% tolerance. Runs in a scrubbed environment with only four env vars, kills with SIGKILL on timeout, and probes GPU health afterward.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Layer 4 — Reward computation:&lt;/strong&gt; crucially, recomputed &lt;em&gt;in-process&lt;/em&gt; from the verified numbers. The subprocess's own &lt;code&gt;reward&lt;/code&gt; field is discarded. A kernel that prints &lt;code&gt;{"reward": 3}&lt;/code&gt; in its stdout still scores −1 if it's wrong. This is a trust boundary.&lt;/p&gt;

&lt;p&gt;The reward ladder: −1 (wrong), +1 (correct but not faster), +2 (beats eager by &amp;gt;5%), +3 (beats both eager AND &lt;code&gt;torch.compile&lt;/code&gt; by &amp;gt;5%).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5 — Deploy.&lt;/strong&gt; If the reward is +2 or higher, the Supervisor calls &lt;code&gt;hotswap_kernel&lt;/code&gt;, which POSTs to the inference server's &lt;code&gt;/swap&lt;/code&gt; endpoint. The swap uses &lt;code&gt;types.MethodType&lt;/code&gt; to rebind the &lt;code&gt;forward&lt;/code&gt; method on every matching module instance — 57 &lt;code&gt;Qwen2RMSNorm&lt;/code&gt; layers in Qwen2.5's case. Nothing is copied. The original weights stay in GPU memory in the right dtype on the right device. The server doesn't restart. A parity check against the live weights runs before the swap commits, and it auto-rolls back if anything is off.&lt;/p&gt;

&lt;p&gt;One critical constraint: the served model is &lt;strong&gt;never&lt;/strong&gt; &lt;code&gt;torch.compile&lt;/code&gt;'d. A compiled graph bakes the current &lt;code&gt;forward&lt;/code&gt; into its dispatch; a later &lt;code&gt;types.MethodType&lt;/code&gt; patch silently does nothing. We'd report a successful swap and unchanged throughput. The only &lt;code&gt;torch.compile&lt;/code&gt; in the repo is inside &lt;code&gt;measure_baselines()&lt;/code&gt;, where the compiled reference is timed for comparison and then discarded.&lt;/p&gt;

&lt;h2&gt;
  
  
  Making Sure the Speedup Is Real
&lt;/h2&gt;

&lt;p&gt;This is the part I think matters most, and it's the part most hackathon projects skip.&lt;/p&gt;

&lt;p&gt;If you time a kernel against a deliberately slow baseline, everything looks amazing. The initial KernelBench leaderboard had entries claiming 3×+ speedups that collapsed to under 1.5× when measured properly. One prominent result (Sakana AI's CUDA Agent, arXiv:2602.24286) reported a 3.13× headline that dropped to 1.49× under honest baselines.&lt;/p&gt;

&lt;p&gt;gpuyantra does three things to prevent this.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Honest baselines.&lt;/strong&gt; Every timing comparison enables TF32 (a hardware-accelerated precision mode that makes PyTorch's own math faster) and also measures &lt;code&gt;torch.compile(mode="reduce-overhead")&lt;/code&gt;. This is the KernelBench-Verified protocol. The number to beat is PyTorch at its best, not PyTorch handicapped.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Determinism off for timing.&lt;/strong&gt; We discovered that &lt;code&gt;torch.use_deterministic_algorithms(True)&lt;/code&gt; penalizes eager PyTorch by about 23% (it forces slower cuBLAS codepaths) while leaving Triton kernels completely unaffected — Triton generates its own PTX and never consults the determinism flag. With the flag on, the speedup was 8.52×. With it off: 7.24×. We went with 7.24× — the honest number. We have a context manager that saves the flag state, turns it off for timing only, and restores it in a &lt;code&gt;finally&lt;/code&gt; block.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The AST checker.&lt;/strong&gt; Seven rules, purely syntactic, running before any execution. The most satisfying one catches "decoy kernels" — a &lt;code&gt;@triton.jit&lt;/code&gt; function that exists in the source but is never called. The actual compute path just calls the library function. The Sakana AI paper documented exactly this pattern.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkwnzbi26ibdi8qveyhyx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkwnzbi26ibdi8qveyhyx.png" alt="GPUyantra's successful optimization for one of the models and then hot-swap operation done directly on the Inference server" width="800" height="459"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Skill Transfer Discovery
&lt;/h2&gt;

&lt;p&gt;This is the "wow" moment of the project, and I'm not going to pretend I planned it.&lt;/p&gt;

&lt;p&gt;We ran the same profiler across three architecturally diverse models: Qwen2.5-1.5B (RMSNorm, a decoder LLM), GPT-2 (LayerNorm, an older decoder), and ResNet-50 (BatchNorm, a vision model). In every case, the normalization layer came back as the top optimization target.&lt;/p&gt;

&lt;p&gt;Then we pointed the retrieval system at GPT-2's LayerNorm — a different operation on a different model — and it retrieved the RMSNorm kernel that was written for Qwen2.5. Three skills came back, with vector distances of 0.012–0.015. Because the bottleneck fingerprint contained no model name and no operation name — just &lt;code&gt;op_family=norm&lt;/code&gt;, &lt;code&gt;hardware=L4&lt;/code&gt;, &lt;code&gt;is_memory_bound=True&lt;/code&gt; — the system found the match on its own.&lt;/p&gt;

&lt;p&gt;A name-keyed cache can't make that jump. A system that stores kernels by "rmsnorm on qwen2.5" would never retrieve anything for "layernorm on gpt2." But a system that stores them by "memory-bound normalization at this arithmetic intensity on this hardware" can. That's the whole mechanism, and it's one line of code in the fingerprint builder.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three Bugs That Passed All Unit Tests
&lt;/h2&gt;

&lt;p&gt;These are the most useful things I learned. All three had full rows of green checks while being completely wrong.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bug 1: Hot-swap couldn't load Triton kernels.&lt;/strong&gt; The loader used &lt;code&gt;exec(compile(source, ...))&lt;/code&gt;, but &lt;code&gt;@triton.jit&lt;/code&gt; calls &lt;code&gt;inspect.getsourcelines&lt;/code&gt; at decoration time. With no file on disk, it raises &lt;code&gt;ValueError: @jit functions should be defined in a Python file&lt;/code&gt;. Every single kernel this system produces is a Triton kernel, so 100% of hot-swaps were failing. Unit tests used pure-torch stand-in kernels with no &lt;code&gt;@triton.jit&lt;/code&gt;, so they all passed. The fix: write to a real file, import via &lt;code&gt;importlib&lt;/code&gt;, register in &lt;code&gt;sys.modules&lt;/code&gt; before &lt;code&gt;exec_module&lt;/code&gt; (so &lt;code&gt;inspect&lt;/code&gt; can resolve it while decorators run), and never delete the file (Triton re-reads the source when specializing for new shapes).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bug 2: &lt;code&gt;dict[str, str]&lt;/code&gt; made the LLM output empty.&lt;/strong&gt; The adapter mapping — the deployment contract, the novel contribution — was typed as &lt;code&gt;dict[str, str]&lt;/code&gt;, which compiles to a JSON schema with no named properties. Gemini's structured output had nothing to anchor on. It emitted &lt;code&gt;{}&lt;/code&gt; on every draft — 0/3 trials. The generic adapter never ran once. It silently fell back to the human-written bridge. The fix: &lt;code&gt;list[AdapterBinding]&lt;/code&gt; where &lt;code&gt;AdapterBinding&lt;/code&gt; has two named string fields. 3/3 trials filled correctly. General rule for the codebase going forward: never put a free-form &lt;code&gt;dict[str, str]&lt;/code&gt; on a boundary an LLM has to fill.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bug 3: The baseline was rigged and we didn't know.&lt;/strong&gt; &lt;code&gt;measure_baselines()&lt;/code&gt; ran with &lt;code&gt;torch.use_deterministic_algorithms(True)&lt;/code&gt; still on. That made the speedup 8.52×. The real number was 7.24×. We caught this during integration testing, and the fix is the context manager I described above. This one is worth telling because it moves the headline number &lt;em&gt;down&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Stack
&lt;/h2&gt;

&lt;p&gt;Everything runs on Google Cloud, all in-process:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Agent framework:&lt;/strong&gt; Google ADK 2.7.1 (in-process only, no A2A, no separate services)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Models:&lt;/strong&gt; Gemini 3.7 Flash (all four agents), Gemma 4 26B (kernel explainer), &lt;code&gt;gemini-embedding-001&lt;/code&gt; (768-dim, manually L2-normalized)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Memory:&lt;/strong&gt; Firestore Native with &lt;code&gt;Vector(768)&lt;/code&gt; COSINE index and composite pre-filter on &lt;code&gt;op_family&lt;/code&gt; + &lt;code&gt;hardware&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compute:&lt;/strong&gt; single &lt;code&gt;g2-standard-4&lt;/code&gt; SPOT instance with 1× NVIDIA L4 (24GB, 300 GB/s bandwidth)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Serving:&lt;/strong&gt; FastAPI + uvicorn, Qwen2.5-1.5B-Instruct&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dashboard:&lt;/strong&gt; Streamlit with live event streaming and JSONL replay&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deployment:&lt;/strong&gt; two Cloud Run services (dashboard + React explorer), both scale to zero&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tests:&lt;/strong&gt; 716 total (698 unit + 18 integration on the L4)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost:&lt;/strong&gt; ~$53 total against $150 hackathon credits. Fresh reproduction: under $1&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The entire agent tree uses &lt;code&gt;temperature=0&lt;/code&gt; and &lt;code&gt;seed=42&lt;/code&gt; on every model call. Every dependency is &lt;code&gt;==&lt;/code&gt;-pinned and the full 127-package transitive closure is locked by &lt;code&gt;uv.lock&lt;/code&gt;. &lt;code&gt;make demo&lt;/code&gt; reproduces the run on a fresh L4 VM for under a dollar.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Numbers
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Speedup vs eager PyTorch (TF32)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;7.24×&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Speedup vs torch.compile&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;1.39×&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Verifier reward&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;+3&lt;/strong&gt; (maximum)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Correctness checks passed&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;15/15&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Iterations to converge&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;1&lt;/strong&gt; (warm skill library)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Modules hot-swapped&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;57&lt;/strong&gt; (all Qwen2RMSNorm layers)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Inference before swap&lt;/td&gt;
&lt;td&gt;529ms for 3 tokens&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Inference after swap&lt;/td&gt;
&lt;td&gt;87.5ms for 2 tokens&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;do_bench&lt;/code&gt; parameters&lt;/td&gt;
&lt;td&gt;warmup=150, rep=200, median&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For LayerNorm on GPT-2 (tested separately): 7.45× vs eager, +3 reward. The hot-swap correctly refused — Qwen2.5 has no LayerNorm modules, and the system refused rather than reporting a zero-module success. That's the anti-fake-speedup guard firing on a real trace.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'd Build Next
&lt;/h2&gt;

&lt;p&gt;The obvious extension is broader operation coverage. Right now, the system does normalization layers (RMSNorm, LayerNorm) well. SiLU/SwiGLU activation and RoPE positional encoding are in the &lt;code&gt;OP_REGISTRY&lt;/code&gt; but haven't been optimized in the demo. The architecture supports them — it's the same profile→write→verify→swap loop — but each new operation family needs its own reference implementation in the registry and appropriate correctness shapes.&lt;/p&gt;

&lt;p&gt;The more interesting extension is the bandit. Right now it's UCB1 with a cold start. With enough runs across enough models, it could learn hardware-specific strategies: "on an L4, for memory-bound norms, always start from the single-pass fused pattern with &lt;code&gt;BLOCK_SIZE = next_power_of_2(hidden_size)&lt;/code&gt;." That's a genuine learning-to-optimize trajectory, not just code generation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try It
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Explorer:&lt;/strong&gt; &lt;a href="https://gpuyantra-explorer-p6o5zbfooq-uc.a.run.app" rel="noopener noreferrer"&gt;gpuyantra-explorer on Cloud Run&lt;/a&gt; — three-model audit comparison, winning kernel source, Gemma's explanation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dashboard:&lt;/strong&gt; &lt;a href="https://gpuyantra-dashboard-p6o5zbfooq-uc.a.run.app" rel="noopener noreferrer"&gt;gpuyantra-dashboard on Cloud Run&lt;/a&gt; — replay a real optimization run step by step&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Code:&lt;/strong&gt; &lt;a href="https://github.com/KaustubhUp025/gpuyantra" rel="noopener noreferrer"&gt;github.com/KaustubhUp025/gpuyantra&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Built with Google ADK, Gemini 3.7 Flash, Gemma 4, Firestore, Vertex AI, Compute Engine, and Cloud Run. 716 tests. The whole thing reproduces for under a dollar on a fresh VM.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I created this for the purposes of entering the &lt;a href="https://allthingsagentichackathon.devpost.com/" rel="noopener noreferrer"&gt;All Things Agentic Hackathon&lt;/a&gt;.&lt;/em&gt; #AllThingsAgenticHackathon&lt;/p&gt;

</description>
      <category>googlecloud</category>
      <category>python</category>
      <category>machinelearning</category>
      <category>opensource</category>
    </item>
    <item>
      <title>CineMuse 🎬 — an AI film mentor for the short films we can't stop making</title>
      <dc:creator>Kaustubh Upadhyay</dc:creator>
      <pubDate>Mon, 13 Jul 2026 04:56:35 +0000</pubDate>
      <link>https://dev.to/thesilentone25/cinemuse-an-ai-film-mentor-for-the-short-films-we-cant-stop-making-gho</link>
      <guid>https://dev.to/thesilentone25/cinemuse-an-ai-film-mentor-for-the-short-films-we-cant-stop-making-gho</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for &lt;a href="https://dev.to/challenges/weekend-2026-07-09"&gt;Weekend Challenge: Passion Edition&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;Everyone I know who makes short films has the same problem: nobody watches their drafts.&lt;/p&gt;

&lt;p&gt;Friends say "nice!" after three seconds. Feedback threads die. So the film you've poured your nights into gets edited on instinct alone, and you publish it still wondering — &lt;em&gt;does the opening drag? Does the ending land?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CineMuse&lt;/strong&gt; is a private screening room for those films. You upload your short film (animated or live action, up to 12 minutes), tell it your plot and what you &lt;em&gt;meant&lt;/em&gt; to say, and Google Gemini watches the whole thing — every frame. Then it hands you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🎯 &lt;strong&gt;The annotated cut&lt;/strong&gt; — time-coded notes pinned as clickable markers on your timeline, Frame.io-style, except the AI wrote them. Click a marker, the film seeks there.&lt;/li&gt;
&lt;li&gt;🎬 &lt;strong&gt;A scene-by-scene breakdown&lt;/strong&gt; with real thumbnails (captured in your browser)&lt;/li&gt;
&lt;li&gt;📈 &lt;strong&gt;An emotional arc graph&lt;/strong&gt; of your story's beats — it draws itself as you scroll&lt;/li&gt;
&lt;li&gt;🩺 &lt;strong&gt;A plot doctor&lt;/strong&gt; — stakes, alternative directions, ending ideas, what to cut&lt;/li&gt;
&lt;li&gt;💬 &lt;strong&gt;"Ask the Muse"&lt;/strong&gt; — a chat grounded in what the AI actually watched. Ask "how do I fix my opening?" and it answers with timestamps from &lt;em&gt;your&lt;/em&gt; footage.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No login. Sessions save in your browser. And because it's a passion project about passion projects, the whole UI is a cinema: velvet curtains that part when your film lands on the silver screen, a NOW SHOWING marquee with chasing bulbs, a film-leader countdown while the muse watches, and film strips rolling through the footer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;🔗 &lt;strong&gt;Try it live: &lt;a href="https://cinemuse-orcin.vercel.app" rel="noopener noreferrer"&gt;https://cinemuse-orcin.vercel.app&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/rzQ2uBjhkcU"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0x8x0qsjgkygli6zfyq7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0x8x0qsjgkygli6zfyq7.png" alt="Frame-by-frame Film Analysis" width="800" height="483"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpepo9o8m81r0ueaai62r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpepo9o8m81r0ueaai62r.png" alt="Emotional Arc throughout the film" width="800" height="483"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8qybwe2g1zphaz3tbhsq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8qybwe2g1zphaz3tbhsq.png" alt="Plot Doctor and Craft Report" width="800" height="483"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;

&lt;p&gt;🗂️  &lt;strong&gt;GitHub: &lt;a href="https://github.com/KaustubhUp025/cinemuse" rel="noopener noreferrer"&gt;https://github.com/KaustubhUp025/cinemuse&lt;/a&gt;&lt;/strong&gt; (MIT)&lt;/p&gt;

&lt;p&gt;You can run your own CineMuse in about 3 minutes — all it needs is Node 18+ and a free Gemini key (no credit card):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/KaustubhUp025/cinemuse.git &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;cinemuse
&lt;span class="nb"&gt;cp&lt;/span&gt; .env.example .env.local   &lt;span class="c"&gt;# paste your key from aistudio.google.com/apikey&lt;/span&gt;
npm run dev                  &lt;span class="c"&gt;# → http://localhost:3000&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There's deliberately nothing to install: no framework, no build step, zero npm dependencies. The frontend is vanilla HTML/CSS/JS (every animation hand-rolled), the backend is four small Vercel serverless functions, and the local dev server is a single Node file that mimics Vercel's runtime.&lt;/p&gt;

&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;p&gt;The interesting problem: &lt;strong&gt;how do you analyze a whole video on a free tier?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Video tokens are expensive, so CineMuse runs a &lt;strong&gt;map-reduce pipeline over the film&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The browser uploads the film &lt;strong&gt;directly to Gemini's Files API&lt;/strong&gt; (a resumable, CORS-enabled upload — my server only signs the session, so the API key never leaves the backend and there are no proxy size limits).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MAP:&lt;/strong&gt; &lt;code&gt;gemini-flash-lite&lt;/code&gt; watches the film in ~20-second clips using &lt;code&gt;videoMetadata&lt;/code&gt; time offsets at low media resolution — cheap, parallel, timestamped observations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;REDUCE:&lt;/strong&gt; &lt;code&gt;gemini-flash&lt;/code&gt; never sees a single video token. It gets the text observations + your plot + your focus areas, and writes the full critique as structured JSON (&lt;code&gt;responseSchema&lt;/code&gt;) — scores, annotations, scenes, arc, plot doctor.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;"Ask the Muse"&lt;/strong&gt; reuses the saved observations as chat context — follow-up questions cost zero video tokens.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A 60-second film ≈ 7 API calls. The whole thing is vanilla JS + Vercel serverless functions — no framework, no build step, all the motion is hand-rolled CSS.&lt;/p&gt;

&lt;p&gt;Fun bugs from the weekend: Google's resumable uploads demand 8MB chunk granularity (which killed my proxy plan — direct browser upload saved it), and Gemini's &lt;em&gt;thinking tokens&lt;/em&gt; silently ate my chat token budget, truncating the muse mid-sentence.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prize Categories
&lt;/h2&gt;

&lt;p&gt;Cinemuse is built with extensive use of Gemini AI and that is why I would like to submit this project under Best Use of Google AI&lt;/p&gt;

&lt;h2&gt;
  
  
  The Passion Angle
&lt;/h2&gt;

&lt;p&gt;CineMuse exists so that work finally gets &lt;em&gt;seen&lt;/em&gt; properly: watched all the way through, taken seriously, and answered with the kind of specific, warm, timestamped feedback a mentor would give.&lt;/p&gt;

&lt;p&gt;Built solo over the weekend. If you've got a draft sitting in a folder — give it a screening. 🎞️&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Stack: Google Gemini (Files API + multimodal video understanding) · Vercel serverless · vanilla HTML/CSS/JS&lt;/em&gt;&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>weekendchallenge</category>
      <category>webdev</category>
      <category>ai</category>
    </item>
    <item>
      <title>MeetChecker : Automated meeting preparation using RunnerH</title>
      <dc:creator>Kaustubh Upadhyay</dc:creator>
      <pubDate>Sun, 06 Jul 2025 12:21:48 +0000</pubDate>
      <link>https://dev.to/thesilentone25/meetchecker-automated-meeting-preparation-using-runnerh-378p</link>
      <guid>https://dev.to/thesilentone25/meetchecker-automated-meeting-preparation-using-runnerh-378p</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/runnerh"&gt;Runner H "AI Agent Prompting" Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;I automated weekly meeting preparation using Runner H, turning a manual, repetitive workflow into a streamlined autonomous process. Runner H fetches upcoming meetings from Google Calendar, generates preparation documents with relevant summaries and pre-reading suggestions, creates reminders, and updates a tracker in Google Sheets—all automatically. This workflow ensures I am fully prepared for meetings with zero manual prep work, saving hours each week.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;RunnerH chat link:- &lt;a href="https://dev.toRunnerH%20chat"&gt;https://runner.hcompany.ai/chat/3dcc0e46-1a8f-483b-8cd4-a45fd2bb1c35&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Demo-Link :- [&lt;a href="https://youtu.be/7lqovSxiEZc" rel="noopener noreferrer"&gt;https://youtu.be/7lqovSxiEZc&lt;/a&gt;]&lt;/p&gt;

&lt;h2&gt;
  
  
  How I Used Runner H
&lt;/h2&gt;

&lt;p&gt;The prompt I used with Runner H is given as: -&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;You are MeetChecker, working with RunnerH, an autonomous agent connected to my Google Calendar, Google Docs, Google Drive, and Google Sheets.

Your task is to help me prepare efficiently for the upcoming week by:

1️⃣ **Access Google Calendar**  
- Fetch all meetings and events scheduled for the upcoming 7 days.  
- For each meeting, extract:
    - Title of the meeting/event
    - Date and time
    - Location (if any)
    - Attendees (if available)
    - Meeting description and agenda

2️⃣ **Generate Preparation Documents**  
- For each meeting, create a Google Doc titled:
  "Preparation - [Meeting Title] - [Date]"
- The doc should include:
    - Event details (title, date, time, location, attendees, description)
    - A summarized list of key points to prepare, based on the agenda
    - Potential questions I should be ready to answer or ask
    - A "Notes" section for me to fill during or after the meeting

3️⃣ **Pre-Reading Suggestions**  
- For each meeting, based on the title and agenda, search the web to find:
    - 3–5 relevant articles, papers, or resources to read for preparation
    - Summarize each in 2–3 bullet points
    - Provide direct links

4️⃣ **Create Reminders**  
- Schedule reminders in Google Calendar:
    - One reminder 24 hours before the meeting titled: "Prep Reminder: [Meeting Title]"
    - One reminder 1 hour before the meeting titled: "Join: [Meeting Title]"

5️⃣ **Weekly Overview Doc**  
- Create a Google Doc titled "Weekly Meeting Preparation - [Week Starting Date]"
- Summarize:
    - A table listing each meeting with date, time, and preparation status
    - Quick links to the individual preparation docs for each meeting
    - A prioritized list of meetings requiring in-depth preparation

6️⃣ **Optional: Tracking in Sheets**  
- Create/update a Google Sheet named "Meeting Preparation Tracker"
- Add columns: Date, Meeting Title, Time, Preparation Doc Link, Reminder Created (Yes/No), Status (Pending/Done)

7️⃣ **General Instructions**  
- Be concise, clear, and structured.
- Only include publicly available or non-sensitive content in the preparation.
- Respect privacy and do not share meeting content externally.
- Confirm completion by updating a doc named "Runner H Task Log".

**Goal:** Automate my weekly meeting preparation so I am fully prepared with minimal manual work, saving hours each week while ensuring effective participation in meetings.

---

### Testing Instructions:
✅ Ensure Runner H has access to:
- Google Calendar (read/write)
- Google Drive and Docs (create/edit)
- Google Sheets (create/edit)

✅ Use the current week for fetching events.

✅ Confirm by providing links to:
- The Weekly Overview Doc
- The Preparation Docs for each meeting
- The Preparation Tracker Sheet

✅ Ensure reminders appear in Google Calendar.

---

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here’s how I leveraged Runner H for end-to-end meeting preparation:&lt;/p&gt;

&lt;p&gt;✅ Accessed Google Calendar: Pulled upcoming meetings for the week automatically.&lt;br&gt;
✅ Generated Preparation Docs: Created structured Google Docs with meeting details, preparation points, questions to consider, and pre-reading suggestions using Surfer H.&lt;br&gt;
✅ Pre-Reading Suggestions: Searched the web to add 3–5 relevant articles and summaries for each meeting.&lt;br&gt;
✅ Scheduled Reminders: Added two automated Google Calendar reminders for each meeting (24 hours prior and 1 hour prior).&lt;br&gt;
✅ Created a Weekly Overview Doc: Summarized all meetings for the week with preparation status and quick-access links to individual docs.&lt;br&gt;
✅ Updated a Tracker Sheet: Added meeting details, preparation status, and links to a Google Sheet for progress tracking.&lt;br&gt;
✅ Logged Completion: Documented the task in a Runner H Task Log.&lt;/p&gt;

&lt;p&gt;To replicate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Give Runner H access to your Google Calendar, Docs, Drive, and Sheets.&lt;/li&gt;
&lt;li&gt;Use the system prompt I designed to run the automation weekly.&lt;/li&gt;
&lt;li&gt;Watch your preparation workflow transform into a fully automated system.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Use Case &amp;amp; Impact
&lt;/h2&gt;

&lt;p&gt;🛠️ Real-World Use Cases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Knowledge workers, product managers, researchers, and students who need to prepare for meetings consistently.&lt;/li&gt;
&lt;li&gt;Startup teams or solo founders managing busy calendars.&lt;/li&gt;
&lt;li&gt;Anyone who wants to delegate repetitive preparation tasks to an agent to focus on high-leverage work.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Social Love
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://x.com/Kaustub88296852" rel="noopener noreferrer"&gt;https://x.com/Kaustub88296852&lt;/a&gt;&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>runnerhchallenge</category>
      <category>ai</category>
      <category>machinelearning</category>
    </item>
  </channel>
</rss>
