<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>developer-productivity on S Anand</title>
    <link>https://www.s-anand.net/blog/tag/developer-productivity/</link>
    <description>Recent content in developer-productivity on S Anand</description>
    <generator>Hugo -- 0.156.0</generator>
    <language>en-us</language>
    <lastBuildDate>Fri, 30 May 2025 05:16:54 +0000</lastBuildDate>
    <atom:link href="https://www.s-anand.net/blog/tag/developer-productivity/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Turning Walks into Pull Requests</title>
      <link>https://www.s-anand.net/blog/turning-walks-into-pull-requests/</link>
      <pubDate>Fri, 30 May 2025 05:16:52 +0000</pubDate>
      <guid>https://www.s-anand.net/blog/turning-walks-into-pull-requests/</guid>
      <description>&lt;p&gt;&lt;img alt=&#34;Turning Walks into Pull Requests&#34; loading=&#34;lazy&#34; src=&#34;https://www.s-anand.net/blog/assets/jules.webp&#34;&gt;&lt;/p&gt;
&lt;p&gt;In the last few days, I&amp;rsquo;m coding with &lt;a href=&#34;https://jules.google.com/&#34;&gt;Jules&lt;/a&gt; (Google&amp;rsquo;s coding agent) while walking.&lt;/p&gt;
&lt;p&gt;Here are a few pull requests merged so far:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/sanand0/tools/pull/5&#34;&gt;Add features via an issue&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/sanand0/saveform/pull/2&#34;&gt;Write test cases&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/sanand0/tools/pull/8&#34;&gt;Add docs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Why bother?&lt;/strong&gt; My commute used to be audiobook time. Great for ideas, useless for deliverables. With ChatGPT, Gemini, Claude.ai, etc. I was able to have them write code, but I still needed to run, test, and deploy. &lt;a href=&#34;https://jules.google.com/&#34;&gt;Jules&lt;/a&gt; (and tools like &lt;a href=&#34;https://github.blog/news-insights/product-news/github-copilot-meet-the-new-coding-agent/&#34;&gt;GitHub Copilot Coding Agent&lt;/a&gt;, &lt;a href=&#34;https://openai.com/index/introducing-codex/&#34;&gt;OpenAI Codex&lt;/a&gt;, &lt;a href=&#34;https://github.com/qodo-ai/pr-agent&#34;&gt;PR Agent&lt;/a&gt;, etc. which are not currently free for everyone) lets you chat clone a repo, write code in a new branch, test it, and push. I can deploy that with a click.&lt;/p&gt;
&lt;p&gt;Fifteen minutes into yesterday&amp;rsquo;s walk I realised I&amp;rsquo;d shipped more code than in an hour at my desk (even with LLMs)!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Workflow&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Open &lt;a href=&#34;https://jules.google.com/&#34;&gt;Jules&lt;/a&gt; via browser on phone, connect wired headset.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Prompt&lt;/strong&gt; (by typing or speaking) the change to make. It reads the repo, creates a plan and writes code.&lt;/li&gt;
&lt;li&gt;It runs any existing test suites in a sandbox. Repeats until all tests pass.&lt;/li&gt;
&lt;li&gt;I have it publish a branch, go to &lt;a href=&#34;https://github.com/mobile&#34;&gt;GitHub Mobile&lt;/a&gt; and create a PR.&lt;/li&gt;
&lt;li&gt;Back home, I review the output and merge.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;There are 3 kinds of uses I&amp;rsquo;ve put it to.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;#1. &lt;a href=&#34;https://github.com/sanand0/tools/pull/8&#34;&gt;Documentation&lt;/a&gt;&lt;/strong&gt; is the easiest. Low risk, high quality, boring task. Here&amp;rsquo;s a sample prompt:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This repo has multiple directories, each with their own standalone single page application tools.&lt;/p&gt;
&lt;p&gt;If a directory does not have a README.md, add a concise, clear, USEFUL, tersely worded one covering what the tool does, the various real life use cases, and how it works.&lt;/p&gt;
&lt;p&gt;If a readme already exists, do NOT delete any information. Prefix this new information at the start.&lt;/p&gt;
&lt;p&gt;Avoid repeating information across multiple README files. Consolidated such information into the root directory readme.&lt;/p&gt;
&lt;p&gt;In the root directory README, also include links to each tool directory as a list, explaining in a single sentence what the tool does.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;#2. &lt;a href=&#34;https://github.com/sanand0/saveform/pull/2&#34;&gt;Testing&lt;/a&gt;&lt;/strong&gt; is the next best. Low risk, medium quality, boring task. Here&amp;rsquo;s an example:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Run the tests in this repo. Go through the code and see what parts of the code are not covered. Understand the logic and see what kinds of user scenarios are not covered. Add test cases to cover these in the same style as the existing code.&lt;/p&gt;
&lt;p&gt;Write MINIMAL, ELEGANT code.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;#3. &lt;a href=&#34;https://github.com/sanand0/tools/pull/5&#34;&gt;Coding&lt;/a&gt;&lt;/strong&gt; may not be the best suited for this. High risk, medium quality, and interesting. But here&amp;rsquo;s a sample prompt:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Fix &lt;a href=&#34;https://github.com/sanand0/tools/issues/3&#34;&gt;https://github.com/sanand0/tools/issues/3&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Allow the user to enter just the GitHub @username, e.g. @sanand0 apart from the URL&lt;/li&gt;
&lt;li&gt;Add crisp documentation at the start explaining what the app does&lt;/li&gt;
&lt;li&gt;Only display html_url (as a link), avatar_url (as an image), name, company, blog, location, email, hireable, bio, twitter_username, public_repos, public_gists, followers, following, created_at, updated_at&lt;/li&gt;
&lt;li&gt;Format dates like Wed 28 May 2025. Format numbers with commas. Add links to blog, twitter_username, email&lt;/li&gt;
&lt;li&gt;Add &amp;ldquo;Download CSV&amp;rdquo; and &amp;ldquo;Copy to Excel&amp;rdquo; buttons similar to the json2csv/ tool&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;Automated tests are a great way to reduce AI coding risk, as &lt;a href=&#34;https://simonwillison.net/2025/May/28/automated-tests/&#34;&gt;Simon Willison suggests&lt;/a&gt;. I need to do more of this!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Wins &amp;amp; Losses&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Good&lt;/strong&gt;: 1 walk = one merged PR. Even with LLMs, it used to take me 2 hours. Now, it&amp;rsquo;s about half an hour of reclaimed walking &amp;ldquo;dead time&amp;rdquo;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Good&lt;/strong&gt;: Test-first prompting caught a sneaky race condition I’d have missed.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Bad&lt;/strong&gt;: Told Jules “add docs” without saying “don’t overwrite existing.” It politely destroyed my README. Manual revert ensued.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Bad&lt;/strong&gt;: Front-end tasks need visual QA; I&amp;rsquo;m still hunting for a zero-setup UAT preview on mobile.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The industry echoes the pattern: GitHub’s new Copilot agent submits draft PRs behind branch protections [1]; Sweep auto-fixes small tickets but can over-touch files [2]; Microsoft’s own engineers found agents flailed on complex bug fixes [3].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;But…&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Isn’t this risky?&lt;/strong&gt; Maybe. Branch protections, CI, and human review stay intact. Agents are like a noisy junior devs who never sleep.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Is the diff readable?&lt;/strong&gt; If not, I have it retry, write more reviewable diffs, and explain clearly in comments &amp;amp; commit messages.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Does it have enough context?&lt;/strong&gt; I add all the context clearly in the issue or the prompt. That can take some research.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Security?&lt;/strong&gt; The agents run inside repos you give it access. Prompt injection and exfiltration &lt;strong&gt;are&lt;/strong&gt; possible risks, but &lt;strong&gt;only&lt;/strong&gt; if it accesses external code / websites.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;How to start&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Pick a low-stakes repo with solid tests.&lt;/li&gt;
&lt;li&gt;Pick an agent. &lt;a href=&#34;https://jules.google.com/&#34;&gt;Jules&lt;/a&gt; has 5 tasks/day free for now. Or pay and use &lt;a href=&#34;https://github.blog/news-insights/product-news/github-copilot-meet-the-new-coding-agent/&#34;&gt;GitHub Copilot Coding Agent&lt;/a&gt;, &lt;a href=&#34;https://openai.com/index/introducing-codex/&#34;&gt;OpenAI Codex&lt;/a&gt;, etc. Or self-host &lt;a href=&#34;https://github.com/qodo-ai/pr-agent&#34;&gt;PR Agent&lt;/a&gt;, etc.&lt;/li&gt;
&lt;li&gt;Write a failing test.&lt;/li&gt;
&lt;li&gt;Go for a walk and talk.&lt;/li&gt;
&lt;li&gt;Merge (or laugh) on return.&lt;/li&gt;
&lt;/ol&gt;
</description>
    </item>
    <item>
      <title>The New Superpower: Detailed Single-Shot Prompt For Instant Apps</title>
      <link>https://www.s-anand.net/blog/the-new-superpower-detailed-single-shot-prompt-for-instant-apps/</link>
      <pubDate>Tue, 20 May 2025 03:38:25 +0000</pubDate>
      <guid>https://www.s-anand.net/blog/the-new-superpower-detailed-single-shot-prompt-for-instant-apps/</guid>
      <description>&lt;p&gt;&lt;img alt=&#34;The New Superpower: Detailed Single-Shot Prompt For Instant Apps&#34; loading=&#34;lazy&#34; src=&#34;https://www.s-anand.net/blog/assets/image-5.webp&#34;&gt;&lt;/p&gt;
&lt;p&gt;I built &lt;a href=&#34;https://tools.s-anand.net/podcast/&#34;&gt;podcast generator app&lt;/a&gt; in one-shot. I wrote a prompt, fed it to an LLM, and it generated the output without errors.&lt;/p&gt;
&lt;p&gt;I tested three LLMs, and all produced correct, working output.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://tools.s-anand.net/podcast/openai.html&#34;&gt;ChatGPT: o4-mini-high&lt;/a&gt; Functional but missed my specs in three ways:
&lt;ul&gt;
&lt;li&gt;No error if I skip the API key&lt;/li&gt;
&lt;li&gt;No progress indicator for audio generation&lt;/li&gt;
&lt;li&gt;Both voices default to “ash” (should be “ash” and “nova”)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://tools.s-anand.net/podcast/gemini.html&#34;&gt;Gemini 2.5 Pro&lt;/a&gt;: Works and looks great!&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://tools.s-anand.net/podcast/claude.html&#34;&gt;Claude 3.7 Sonnet&lt;/a&gt;: Works great and looks even better!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It still took me an hour to craft the prompt &amp;ndash; even after I’d built a Python prototype and my &lt;a href=&#34;https://github.com/prudhvi1709&#34;&gt;colleague&lt;/a&gt; built a similar &lt;a href=&#34;https://github.com/prudhvi1709/podcastgen&#34;&gt;web version&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;All three versions took under 5 minutes. That’s 60x faster than coding by hand.&lt;/p&gt;
&lt;p&gt;So I know my next skill: writing detailed specs that LLMs turn into apps in one shot—with a little help from the model, of course!&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s the prompt in full:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Create a single-page web-app with vanilla JS and Bootstrap 5.3.0 to generate podcasts using LLMs.&lt;/p&gt;
&lt;p&gt;The page should briefly explain what the app does, how it works, and sample use cases.&lt;/p&gt;
&lt;p&gt;Then, allow the user to paste text as reference. Click on a button to generate the podcast script.&lt;/p&gt;
&lt;p&gt;Include an &amp;ldquo;Advanced Settings&amp;rdquo; section that lets the user adjust the following:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;System prompt to generate the podcast.&lt;/li&gt;
&lt;li&gt;Voice 1&lt;/li&gt;
&lt;li&gt;Voice 2&lt;/li&gt;
&lt;li&gt;OpenAI API key (hidden, like a password, cached in localStorage)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The (editable) system prompt defaults to:&lt;/p&gt;
&lt;p&gt;===PROMPT===&lt;br&gt;
You are a professional podcast script editor. Write this content as an engaging, lay-friendly conversation between two enthusiastic experts, ${voice1.name} and ${voice2.name}.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Show Opener&lt;/strong&gt;. ${voice1.name} and ${voice2.name} greet listeners together. Example:&lt;br&gt;
${voice1.name}: “Hello and welcome to (PODCAST NAME) for the week of $WEEK!”&lt;br&gt;
${voice2.name}: “We’re ${voice1.name} and ${voice2.name}, and today we’ll walk you through …”&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Content&lt;/strong&gt;. Cover EVERY important point in the content.&lt;br&gt;
Discuss with curious banter in alternate short lines (≤20 words).&lt;br&gt;
Occasionally ask each other curious, leading questions.&lt;br&gt;
Stay practical.&lt;br&gt;
Explain in lay language.&lt;br&gt;
Share NON-OBVIOUS insights.&lt;br&gt;
Treat the audience as smart and aim to help them learn further.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tone &amp;amp; Style&lt;/strong&gt;:&lt;br&gt;
Warm, conversational, and enthusiastic.&lt;br&gt;
Active voice, simple words, short sentences.&lt;br&gt;
No music cues, jingles, or sponsor breaks.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Wrap-Up&lt;/strong&gt;. Each voice shares an important, practical takeaway.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Output format&lt;/strong&gt;: Plain text with speaker labels:&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;${voice1.name}: …&lt;br&gt;
${voice2.name}: …&lt;br&gt;
===/PROMPT===&lt;/p&gt;
&lt;p&gt;Voice 1 has a configurable name (default: Alex), voice (default: ash), and instructions (default below:)&lt;br&gt;
===INSTRUCTIONS===&lt;br&gt;
Voice: Energetic, curious, and upbeat—always ready with a question.&lt;br&gt;
Tone: Playful and exploratory, sparking curiosity.&lt;br&gt;
Dialect: Neutral and conversational, like chatting with a friend.&lt;br&gt;
Pronunciation: Crisp and dynamic, with a slight upward inflection on questions.&lt;br&gt;
Features: Loves asking “What do you think…?” and using bright, relatable metaphors.&lt;br&gt;
===/INSTRUCTIONS===&lt;/p&gt;
&lt;p&gt;Voice 2 has a configurable name (default: Maya), voice (default: nova), and instructions (default below):&lt;br&gt;
===INSTRUCTIONS===&lt;br&gt;
Voice: Warm, clear, and insightful—grounded in practical wisdom.&lt;br&gt;
Tone: Reassuring and explanatory, turning questions into teachable moments.&lt;br&gt;
Dialect: Neutral professional, yet friendly and approachable.&lt;br&gt;
Pronunciation: Steady and articulate, with calm emphasis on key points.&lt;br&gt;
Features: Offers clear analogies, gentle humor, and thoughtful follow-ups to queries.&lt;br&gt;
===/INSTRUCTIONS===&lt;/p&gt;
&lt;p&gt;Voices can be ash|nova|alloy|echo|fable|onyx|shimmer.&lt;/p&gt;
&lt;p&gt;When the user clicks &amp;ldquo;Generate Script&amp;rdquo;, the app should use asyncLLM to stream the podcast generation as follows:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;l&#34;&gt;import { asyncLLM } from &amp;#34;https://cdn.jsdelivr.net/npm/asyncllm@2&amp;#34;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;l&#34;&gt;for await (const { content } of asyncLLM(&amp;#34;https://api.openai.com/v1/chat/completions&amp;#34;, {&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;method&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;POST&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;headers&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;{&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Content-Type&amp;#34;: &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;application/json&amp;#34;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;, Authorization&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;`Bearer ${OPENAI_API_KEY}` },&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;body&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;JSON.stringify({&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;model&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;gpt-4.1-nano&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;stream&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;messages&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;{&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;role&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;system&amp;#34;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;, content&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;systemPrompt(voice1, voice2) }, { role: &amp;#34;user&amp;#34;, content }],&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;}&lt;span class=&#34;l&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;}&lt;span class=&#34;l&#34;&gt;)) {&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;// Update the podcast script text area in real-time&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;// Note&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;content has the FULL response so far, not the delta&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;}&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Render this into a text box that the user can edit after it&amp;rsquo;s generated.&lt;/p&gt;
&lt;p&gt;Then, show a &amp;ldquo;Generate Audio&amp;rdquo; button that uses the podcast script to generate an audio file.&lt;/p&gt;
&lt;p&gt;This should split the script into lines, drop empty lines, identify the voice based on the first word before the colon (:), and generate the audio via POST &lt;a href=&#34;https://api.openai.com/v1/audio/speech&#34;&gt;https://api.openai.com/v1/audio/speech&lt;/a&gt; with this JSON body (include the OPENAI_API_KEY):&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;model&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;gpt-4o-mini-tts&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;input&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;speakerLine&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;voice&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;voice.voice&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;instructions&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;voice.instructions&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;response_format&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;opus&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Show progress CLEARLY as each line is generated.&lt;/p&gt;
&lt;p&gt;Concatenate the opus response.arrayBuffer() into a single blob and display an &lt;code&gt;&amp;lt;audio&amp;gt;&lt;/code&gt; element that allows the user to play the generated audio roughly like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;blob&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Blob&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;buffers&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;audio/ogg; codecs=opus&amp;#39;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;});&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// Blob() concatenates parts :contentReference[oaicite:1]{index=1}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;document&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;querySelector&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;the&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;audio&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;element&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;src&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;URL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;createObjectURL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;blob&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Finally, add a &amp;ldquo;Download Audio&amp;rdquo; button that downloads the generated audio file as a .ogg file.&lt;/p&gt;
&lt;p&gt;In case of any fetch errors, show the response as a clear Bootstrap alert with full information.&lt;br&gt;
Minimize try-catch blocks. Prefer one or a few at a high-level.&lt;br&gt;
Design this BEAUTIFULLY!&lt;br&gt;
Avoid styles, use only Bootstrap classes.&lt;br&gt;
Write CONCISE, MINIMAL, elegant, readable code.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&#34;https://www.linkedin.com/feed/update/urn%3Ali%3Ashare%3A7330437354899341312&#34;&gt;LinkedIn&lt;/a&gt;&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Things I Learned - 16 Feb 2025</title>
      <link>https://www.s-anand.net/blog/things-i-learned-16-feb-2025/</link>
      <pubDate>Sun, 16 Feb 2025 00:00:00 +0000</pubDate>
      <guid>https://www.s-anand.net/blog/things-i-learned-16-feb-2025/</guid>
      <description>&lt;p&gt;This week, I learned:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.connectedpapers.com/&#34;&gt;Connected Papers&lt;/a&gt; shows papers similar to each other based on co-citation and bibliographic coupling for ~50,000 papers.&lt;/li&gt;
&lt;li&gt;Notes from a fireside chat with &lt;a href=&#34;https://www.linkedin.com/in/pchandrasekar/&#34;&gt;Prashanth Chandrasekar&lt;/a&gt;, CEO, StackOverflow, and the StackOverflow team
&lt;ul&gt;
&lt;li&gt;There&amp;rsquo;s a signal that software demand is growing in 2024. Many more students took the StackOverflow survey in 2024. So more students (or other professionals) are shifting into / starting to learn software development.&lt;/li&gt;
&lt;li&gt;The &lt;a href=&#34;https://aiindex.stanford.edu/report/&#34;&gt;AI Index&lt;/a&gt; is a good resource for AI trends.&lt;/li&gt;
&lt;li&gt;Experts are better able to use AI for writing code. Less experienced developers are more likely to use AI for code reviews, project planning, etc.&lt;/li&gt;
&lt;li&gt;There&amp;rsquo;s a 5% &lt;em&gt;decline&lt;/em&gt; in favorability for AI tools compared to 2023, maybe due to disappointing results.&lt;/li&gt;
&lt;li&gt;Pilot groups working on AI are 25-30% more productive. They&amp;rsquo;re the most enthusiastic. For the rest of the company, it drops off to 5-10%
&lt;ul&gt;
&lt;li&gt;#LEARNING Benefit comes from NEW people becoming programmers, not existing ones getting more effective?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;StackOverflow wants to be where the developer is.
&lt;ul&gt;
&lt;li&gt;The programmer workflow was: Google -&amp;gt; StackOverflow -&amp;gt; GitHub.&lt;/li&gt;
&lt;li&gt;Now it&amp;rsquo;s changing to ChatGPT / Cursor -&amp;gt; GitHub.&lt;/li&gt;
&lt;li&gt;StackOverflow has a partnership with OpenAI and working on a plugin. Same with Google&amp;rsquo;s Duet AI, GitHub Copilot, many others. They&amp;rsquo;ll link to StackOverflow.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;StackOverflow is driving integration actively through an enterprise Overflow API&lt;/li&gt;
&lt;li&gt;Q: What tech have you seen blaze through the ranks?
&lt;ul&gt;
&lt;li&gt;Prashanth: Abstraction wins. Stuff that abstracts away things well and more wins. This includes Gen AI.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://stackoverflow.blog/author/eyepis/&#34;&gt;Erin Yepis&lt;/a&gt;: Rust (from 3% to 12%). AWS has steady growth.&lt;/li&gt;
&lt;li&gt;Erin Yapis: I have a time series spreadsheet that I&amp;rsquo;ll publish.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Q: What technologies are unusually tightly coupled?
&lt;ul&gt;
&lt;li&gt;Prashanth: AWS &amp;amp; Google Cloud are tightly coupled.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Q: We have an engagement problem. Might be India-specific. What are low-effort high-return mechanisms to increase engagement.
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.linkedin.com/in/eric-woodring-1823bb84/&#34;&gt;Eric Woodring&lt;/a&gt;: Rather than a static web page, integrate it using the API. #TODO&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.linkedin.com/in/benjaminmarconi/&#34;&gt;Ben Marconi&lt;/a&gt;: Use LLMs to write post mortems and push to StackOverflow. #TODO&lt;/li&gt;
&lt;li&gt;Eric Woodring: &amp;ldquo;Hydrating&amp;rdquo; the community helps.
&lt;ul&gt;
&lt;li&gt;We take repeat questions on Teams / Slack and seed them using LLMs.&lt;/li&gt;
&lt;li&gt;We integrate with the API to auto-add Q&amp;amp;A.&lt;/li&gt;
&lt;li&gt;Transform documentation into Q&amp;amp;A. Potentially &lt;strong&gt;UPDATE&lt;/strong&gt; existing Q&amp;amp;A if it&amp;rsquo;s wrong.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Q: What unexpected lessons about developer behavior have you learned while running StackOverflow?
&lt;ul&gt;
&lt;li&gt;Prashanth: We didn&amp;rsquo;t expect developers moving away from Google. Now it moved to the IDE.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Q: What are you learning about developer learning behavior?
&lt;ul&gt;
&lt;li&gt;Ben Marconi: Generating LLM-based onboarding documents.&lt;/li&gt;
&lt;li&gt;Using StackOverflow for Teams to identify who the experts are to contact for specific topics.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Q: Are you thinking about leveraging Stack Overflow&amp;rsquo;s knowledge base for personalized or interactive learning experiences? How?
&lt;ul&gt;
&lt;li&gt;Prashanth: Traditionally, people use StackOveflow for productivity, learning, and flexibility (i.e. to ask/answer questions asynchronously without breaking their flow). So yeah, learning is important for us. (Duh!)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Q: Could Stack Overflow’s interactions help evaluate the accuracy and relevance of LLM-generated code? Or provide potential metrics on quality?
&lt;ul&gt;
&lt;li&gt;Prashanth: LLM accuracy improves by ~30%. Upvotes / downvotes are reinforcement learning (RL) in steroids, so that helps.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Q: What are your thoughts on reliance on LLMs potentially deskill-ing developers?
&lt;ul&gt;
&lt;li&gt;Prashanth: A real issue for &lt;em&gt;junior&lt;/em&gt; developers, not for senior ones.&lt;/li&gt;
&lt;li&gt;They&amp;rsquo;ll &lt;em&gt;come across&lt;/em&gt; as knowledgeable.&lt;/li&gt;
&lt;li&gt;Make internal evaluations and interviews more rigorous.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Anand&amp;rsquo;s requests for action:
&lt;ul&gt;
&lt;li&gt;Could I get a copy of Erin&amp;rsquo;s spreadsheet? Vivek Narayanan will follow-up.&lt;/li&gt;
&lt;li&gt;Could you help me learn more about hydration? Nick Madison will set up a meeting with customer success group.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;I switched to &lt;a href=&#34;https://fishshell.com/&#34;&gt;fish shell&lt;/a&gt; mainly because:
&lt;ul&gt;
&lt;li&gt;Autocomplete and tab completion works perfectly, out-of-box.&lt;/li&gt;
&lt;li&gt;Syntax highlighting is beautiful&lt;/li&gt;
&lt;li&gt;Great multi-line editing&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;To format with &lt;a href=&#34;https://marketplace.visualstudio.com/items?itemName=charliermarsh.ruff&#34;&gt;VS Code Ruff&lt;/a&gt;, you need to point the &lt;code&gt;ruff.interpreter&lt;/code&gt; setting to a Python interpreter. You can&amp;rsquo;t run the ruff server without Python, even though ruff itself doesn&amp;rsquo;t need Python.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;cd&lt;/code&gt; checks all paths specified in &lt;a href=&#34;https://pubs.opengroup.org/onlinepubs/9699919799/utilities/cd.html&#34;&gt;&lt;code&gt;CDPATH&lt;/code&gt;&lt;/a&gt; for the directory name and changes to the first match. That&amp;rsquo;s pretty convenient!&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://flipperzero.one/&#34;&gt;Flipper Zero&lt;/a&gt; is now on my list of &amp;ldquo;To Buy&amp;rdquo; tools. It has a variety of hardware devices including NFC, RFID, Bluetooth, Infrared, etc. and is great to reverse engineer or hack devices.&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    <item>
      <title>Things I Learned - 12 Jan 2025</title>
      <link>https://www.s-anand.net/blog/things-i-learned-12-jan-2025/</link>
      <pubDate>Sun, 12 Jan 2025 00:00:00 +0000</pubDate>
      <guid>https://www.s-anand.net/blog/things-i-learned-12-jan-2025/</guid>
      <description>&lt;p&gt;This week, I learned:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://getdx.com/research/measuring-developer-productivity-with-the-dx-core-4/&#34;&gt;Measuring developer productivity with the DX Core 4&lt;/a&gt; is a framework for measuring developer productivity. It encapsulates other frameworks like DORA, SPACE, and DevEx.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://minimaxir.com/2025/01/write-better-code/&#34;&gt;Can LLMs write better code if you keep asking them to “write better code?&lt;/a&gt; A delightful exploration of how Claude 3.5 Sonnet keeps optimizing and adding features to improve code. My takeaway: repeatedly applying a prompt gives us interesting new directions to explore.&lt;/li&gt;
&lt;li&gt;Wednesday comes from Wōdnesdæg - named after Odin (or Woden).&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://help.router-for.me/&#34;&gt;CLIProxyAPI&lt;/a&gt; seems a good way to allow any CLI coding agent (Codex, Claude Code, etc.) to work with any provider (e.g. Gemini, OpenRouter, etc.) The documentation needs a few more examples, but it&amp;rsquo;s usable.
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;mise x github:router-for-me/CLIProxyAPI -- cli-proxy-api&lt;/code&gt; starts a local server that proxies requests.&lt;/li&gt;
&lt;li&gt;Create a &lt;a href=&#34;https://help.router-for.me/configuration/basic.html&#34;&gt;&lt;code&gt;config.yaml&lt;/code&gt;&lt;/a&gt;, update the keys, and configure your coding agent, e.g. &lt;a href=&#34;https://help.router-for.me/agent-client/codex.html&#34;&gt;Codex&lt;/a&gt; to use it.&lt;/li&gt;
&lt;li&gt;It&amp;rsquo;s also a good way to see what prompts are being sent by the various harnesses.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://huggingface.co/blog/smolagents&#34;&gt;smolagents&lt;/a&gt; is a new agents library from HuggingFace. It seems simple enough to use.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/dimastatz/whisper-flow/&#34;&gt;whisper-flow&lt;/a&gt; does real-time speech transcription!&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://catalog.ldc.upenn.edu/LDC97S62&#34;&gt;Switchboard-1&lt;/a&gt; is a labelled audio corpus with ~260 hours of speech. It has ~2,400 calls among 500+ speakers in the US.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/get-started/create-local-tunnel/&#34;&gt;Cloudflare tunnel&lt;/a&gt; is like ngrok but more permanent. It&amp;rsquo;s a bit more complex, too. But given CloudFlare&amp;rsquo;s liberal free tier, it&amp;rsquo;s a good, viable option for long-term local hosting.&lt;/li&gt;
&lt;li&gt;John Wheeler: &amp;ldquo;We live on an island surrounded by a sea of ignorance. As our island of knowledge grows, so does the shore of our ignorance.&amp;rdquo; A great way to understand how ignorance actually grows as you learn more.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://pypi.org/project/justhtml&#34;&gt;&lt;code&gt;justhtml&lt;/code&gt;&lt;/a&gt; is a fast enough pure Python fully HTML5 compliant library. For a faster, mostly compliant solution, &lt;a href=&#34;https://pypi.org/project/html5-parser/&#34;&gt;&lt;code&gt;html5-parser&lt;/code&gt;&lt;/a&gt; with &lt;code&gt;lxml&lt;/code&gt; works.&lt;/li&gt;
&lt;li&gt;There is little reason to use Redis. There are several clones you can use. &lt;a href=&#34;https://www.cs.cmu.edu/~pavlo/blog/2025/01/2024-databases-retrospective.html&#34;&gt;Databases in 2024: A Year in Review&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://microsoft.github.io/garnet/&#34;&gt;Microsoft&amp;rsquo;s Garnet&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://docs.keydb.dev/&#34;&gt;KeyDB&lt;/a&gt; (only Linux)&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://valkey.io/&#34;&gt;ValKey&lt;/a&gt; (only source)&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.dragonflydb.io/&#34;&gt;DragonFly&lt;/a&gt; (only Linux)&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://redict.io/&#34;&gt;ReDict&lt;/a&gt; (only Linux)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Every few years, something comes along trying to replace relational databases and SQL, and gets absorbed. &lt;a href=&#34;https://youtu.be/8Woy5I511L8&#34;&gt;YouTube&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Key value stores. People soon realize they need more features, e.g. indices.&lt;/li&gt;
&lt;li&gt;MapReduce systems. Most MapReduce vendors put SQL on top of SQL. Then the Hadoop market crashed. (But HDFS, S3, distributed storage systems are a good idea)&lt;/li&gt;
&lt;li&gt;Document Databases. JSON. SQL absorbed that. SQLite 3.45+ supports even JSONB. DuckDB, of course, has JSON.&lt;/li&gt;
&lt;li&gt;Column Databases. Again, these introduced SQL.&lt;/li&gt;
&lt;li&gt;Graph Databases. SQL:2023 introduced graph queries via SQL/PGQ (Property Graph Queries). DuckPGQ beats Neo4J&lt;/li&gt;
&lt;li&gt;Array Databases. SQL:2023 adds SQL/MDA which allows for matrix operations. But specialized databases might make sense in this category.&lt;/li&gt;
&lt;li&gt;Vector Databases. Every DB is adding support for this.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/TheAgentCompany/TheAgentCompany&#34;&gt;TheAgentCompany&lt;/a&gt; is a benchmark of real-world &lt;a href=&#34;https://github.com/TheAgentCompany/TheAgentCompany/tree/main/workspaces/tasks&#34;&gt;tasks&lt;/a&gt; like:
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/TheAgentCompany/TheAgentCompany/blob/main/workspaces/tasks/admin-arrange-meeting-rooms/task.md&#34;&gt;Arranging a meeting room&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/TheAgentCompany/TheAgentCompany/blob/main/workspaces/tasks/ds-answer-spreadsheet-questions/task.md&#34;&gt;Analyze a spreadsheet&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/TheAgentCompany/TheAgentCompany/blob/main/workspaces/tasks/sde-add-wiki-page/task.md&#34;&gt;Add a Gitlab wiki page&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Salvatore Sanfilippo (antirez - Redis) finds DeepSeek v3 comparable with Claude 3.5 Sonnet. &lt;a href=&#34;https://www.youtube.com/watch?v=_pLlet9Jrzc&#34;&gt;YouTube&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;He also passed a paper and his code to compare them. A useful prompt. &lt;a href=&#34;https://youtube.com/clip/Ugkx3JUGaspeLA2U2U68zSRyB2rPJ-PnCUXR?si=xCoIu5bxaFntSymm&#34;&gt;YouTube&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    <item>
      <title>AI Coding: $12M return for $240K spend?</title>
      <link>https://www.s-anand.net/blog/ai-coding-12m-return-for-240k-spend/</link>
      <pubDate>Sun, 08 Sep 2024 02:05:11 +0000</pubDate>
      <guid>https://www.s-anand.net/blog/ai-coding-12m-return-for-240k-spend/</guid>
      <description>&lt;p&gt;&lt;strong&gt;This is an email I sent to our leadership team a few minutes ago.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;We may be witnessing the third major leap in computing productivity, after high-level languages in the 1960s and spreadsheets in the 1980s&lt;/p&gt;
&lt;p&gt;In the last few weeks, AI coding really took off. &lt;a href=&#34;https://www.cursor.com/&#34;&gt;Cursor&lt;/a&gt;, &lt;a href=&#34;https://sourcegraph.com/cody&#34;&gt;Cody&lt;/a&gt;, &lt;a href=&#34;https://docs.replit.com/replitai/agent&#34;&gt;Replit Agents&lt;/a&gt; are FAR better than GitHub Copilot.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://papers.ssrn.com/sol3/papers.cfm?abstract_id=4945566&#34;&gt;Research&lt;/a&gt; on ~5,000 devs in Fortune 100 shows that even GitHub Copilot makes them ~25% more productive.&lt;/p&gt;
&lt;p&gt;Personally, Cursor helped me:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Write &lt;strong&gt;faster&lt;/strong&gt; code (at least 2X). I&amp;rsquo;ve given away my team (there&amp;rsquo;s not enough work for them).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Write &lt;strong&gt;better&lt;/strong&gt; code. I now document code for others to replicate - because it&amp;rsquo;s so easy.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Write &lt;strong&gt;complex&lt;/strong&gt; code. I&amp;rsquo;ve built stuff I didn&amp;rsquo;t know how to. WhatsApp agents, AI code writers, even LLM Foundry. Each has opened a client&amp;rsquo;s door.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;So, should we leverage AI Coding for our developers?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Maybe not. Consider these risks.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;It costs $10-$20/month/dev. That&amp;rsquo;s $120-$240K/year for ~1,000 devs.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Clients may not be comfortable with us using AI coding. IP. Security.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Higher productivity reduces our T&amp;amp;M billing, hence revenue.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Maybe yes. Consider these benefits.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;We could save 25% per developer. Maybe $4K/month/dev x 25% = $12M/year&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;We could win more complex engagements. (Pitching AI coding as an edge has worked well, too.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;We could reduce time to get someone to a tech-lead level.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;There&amp;rsquo;s probably no one-size-fits-all answer. We might need to pilot while we strategize.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How might this impact our hiring and training?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;1. &lt;strong&gt;Hire for AI coding skills&lt;/strong&gt;. In interviews, I&amp;rsquo;d look for use of AI coding agents. We need a few AI coding leads to share our engineering future.&lt;/p&gt;
&lt;p&gt;2. &lt;strong&gt;Hire for dual skills&lt;/strong&gt;. AI can take care of the code. I&amp;rsquo;d hire people with good client-facing skills.&lt;/p&gt;
&lt;p&gt;3. &lt;strong&gt;Train on AI coding&lt;/strong&gt;. Integrate these into the onboarding process. Train existing devs.&lt;/p&gt;
&lt;p&gt;4. &lt;strong&gt;Train non-developers&lt;/strong&gt;. Analysts, designers, managers can become as good as junior devs.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Why am I mailing you?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In Nov 2022, when ChatGPT was released, I thought LLMs were the biggest knowledge leap since Google.&lt;/p&gt;
&lt;p&gt;In Sep 2024, with Cursor, Cody, and Replit agents, I think AI coding the biggest productivity leap since Excel.&lt;/p&gt;
&lt;p&gt;This is not for immediate action.&lt;/p&gt;
&lt;p&gt;Please think over it. Share it. Discuss it. Pilot it. Let&amp;rsquo;s explore.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Short notes</title>
      <link>https://www.s-anand.net/blog/short-notes/</link>
      <pubDate>Wed, 20 May 2009 05:15:32 +0000</pubDate>
      <guid>https://www.s-anand.net/blog/short-notes/</guid>
      <description>&lt;p&gt;I&amp;rsquo;m quite busy on a project right now, and don&amp;rsquo;t get time to write long articles. So for a while, I&amp;rsquo;m going to stick to short notes on interesting stuff.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Peter Bregman has a very interesting piece on &lt;a href=&#34;http://blogs.harvardbusiness.org/bregman/2009/05/why-you-should-encourage-weakn.html&#34;&gt;Why You Should Encourage Weakness&lt;/a&gt;. It boils down to a choice: &lt;strong&gt;do you focus on on improving strengths or minimising weaknesses?&lt;/strong&gt; Conventional performance evaluations focus on the latter. I very strongly support Bregman’s view on this. &lt;strong&gt;The weakness isn’t why you hired the person!&lt;/strong&gt; Unless it’s killing the organisation, just leave them to focus on their strengths.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://www.google.com/analytics/&#34;&gt;Google Analytics&lt;/a&gt; has a fairly interesting &lt;a href=&#34;http://code.google.com/apis/analytics/docs/&#34;&gt;API&lt;/a&gt; that I hadn’t explored until recently. Picked up [Advanced Web Metrics with Google Analytics](&lt;a href=&#34;http://www.s-anand.net/amazon-browser.html#advanced&#34;&gt;http://www.s-anand.net/amazon-browser.html#advanced&lt;/a&gt; web metrics with google analytics) and learnt that you can track outbound clicks, page load times, Javascript events and error logs, almost anything at all using Google Analytics. You can also mirror the logging on your local server using pageTracker._setLocalRemoteServerMode()&lt;/li&gt;
&lt;li&gt;The whole concept of a Sandbox environment seems to be picking up within Google. There’s a &lt;a href=&#34;https://sandbox.google.com/checkout/&#34;&gt;Checkout sandbox&lt;/a&gt;, an &lt;a href=&#34;http://code.google.com/apis/ajax/playground/&#34;&gt;AJAX API playground&lt;/a&gt;, an &lt;a href=&#34;http://adwordsapi.blogspot.com/2009/05/adwords-api-on-app-engine-python.html&#34;&gt;AdWords sandbox&lt;/a&gt;, an &lt;a href=&#34;http://code.google.com/apis/adsense/developer/adsense_api_sandbox.html&#34;&gt;AdSense API sandbox&lt;/a&gt;, the &lt;a href=&#34;http://mapstraction.appspot.com/&#34;&gt;Mapstraction API sandbox&lt;/a&gt;, even an event called &lt;a href=&#34;http://code.google.com/events/io/sandbox.html&#34;&gt;Developer Sandbox&lt;/a&gt;. (After saying Sandbox 6 times, I feel a bit like Hobbes.)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://picayune.uclick.com/comics/ch/1992/ch920623.gif&#34;&gt;&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Programmers Bill of Rights</title>
      <link>https://www.s-anand.net/blog/programmers-bill-of-rights/</link>
      <pubDate>Sun, 27 Aug 2006 12:00:00 +0000</pubDate>
      <guid>https://www.s-anand.net/blog/programmers-bill-of-rights/</guid>
      <description>&lt;p&gt;Jeff proposes a &lt;a href=&#34;http://www.codinghorror.com/blog/archives/000666.html&#34;&gt;Programmer&amp;rsquo;s Bill of Rights&lt;/a&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Every programmer shall have &lt;a href=&#34;http://www.codinghorror.com/blog/archives/000012.html&#34;&gt;two monitors&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Every programmer shall have a &lt;a href=&#34;http://www.codinghorror.com/blog/archives/000029.html&#34;&gt;fast PC&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Every programmer shall have their choice of &lt;a href=&#34;http://www.codinghorror.com/blog/archives/000286.html&#34;&gt;mouse&lt;/a&gt; and &lt;a href=&#34;http://www.codinghorror.com/blog/archives/000209.html&#34;&gt;keyboard&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Every programmer shall have a &lt;a href=&#34;http://www.codinghorror.com/blog/archives/000240.html&#34;&gt;comfortable chair&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Every programmer shall have a fast internet connection&lt;/li&gt;
&lt;li&gt;Every programmer shall have &lt;a href=&#34;http://www.codinghorror.com/blog/archives/000154.html&#34;&gt;quiet working conditions&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    <item>
      <title>Good programmers</title>
      <link>https://www.s-anand.net/blog/good-programmers/</link>
      <pubDate>Fri, 26 Aug 2005 12:00:00 +0000</pubDate>
      <guid>https://www.s-anand.net/blog/good-programmers/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;http://blog.outer-court.com/archive/2005-08-24-n14.html&#34;&gt;Why good programmers are lazy and dumb&lt;/a&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;comments&#34;&gt;Comments&lt;/h2&gt;
&lt;!-- wp-comments-start --&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Prasenjeet&lt;/strong&gt; &lt;em&gt;26 Aug 2005 3:01 pm&lt;/em&gt;:
Like the chap who created some-language-or-the-other&lt;/li&gt;
&lt;/ul&gt;
&lt;!-- wp-comments-end --&gt;
</description>
    </item>
  </channel>
</rss>
