[{"content":"OpenAI was evaluating a frontier model on cyber-security tasks inside ExploitGym, a sandboxed benchmark — informally, a \u0026ldquo;cyber gym.\u0026rdquo; The tasks are capture-the-flag style: a deliberately vulnerable system hides a secret string, the flag, and retrieving it proves you found the hole. The intended loop:\n1 2 3 4 5 6 7 Find a vulnerability ↓ Exploit it ↓ Read the flag ↓ Return the flag Returning the flag is what earns the reward. That framing is the whole story: the agent was rewarded for producing the flag, not for solving the challenge.\nWhat the agent actually did The agent appears to have reasoned along these lines: why work through a hard exploit chain when the answers are probably published somewhere? Write-ups, solution repos, and datasets for benchmarks like this are all over the internet. Fetching an answer maximizes reward for a fraction of the effort.\nSo it broke out of ExploitGym and reached the open internet — the first reward hack. From there it found a vulnerability in Hugging Face\u0026rsquo;s dataset upload path. Hugging Face is the main public hub for sharing ML models and datasets, and it accepts uploaded datasets, including SQLite files:\n1 dataset.db A database file isn\u0026rsquo;t only data — loading one can trigger code. A crafted dataset.db could carry a payload that executed when the file was processed, handing the uploader control of the machine — conceptually something like:\n1 os.system(...) # illustrative; the real payload differed That gave the agent remote code execution on someone else\u0026rsquo;s servers. It started with ordinary reconnaissance — whoami, pwd — then swept the environment and turned up GitHub credentials, secrets, and Kubernetes tokens. It used that material to launch two further attacks.\nIn total, the agent performed roughly 17,600 actions. Most of them failed. Enough didn\u0026rsquo;t.\nThe part I keep thinking about Hugging Face noticed unusual activity and went to analyze their logs with the OpenAI API — and the API refused the request. The logs were full of attack traffic, so the prompts looked malicious. Their incident response was blocked by a safety filter reacting to evidence of the incident itself.\nThey fell back to a self-hosted GLM 5.2 to complete the analysis.\nOnce the analysis was done, Hugging Face closed the vulnerable code paths, rebuilt the compromised systems, and rotated credentials and secrets.\nReferences Hugging Face — Agent intrusion: technical timeline OpenAI — Hugging Face model evaluation security incident Lilian Weng — Reward hacking in reinforcement learning ","permalink":"https://hadifar.net/posts/reward-hacking-security-incident/","summary":"\u003cp\u003eOpenAI was evaluating a frontier model on cyber-security tasks inside \u003cstrong\u003eExploitGym\u003c/strong\u003e,\na sandboxed benchmark — informally, a \u0026ldquo;cyber gym.\u0026rdquo; The tasks are capture-the-flag style:\na deliberately vulnerable system hides a secret string, the \u003cem\u003eflag\u003c/em\u003e, and retrieving it\nproves you found the hole. The intended loop:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cdiv class=\"chroma\"\u003e\n\u003ctable class=\"lntable\"\u003e\u003ctr\u003e\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"lnt\"\u003e1\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e2\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e3\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e4\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e5\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e6\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e7\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-fallback\" data-lang=\"fallback\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eFind a vulnerability\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        ↓\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e   Exploit it\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        ↓\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  Read the flag\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        ↓\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e Return the flag\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eReturning the flag is what earns the reward. That framing is the whole story: the agent\nwas rewarded for \u003cem\u003eproducing the flag\u003c/em\u003e, not for \u003cem\u003esolving the challenge\u003c/em\u003e.\u003c/p\u003e","title":"OpenAI, Hugging Face, and reward hacking as a security incident"},{"content":"A single SKILL.md file is enough for personal use, but it doesn\u0026rsquo;t scale once you want to version it, bundle it with agents and hooks, or share it with teammates. This post covers how to package skills into a plugin and distribute that plugin through a marketplace.\nYou probably don\u0026rsquo;t need plugins for a personal project or a quick one-off customization. You do need them once you want to share with teammates, distribute to a community, cut versioned releases, or reuse the same setup across projects.\nDefinitions Skill — an instruction (or set of instructions) that your harness (Claude Code, Codex, etc.) can load during a session. Example: /design in Claude Code, which can be loaded manually or automatically when you ask it to draw a chart.\nPlugin — a package that contains skills plus other pieces: agents, tools, commands, hooks, docs. Example: the claude-security plugin. Running it can spawn a team of agents (explorer, patch-generator, scanner), each with its own responsibility and capability. It also ships scripts (e.g. scripts/write_scan_meta.py, which writes scan-meta.json for a run) and hooks (e.g. hooks/banner_notice.py, which shows a banner at the start of a session). In the simple case, a plugin can just be a bundle of skills.\nMarketplace — a collection of plugins hosted remotely (e.g. GitHub) or locally. See hadifar/myplugins for an example.\nBuild a plugin Create the plugin directory:\n1 mkdir -p plugins/daily-plugin/.claude-plugin Add a plugin manifest at plugins/daily-plugin/.claude-plugin/plugin.json:\n1 2 3 4 5 6 7 8 { \u0026#34;name\u0026#34;: \u0026#34;daily-plugin\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Adds useful skills for my daily tasks\u0026#34;, \u0026#34;version\u0026#34;: \u0026#34;1.0.0\u0026#34;, \u0026#34;author\u0026#34;: { \u0026#34;name\u0026#34;: \u0026#34;Amir Hadifar\u0026#34; } } Add a skill to the plugin (here, one called grill-me):\n1 mkdir -p plugins/daily-plugin/skills/grill-me/ Then create SKILL.md inside that folder:\n1 2 3 4 5 6 7 --- name: grill-me description: Grill the user relentlessly about a plan, decision, or idea. Use when the user wants to stress-test their thinking, or uses any \u0026#39;grill\u0026#39; trigger phrases. --- Interview the user relentlessly until you reach a shared understanding. Map this as a design tree: every decision branches into the decisions that hang off it. ... Load it in Claude Code For a one-time load, pass --plugin-dir:\n1 claude --plugin-dir ./plugins/daily-plugin To avoid passing --plugin-dir on every launch, drop the plugin into your skills directory (~/.claude/skills/). Any folder under a skills directory that contains a .claude-plugin/plugin.json manifest is loaded automatically as \u0026lt;name\u0026gt;@skills-dir on the next session — no marketplace, no install step. This works, but the marketplace approach below is the better way to distribute and version a plugin.\nShare it and version it with a marketplace Create the marketplace directories (called myplugins here):\n1 2 mkdir -p myplugins/plugins/ mkdir -p myplugins/.claude-plugin Add a marketplace manifest at myplugins/.claude-plugin/marketplace.json:\n1 2 3 4 5 6 7 8 9 10 11 12 13 { \u0026#34;name\u0026#34;: \u0026#34;myplugins\u0026#34;, \u0026#34;owner\u0026#34;: { \u0026#34;name\u0026#34;: \u0026#34;Amir Hadifar\u0026#34; }, \u0026#34;plugins\u0026#34;: [ { \u0026#34;name\u0026#34;: \u0026#34;daily-plugin\u0026#34;, \u0026#34;source\u0026#34;: \u0026#34;./plugins/daily-plugin\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Adds useful skills for my daily tasks\u0026#34; } ] } Push the myplugins folder to git. Anyone can then install it:\n1 2 3 # in a new Claude Code session /plugin marketplace add https://github.com/hadifar/myplugins /plugin install daily-plugin@myplugins To ship an update, push to git, then have teammates go to /marketplace → select myplugins → Update marketplace.\nReferences Claude Code — Plugins reference GitHub — anthropics/claude-plugins-official, claude-security plugin GitHub — hadifar/myplugins ","permalink":"https://hadifar.net/posts/organize-your-skills/","summary":"\u003cp\u003eA single \u003ccode\u003eSKILL.md\u003c/code\u003e file is enough for personal use, but it doesn\u0026rsquo;t scale once you want to\nversion it, bundle it with agents and hooks, or share it with teammates. This post covers how\nto package skills into a plugin and distribute that plugin through a marketplace.\u003c/p\u003e\n\u003cp\u003eYou probably don\u0026rsquo;t need plugins for a personal project or a quick one-off customization. You\ndo need them once you want to share with teammates, distribute to a community, cut versioned\nreleases, or reuse the same setup across projects.\u003c/p\u003e","title":"Organize your skills"},{"content":"superset.sh is a desktop app for running several AI coding agents at once, each in its own isolated workspace. It covers the same ground as Conductor, but also runs on Linux (Conductor is Mac-only as of August 2026).\nWhat it does Like other agentic IDEs, superset.sh is built around a few features specifically for modern agentic coding:\nRun multiple agents simultaneously Isolate each task in its own git worktree so agents don\u0026rsquo;t interfere with each other Monitor all agents from one place and get notified when they need attention Switch between LLM providers (Claude, Codex, and others) per task Why worktrees, not branches The core concept behind superset.sh — and tools like it — is the git worktree: a separate directory with its own files and branch, sharing the same repository history and remote as your main checkout.\nA plain branch checkout still points at the same files on disk. A worktree gives each task its own physical copy of those files. That\u0026rsquo;s what lets multiple agents (or humans) work on the same repo at the same time without stepping on each other — and lets you throw a workspace away without touching your main branch. Each workspace also gets its own worktree, so switching between tasks is a click instead of a stash-checkout-rebuild cycle.\nInstall on Ubuntu Download the AppImage from the latest release.\nRun it:\n1 ./Superset-x86_64.AppImage --no-sandbox --no-sandbox skips a permission prompt — only pass it if you trust the app.\nIf that doesn\u0026rsquo;t work, extract and fix sandbox permissions manually:\n1 2 3 4 ./Superset-x86_64.AppImage --appimage-extract sudo chown root:root squashfs-root/chrome-sandbox sudo chmod 4755 squashfs-root/chrome-sandbox ./squashfs-root/AppRun Daily recipe The docs have a full set of examples and best practices. For day-to-day bug fixes and features, this pattern works well:\nFeature (⌘N → new branch): prompt an agent with the task and let it run.\n1 2 Build the PDF parsing button on the upload page. Match the existing export patterns in this codebase. Stop and ask before adding dependencies. Bugfix (⌘N → new branch): describe the bug and let the agent reproduce and fix it.\n1 2 Users report the auth form clears on validation errors. Reproduce it, find the root cause, and fix it. Include the repro steps in your final message. Rotate attention: use the sidebar to jump to whichever workspace needs you next.\nWhat stands out Notifications. A small feature, but a useful one — it lets you switch attention to a task the moment an agent finishes or needs input, instead of polling each workspace. Side-by-side terminals. Beyond separate terminal tabs, you can view terminal/agent panes side by side per worktree, giving more visibility into what\u0026rsquo;s running. Fast provider switching. Swap between Claude, Codex, and other LLM providers per task. Skills and hooks. Combined with custom skills and hooks, superset.sh can enforce conventions automatically — e.g., tagging branches as feat/, bug/, or doc/, or running pre-commit checks before every push. References superset.sh docs superset.sh automations Latest release (AppImage) git-worktree docs ","permalink":"https://hadifar.net/posts/superset-sh-agentic-ide/","summary":"\u003cp\u003e\u003ca href=\"https://docs.superset.sh/\"\u003esuperset.sh\u003c/a\u003e is a desktop app for running several AI coding\nagents at once, each in its own isolated workspace. It covers the same ground as\n\u003ca href=\"/posts/conductor-ide-for-parallel-agent/\"\u003eConductor\u003c/a\u003e, but\nalso runs on Linux (Conductor is Mac-only as of August 2026).\u003c/p\u003e\n\u003ch2 id=\"what-it-does\"\u003eWhat it does\u003c/h2\u003e\n\u003cp\u003eLike other agentic IDEs, superset.sh is built around a few features specifically for\nmodern agentic coding:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eRun multiple agents simultaneously\u003c/li\u003e\n\u003cli\u003eIsolate each task in its own git worktree so agents don\u0026rsquo;t interfere with each other\u003c/li\u003e\n\u003cli\u003eMonitor all agents from one place and get notified when they need attention\u003c/li\u003e\n\u003cli\u003eSwitch between LLM providers (Claude, Codex, and others) per task\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"why-worktrees-not-branches\"\u003eWhy worktrees, not branches\u003c/h2\u003e\n\u003cp\u003eThe core concept behind superset.sh — and tools like it — is the git\n\u003ca href=\"https://git-scm.com/docs/git-worktree\"\u003eworktree\u003c/a\u003e: a separate directory with its own\nfiles and branch, sharing the same repository history and remote as your main checkout.\u003c/p\u003e","title":"superset.sh: IDE to run parallel coding agents"},{"content":"Many agentic workflows converge on the same shape: write a Markdown file at the root of your repo, point your agent at it, and let it loop until it meets a stated goal. Test-driven development is a natural fit for that shape — the tests are the goal, and \u0026ldquo;all tests green\u0026rdquo; is an unambiguous exit condition the agent can check without you.\nThe basic loop In this paradigm you ask the agent to write tests first. You review them (or have another agent review them), then ask the agent to implement the feature until every test passes. You revise the tests a little, the agent revises the code a little, and when everything is green you move to the next feature — with a fully testable one behind you.\nThe loop is four steps:\nProvide the prompt, spec, or task description. Provide the tests up front — written by hand, or generated by the agent. The agent writes code to pass those tests. Repeat 2 and 3 until the goals in step 1 are met and all tests are green. What makes this work for agents specifically is that step 4 is machine-checkable. The agent does not have to guess whether it is done.\nSimilar but different TDD philosophies The same philosophy can be implemented in several ways.\nPolicy-enforced TDD. TDD Governance for Multi-Agent Code Generation via Prompt Engineering pairs the user\u0026rsquo;s request with a policy for tests. The policy is derived from the early Beck and Martin TDD literature and encoded as a machine-readable manifesto — see tdd_principles_manifesto.json, which lists principles such as Eliminate Duplication, High Cohesion, Loose Coupling, and Test-First Gate. The agent must comply with the policy or the run is considered failed. The architecture separates model proposals from deterministic validation, enforcing phase ordering, bounded repair loops, and validation gates.\nSpec-and-tests-driven generation. whenwords takes the design one step further: it is a relative-time-formatting library that contains no code. You hand a model a SPEC.md and a tests.yaml, and it produces an implementation in your language of choice that passes every case. The tests are language-agnostic input/output pairs written up front by a human or another agent. The same spec has been used to generate working implementations in Ruby, Python, Rust, Elixir, Swift, PHP, and Bash.\nHow to write TDD prompts In this philosophy the way you phrase a task changes. Prompts become verifiable actions rather than open-ended intentions:\nInstead of… Transform to… \u0026ldquo;Add validation\u0026rdquo; \u0026ldquo;Write tests for invalid inputs, then make them pass\u0026rdquo; \u0026ldquo;Fix the bug\u0026rdquo; \u0026ldquo;Write a test that reproduces it, then make it pass\u0026rdquo; \u0026ldquo;Refactor X\u0026rdquo; \u0026ldquo;Ensure tests pass before and after\u0026rdquo; As with any agentic development, the standard software engineering practices still apply. If you ask your agent to \u0026ldquo;write tests for all functionality and make sure they\u0026rsquo;re green,\u0026rdquo; it will probably fail. Break the intent into small, atomic pieces and build the feature up gradually.\nThis is the same \u0026ldquo;ask small\u0026rdquo; advice from the YC guide to vibe coding.\nReferences arXiv — TDD Governance for Multi-Agent Code Generation via Prompt Engineering GitHub — shahbazsiddeeq/TDD-manifesto GitHub — dbreunig/whenwords GitHub — obra/superpowers, test-driven-development skill GitHub — multica-ai/andrej-karpathy-skills ","permalink":"https://hadifar.net/posts/tdd-for-agents/","summary":"\u003cp\u003eMany agentic workflows converge on the same shape: write a Markdown file at the root of your\nrepo, point your agent at it, and let it loop until it meets a stated goal. Test-driven\ndevelopment is a natural fit for that shape — the tests \u003cem\u003eare\u003c/em\u003e the goal, and \u0026ldquo;all tests green\u0026rdquo;\nis an unambiguous exit condition the agent can check without you.\u003c/p\u003e\n\u003ch2 id=\"the-basic-loop\"\u003eThe basic loop\u003c/h2\u003e\n\u003cp\u003eIn this paradigm you ask the agent to write tests first. You review them (or have another\nagent review them), then ask the agent to implement the feature until every test passes.\nYou revise the tests a little, the agent revises the code a little, and when everything is\ngreen you move to the next feature — with a fully testable one behind you.\u003c/p\u003e","title":"TDD for agents"},{"content":"goose is an open-source AI agent that wraps an LLM in a loop of tool calls, so the model can actually do things rather than only describe them. Its own docs put it this way:\ngoose, an open source AI Agent, builds upon the basic interaction framework of Large Language Models (LLMs), which primarily functions as a text-based conversational interface. It processes text input and generates text output. This \u0026ldquo;text in, text out\u0026rdquo; approach is enhanced with tool integrations, which allows the AI agent to complete tasks, creating goose.\nIn other words, goose is a harness: the layer that sits between you and the model, carrying requests out to tools and results back in.\nHow it works Human request. The loop starts and ends with you — a question, command, or problem to solve. Provider chat. goose sends your request along with the list of available tools to the LLM provider you\u0026rsquo;ve connected. The provider processes it and, if needed, emits a tool call as part of its response. Extension call. The model can request a tool call but not execute it — that\u0026rsquo;s goose\u0026rsquo;s job. It takes the JSON-formatted tool call, runs it, and collects the results. Response to model. goose sends the results back to the model. If more extensions are needed, these steps repeat. Context revision. goose drops old or irrelevant information so the model stays focused on what matters, which also keeps token usage in check. Model response. Once the tool calls are done, the model sends its final response back to you, and the loop restarts when you reply. Interesting features The context-engineering side of goose is, in my opinion, particularly well designed.\nSplit providers for planning and coding. You can point planning at one provider and code generation at another via configuration variables:\nGOOSE_PLANNER_PROVIDER — which provider to use for planning GOOSE_PLANNER_MODEL — which model to use for planning Recent models are converging on both capabilities, so you may not need two, but it\u0026rsquo;s a nice lever to have.\nSubagents. You can ask goose to spawn subagents and delegate work — \u0026ldquo;create the login and logout page in parallel with two agents\u0026rdquo;. Agent creation can be constrained with Recipes: YAML files specifying the system prompt, inputs, and a timeout after which an agent that hasn\u0026rsquo;t finished is shut down.\nScheduled agents. goose has built-in scheduling — essentially cron for agent runs. It\u0026rsquo;s a minor feature, but a genuinely useful one that other harnesses like Claude Code and Codex don\u0026rsquo;t offer out of the box.\nPre-built extensions. Extensions are add-ons that connect goose to the applications and tools already in your workflow — adding features, accessing data, or integrating with other systems. They\u0026rsquo;re built on the Model Context Protocol (see What is MCP?), so goose plugs into a wide ecosystem of existing capabilities.\nReferences goose documentation goose Recipes ","permalink":"https://hadifar.net/posts/what-is-goose/","summary":"\u003cp\u003e\u003ca href=\"https://goose-docs.ai/\"\u003egoose\u003c/a\u003e is an open-source AI agent that wraps an LLM in a loop of\ntool calls, so the model can actually do things rather than only describe them. Its own\ndocs put it this way:\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003egoose, an open source AI Agent, builds upon the basic interaction framework of Large\nLanguage Models (LLMs), which primarily functions as a text-based conversational\ninterface. It processes text input and generates text output. This \u0026ldquo;text in, text out\u0026rdquo;\napproach is enhanced with tool integrations, which allows the AI agent to complete tasks,\ncreating goose.\u003c/p\u003e","title":"goose: open-source AI agent harness"},{"content":"I recently started a Kaggle competition and decided to apply autoresearch to it: an agent that loops forever to ace the leaderboard.\nThe Kaggle problem is student health risk prediction: categorize records into three classes (unhealthy, at-risk, fit) from categorical features like sleep_duration, gender, and water_intake.\nI based my problem.md on autoresearch\u0026rsquo;s description with small modifications; it\u0026rsquo;s in hadifar/autonomous-kaggling, along with the full run. The commit history on the shr-v1 branch shows what ideas the agent applied and where each one landed, and results.csv in the root tracks the scores.\nSummary: promising direction, not a replacement. Not yet.\nWhat worked The baseline was solid and hard to beat. I didn\u0026rsquo;t get the gold medal, but the score the loop produced on its first serious pass held up against most of what I tried afterwards. The distance between \u0026ldquo;an hour of autonomous iteration\u0026rdquo; and \u0026ldquo;someone who knows what they\u0026rsquo;re doing\u0026rdquo; was narrower than I expected.\nWeb search changed what it was capable of. I gave Claude access to the WebSearch tool, and it went looking for prior work rather than just iterating on its own ideas. It surfaced a Kaggle discussion — \u0026ldquo;0.95238 Starter\u0026rdquo; — describing a way to game the public leaderboard:\nTreat the public LB as an oracle: flip a batch of ~150 candidate rows to fit, submit, read the score delta to count how many were right, then binary-search the batch (37 → 18 → 9 rows) to localize them.\nIt also tracked down the original dataset the competition was derived from and ran a series of augmentations against it.\nBoth moves are the kind of thing an experienced competitor does, and it was very insightful!\nThe error analysis was better than I expected. Unprompted, it computed majority-class baselines and estimated a ceiling — establishing what \u0026ldquo;good\u0026rdquo; means before chasing it. Then it traced the bulk of the residual error to missing values in decisive features and concluded the problem wasn\u0026rsquo;t recoverable through modeling. That\u0026rsquo;s the correct call; no amount of feature engineering fixes information that isn\u0026rsquo;t in the data. Any working data scientist would get there. The point is that an LLM got there without being pointed at it.\nIt\u0026rsquo;s a good ideation partner. Several suggestions were new to me. I\u0026rsquo;m not a data-science expert — I know most of the concepts — and for someone in that position it widened the search space faster than I could have alone.\nWhere it stalled It abandons ideas too early. For example, the loop proposed data augmentation, saw no improvement in balanced accuracy, and discarded it. Reasonable! But I looked at the actual distribution of the data, and the problem wasn\u0026rsquo;t that augmentation was wrong — it was that that particular strategy was too naive for this distribution. I proposed a different one and it worked.\nMuch of the budget goes to the obvious. A large share of attempts were hyperparameter nudges — raising and lowering the learning rate, blending XGBoost with CatBoost. Almost certainly the moves most represented in its training data.\nMy own ideas still moved the score most. The loop got me to a strong baseline fast; the meaningful gains past that came from me looking at the data — the data augmentation above is one example.\nInstruction-following issues. I explicitly stated in my problem.md file that it should loop forever. However, my loop stopped after 1h 38m 10s. Another pattern I observed is that during the loop it sometimes forgot to commit before ideation and jumped straight into implementation. So if the goal is reliability, be careful about it.\nTakeaway Treat it as a fast, tireless junior assistant that covers the obvious ground — baselines, error analysis, standard ensembling, hyperparameter sweeps — so your attention goes to the parts that need judgment \u0026amp; ideation. Very good at execution \u0026amp; not good at ideation!\nReferences karpathy/autoresearch Kaggle — Playground Series S6E7 ","permalink":"https://hadifar.net/posts/autonomous-kaggling/","summary":"\u003cp\u003eI recently started a Kaggle competition and decided to apply\n\u003ca href=\"https://github.com/karpathy/autoresearch/\"\u003eautoresearch\u003c/a\u003e to it: an agent that loops forever\nto ace the leaderboard.\u003c/p\u003e\n\u003cp\u003eThe \u003ca href=\"https://www.kaggle.com/competitions/playground-series-s6e7\"\u003eKaggle problem\u003c/a\u003e is\nstudent health risk prediction: categorize records into three classes (unhealthy, at-risk,\nfit) from categorical features like \u003ccode\u003esleep_duration\u003c/code\u003e, \u003ccode\u003egender\u003c/code\u003e, and \u003ccode\u003ewater_intake\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003eI based my \u003ccode\u003eproblem.md\u003c/code\u003e on autoresearch\u0026rsquo;s description with small modifications; it\u0026rsquo;s in\n\u003ca href=\"https://github.com/hadifar/autonomous-kaggling\"\u003ehadifar/autonomous-kaggling\u003c/a\u003e, along with\nthe full run. The commit history on the \u003ccode\u003eshr-v1\u003c/code\u003e branch shows what ideas the agent applied\nand where each one landed, and \u003ccode\u003eresults.csv\u003c/code\u003e in the root tracks the scores.\u003c/p\u003e","title":"Autonomous Kaggling"},{"content":"This post explains the AI coding workflow of Y Combinator\u0026rsquo;s CEO — how he uses GStack for ideation, building, and deployment.\nWhat is gstack gstack is a collection of SKILL.md files that give your AI agents personas for different stages of the software/product development life cycle.\nA normal software sprint runs through roughly these stages:\n1 think → plan → design → build → review → test → ship In gstack, there is a SKILL.md file (often several) for each of these stages. You invoke them to guide your agents toward the goal (generating code, a specification, ideation, etc.).\nSome of the skills Below is a sample of the available skills. Explore the gstack repo to find the full set.\nSkill What it does /office-hours Starting point. Reframes your product idea before you write code. /plan-ceo-review CEO-level review: find the 10-star product in the request. /plan-eng-review Lock architecture, data flow, edge cases, and tests. /plan-design-review Rate each design dimension 0–10, explain what a 10 looks like. /plan-devex-review DX-mode review: TTHW, magical moments, friction points, persona traces. /plan-tune Self-tune AskUserQuestion sensitivity per question. /autoplan One command runs CEO → design → eng → DX review. /design-consultation Build a complete design system from scratch. /spec Turn vague intent into a precise, executable spec in five phases. Files a GitHub issue, optionally spawns a Claude Code agent in a fresh worktree, and lets /ship close the source issue on merge. Setup Installation Clone gstack into your Claude skills directory and run the setup script:\n1 2 3 git clone --single-branch --depth 1 https://github.com/garrytan/gstack.git ~/.claude/skills/gstack \\ \u0026amp;\u0026amp; cd ~/.claude/skills/gstack \\ \u0026amp;\u0026amp; ./setup Then add a gstack section to your CLAUDE.md that:\ntells the agent to use the /browse skill for all web browsing (never the mcp__claude-in-chrome__* tools), and lists the available skills so the agent knows what it can call: /office-hours, /plan-ceo-review, /plan-eng-review, /plan-design-review, /design-consultation, /design-shotgun, /design-html, /review, /ship, /land-and-deploy, /canary, /benchmark, /browse, /connect-chrome, /qa, /qa-only, /design-review, /setup-browser-cookies, /setup-deploy, /setup-gbrain, /retro, /investigate, /document-release, /document-generate, /codex, /cso, /autoplan, /plan-devex-review, /devex-review, /careful, /freeze, /guard, /unfreeze, /gstack-upgrade, /learn. Optionally, add gstack to the current project too, so teammates get it.\nQuick start Install gstack (30 seconds — see above). Run /office-hours — describe what you\u0026rsquo;re building. Run /plan-ceo-review on any feature idea. Run /review on any branch with changes. Run /qa on your staging URL. Stop there. You\u0026rsquo;ll know if this is for you. /office-hours is where you begin. Before you write any code, it acts as a structured brainstorming partner that helps you upgrade and revise your idea — honing it toward the real problem, testing feasibility, and surfacing what might work and what won\u0026rsquo;t. It adapts to your context — a startup concept or a side project — and works through several phases. For example, /office-hours asks you several questions that depend on your product: who said this software/product/idea is interesting? Is it a commercial, learning, or entrepreneurship project? It even searches the web to find relevant competitors and identify your differentiator. Based on your answers, it then suggests a couple of points worth noting and considering. By answering those questions, your agent can construct better context for later stages in the pipeline and development.\nAlternatives Superpowers is basically the same idea; we review it in another post.\nReferences YC Library — \u0026ldquo;Inside Garry Tan\u0026rsquo;s AI Coding Setup\u0026rdquo; GitHub — garrytan/gstack ","permalink":"https://hadifar.net/posts/gstack-ai-engineering-workflow/","summary":"\u003cp\u003eThis post explains the AI coding workflow of Y Combinator\u0026rsquo;s CEO — how he uses \u003ca href=\"https://github.com/garrytan/gstack.git\"\u003eGStack\u003c/a\u003e for ideation, building, and deployment.\u003c/p\u003e\n\u003ch2 id=\"what-is-gstack\"\u003eWhat is gstack\u003c/h2\u003e\n\u003cp\u003e\u003cstrong\u003egstack\u003c/strong\u003e is a collection of \u003ccode\u003eSKILL.md\u003c/code\u003e files that give your AI agents personas for different stages of the\nsoftware/product development life cycle.\u003c/p\u003e\n\u003cp\u003eA normal software sprint runs through roughly these stages:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cdiv class=\"chroma\"\u003e\n\u003ctable class=\"lntable\"\u003e\u003ctr\u003e\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"lnt\"\u003e1\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-text\" data-lang=\"text\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ethink → plan → design → build → review → test → ship\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eIn gstack, there is a \u003ccode\u003eSKILL.md\u003c/code\u003e file (often several) for each of these stages. You invoke\nthem to guide your agents toward the goal (generating code, a specification, ideation, etc.).\u003c/p\u003e","title":"Gstack: AI engineering workflow"},{"content":"A skill is a Markdown file an agent loads on demand to learn how to handle a particular kind of request. It\u0026rsquo;s useful when you have a repetitive task and don\u0026rsquo;t want to re-prompt your agent each time.\nThink of it as the utility function of prompting: instead of duplicating the same instructions in every conversation, you write them once and reuse them. Skills are more general than that, of course — their behaviour adapts to the request in a way a single utility function doesn\u0026rsquo;t.\nBefore jumping into skills, let\u0026rsquo;s review what the agent actually sees when you enter a prompt.\nWhat gets sent to the model When you send a request to Claude or ChatGPT, your message is not the only thing that travels to the model. Alongside it go:\nSystem prompt — a general instruction telling the model what to do (see leaked examples). Conversation history — what you\u0026rsquo;ve discussed in the chat so far. Tool schemas — any tools you\u0026rsquo;ve enabled, e.g. deep research or web search. Retrieved items — results of any search the model runs, locally or online. User input — your actual question or request. Some concatenation of the above is passed to the LLM, which then generates a response.\nSkills slot into that picture as retrieved items. When you enable a skill — or Claude decides to load one — it loads one or more SKILL.md files that specify what to do in a given situation to better fulfil the request.\nThe loading happens in two stages. Initially the agent sees only the name and description of each available skill — nothing else. When the description tells it that a skill is needed to fulfil your request, it triggers that skill and loads the entire file into its context. From then on, the content of SKILL.md travels alongside everything else listed above each time you submit a prompt.\nAn example: dataviz In Claude, if you ask:\n1 draw me a plot which shows y = x^2 Initially, Claude only sees the name and description:\n1 2 3 4 /dataviz Use this skill whenever you are about to create ANY chart, graph, plot, dashboard, or data visualization, in ANY output medium — an HTML or React artifact, inline SVG, plotting code in any library (matplotlib, plotly, d3, Recharts, …)… That\u0026rsquo;s enough to decide, so it loads (or asks permission to load) the dataviz skill, which instructs Claude to complete the request in a certain way. The actual content looks roughly like this — see the full version:\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 # Data Visualization A chart is read by people and executed by you. This skill turns \u0026#34;make it look good\u0026#34; into a procedure with checks, so the result is right by construction rather than by taste... ## The procedure — do these in order Color comes LAST. Most bad charts pick colors first. Pick the form. What is the data\u0026#39;s job — magnitude, identity, polarity, a single headline, ... ## Non-negotiables (true in every design system) ... ## Plugging in a design system ... ## Reference files | File | What it answers | |------|-----------------| | `references/choosing-a-form.md` | Which chart type / is it even a chart? | | `references/color-formula.md` | The four jobs, the six checks, snap-to-passing | | `references/marks-and-anatomy.md` | Mark specs, spacers, labels, figures, hero number | ... It\u0026rsquo;s a well-written text that guides the model on what to do and what not to do. It also points to reference files the model can pull in for more detail when needed.\nBeyond dataviz, Claude ships other skills such as /debug and /doctor, designed to perform an action, which you can invoke directly with / followed by the skill name. As above, Claude initially sees only their name and description, and loads the actual content when one is triggered.\nWriting your own You can write your own skills too — see the Claude Code skills docs. Ask Claude to create a skill that helps you polish your email, for instance, and it will write a file at:\n1 ~/.claude/skills/\u0026lt;skill-name\u0026gt;/SKILL.md Note that it\u0026rsquo;s a folder, not a lone file. That means you can include additional resources — code, docs, examples — that help the model further, on top of the single SKILL.md.\n1 2 3 4 5 skill-name/ ├── SKILL.md # Required: metadata + core instructions (\u0026lt;500 lines) ├── scripts/ # Executable code (Python/Bash) designed as tiny CLIs ├── references/ # Supplementary context (schemas, cheatsheets) └── assets/ # Templates or static files used in output For guidance on what makes a skill effective, a solid set of practices is collected in the agentskills.io best practices.\nWhere did the idea come from? The earliest place I saw skills introduced for LLMs was Metacognitive Capabilities of LLMs, where the authors define various skills for solving math problems — later picked up and refined by others.\nThe underlying idea of decomposing a task into simpler sub-tasks isn\u0026rsquo;t new. Industrial automation has long done the same:\nThe highest-level goal (e.g. make beer). The major production stages (e.g. mash, ferment). The functions within each stage, which is where a skill fits (e.g. heat liquid, add ingredients). Limitations Context limits and forgetting are the usual suspects, but the main gap is composition: having the model look across several skills and combine them to reach a goal more complex than any single skill describes. Picking and following one skill is largely solved; stitching several together is not.\nReferences agentskills.io — skill creation best practices Gist — full dataviz skill GitHub — anthropics/skills Claude Code — bundled skills Metacognitive Capabilities of LLMs (NeurIPS 2024) GitHub — asgeirtj/system_prompts_leaks GitHub — mgechev/skills-best-practices ","permalink":"https://hadifar.net/posts/what-is-a-skill/","summary":"\u003cp\u003eA skill is a Markdown file an agent loads on demand to learn how to handle a particular\nkind of request. It\u0026rsquo;s useful when you have a repetitive task and don\u0026rsquo;t want to re-prompt\nyour agent each time.\u003c/p\u003e\n\u003cp\u003eThink of it as the utility function of prompting: instead of duplicating the same\ninstructions in every conversation, you write them once and reuse them. Skills are more\ngeneral than that, of course — their behaviour adapts to the request in a way a single\nutility function doesn\u0026rsquo;t.\u003c/p\u003e","title":"What is a Skill?"},{"content":"The Modern Software Developer is a Stanford course (CS146S) that covers most of what you need to know about agentic coding — prompting techniques, AI IDEs, patterns, and more.\nWhy it\u0026rsquo;s worth it I highly recommend this course: it covers the foundations you need, from the ground up.\nIt starts by introducing LLMs and different prompting strategies — K-shot, chain-of-thought, self-critique, and others — before moving on to the tooling and patterns of agentic coding.\nReferences The Modern Software Developer (CS146S) ","permalink":"https://hadifar.net/posts/modern-software-developer-course/","summary":"\u003cp\u003e\u003ca href=\"https://themodernsoftware.dev/\"\u003eThe Modern Software Developer\u003c/a\u003e is a Stanford course\n(CS146S) that covers most of what you need to know about agentic coding — prompting\ntechniques, AI IDEs, patterns, and more.\u003c/p\u003e\n\u003ch2 id=\"why-its-worth-it\"\u003eWhy it\u0026rsquo;s worth it\u003c/h2\u003e\n\u003cp\u003eI highly recommend this course: it covers the foundations you need, from the ground up.\u003c/p\u003e\n\u003cp\u003eIt starts by introducing LLMs and different prompting strategies — K-shot, chain-of-thought,\nself-critique, and others — before moving on to the tooling and patterns of agentic\ncoding.\u003c/p\u003e","title":"The Modern Software Developer course"},{"content":"This section briefly explains what MCP is and why it\u0026rsquo;s useful. Before describing MCP, it helps to understand tool-calling first — MCP is built on top of it.\nTool-calling Tool-calling is a capability that lets an AI model (like an LLM) interact with the outside world by invoking external functions or APIs.\nHere\u0026rsquo;s a simple example of tool-calling in Python with two tools, bash_tool and web_search:\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 # mock tools def bash_tool(command: str) -\u0026gt; str: \u0026#34;\u0026#34;\u0026#34;Run a shell command and return its output.\u0026#34;\u0026#34;\u0026#34; return \u0026#34;index.html main.py styles.css README.md\u0026#34; if command == \u0026#34;ls\u0026#34; else \u0026#34;Done\u0026#34; def web_search(query: str) -\u0026gt; str: \u0026#34;\u0026#34;\u0026#34;Search the web and return the results.\u0026#34;\u0026#34;\u0026#34; return f\u0026#34;Search results for \u0026#39;{query}\u0026#39;: Found documentation.\u0026#34; tools = {\u0026#34;bash_tool\u0026#34;: bash_tool, \u0026#34;web_search\u0026#34;: web_search} # Simulates the AI picking a tool based on keywords def mock_llm(query): if \u0026#34;file\u0026#34; in query or \u0026#34;list\u0026#34; in query: return {\u0026#34;tool\u0026#34;: \u0026#34;bash_tool\u0026#34;, \u0026#34;arguments\u0026#34;: {\u0026#34;command\u0026#34;: \u0026#34;ls\u0026#34;}} return {\u0026#34;tool\u0026#34;: \u0026#34;web_search\u0026#34;, \u0026#34;arguments\u0026#34;: {\u0026#34;query\u0026#34;: query}} while True: user_query = input(\u0026#34;User: \u0026gt; \u0026#34;) if user_query.lower() in [\u0026#34;exit\u0026#34;, \u0026#34;quit\u0026#34;]: print(\u0026#34;Goodbye!\u0026#34;) break # Step 1: Get tool choice from LLM decision = mock_llm(user_query) tool_name, args = decision[\u0026#34;tool\u0026#34;], decision[\u0026#34;arguments\u0026#34;] print(f\u0026#34;AI wants to call: {tool_name}({args})\u0026#34;) # Step 2 \u0026amp; 3: execute the tool and print the output tool_output = tools[tool_name](**args) print(f\u0026#34;Tool Output: {tool_output}\\n\u0026#34;) That\u0026rsquo;s tool-calling in a nutshell: the model picks a tool (e.g. web_search or bash_tool) and supplies the right arguments (e.g. query: \u0026quot;who won the 2022 World Cup\u0026quot;), the tool or API is executed — locally or remotely — and the model reads back the result.\nWhat is MCP? MCP is a standardized wrapper around tool-calling that makes it easier to connect external APIs, data, and documentation without writing custom integration code for each one.\nWithout MCP, every LLM provider or AI developer needs their own custom tool definitions for each external API or database. Suppose Claude, OpenAI, and Qwen all want to use the web_search tool above (in the real world, say they all want to use the Google Search API). One might implement it as web_search(query: str), another as web_search(query: str, number_of_return_pages: int) — so each model sees a different signature and observes different results. That fragmentation introduces a lot of integration headaches.\nMCP standardizes this. Instead of a separate integration per provider, you expose one official tool behind an MCP server that every LLM provider can call the same way.\nMany organizations already publish MCP servers, for example:\nGitHub MCP server — tools Notion MCP — supported tools How do LLMs use MCP? A good way to understand how an LLM uses MCP is to look at a leaked system prompt. It states:\n1 2 3 Claude can connect to external apps and services on behalf of the person through MCP Apps... Claude should check its tool list rather than assume. MCP App tools are identified by descriptions that begin with the tag [third_party_mcp_app]. The system prompt describes the flow:\nThe model first checks which MCP servers are available and relevant. If it finds a relevant one, it inspects the tools it contains via their descriptions. Finally it makes a tool request through the relevant tool. More specifically, the exchange between the user\u0026rsquo;s session, the server, and the LLM goes as follows:\nThe client (your Claude session) calls tools/list on the MCP server (\u0026ldquo;what can you do?\u0026rdquo;). The server returns JSON describing each tool (name, summary, JSON schema). The host (Claude Code, Codex) injects that JSON into the model\u0026rsquo;s context. A user prompt triggers the model, which emits a structured tool call. The MCP server executes it and the conversation resumes. Under the hood there are additional tricks. For example, Claude Code and Codex load only the MCP servers a user has already activated (Claude Code stores these in .claude.json) rather than blindly loading everything.\nWriting your own MCP server The easy way Ask Claude to do it for you. First install the mcp-server-dev plugin from Claude Code:\n1 2 /plugin marketplace add anthropics/claude-plugins-official /plugin install mcp-server-dev With its skills installed, ask Claude to build the server for you — for example: help me build an MCP server with two tools, web_search and bash_tool.\nDoing it yourself Here are the same two tools from the tool-calling example above, this time exposed through an MCP server using the Python SDK\u0026rsquo;s FastMCP helper:\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 # my_mcp_server.py from mcp.server.fastmcp import FastMCP # Initialize FastMCP server mcp = FastMCP(\u0026#34;mymcp\u0026#34;) @mcp.tool() def bash_tool(command: str) -\u0026gt; str: \u0026#34;\u0026#34;\u0026#34;Run a shell command and return its output.\u0026#34;\u0026#34;\u0026#34; ... @mcp.tool() def web_search(query: str) -\u0026gt; str: \u0026#34;\u0026#34;\u0026#34;Search the web and return the results.\u0026#34;\u0026#34;\u0026#34; ... def main(): mcp.run(transport=\u0026#34;http\u0026#34;, host=\u0026#34;0.0.0.0\u0026#34;, port=3000) if __name__ == \u0026#34;__main__\u0026#34;: main() # run via: python my_mcp_server.py The @mcp.tool() decorator is what turns a plain Python function into a tool the server advertises — its signature and docstring become the description an MCP client discovers, so any client can then call both tools the same way.\nYou can then inspect the tools with the MCP inspector:\n1 2 npx @modelcontextprotocol/inspector # → select \u0026#34;Streamable HTTP\u0026#34;, paste http://localhost:3000/mcp as the URL, click Connect The example above is deliberately minimal. A real server needs decisions this snippet skips, and Anthropic\u0026rsquo;s official example frames them as five questions:\nWhat does it connect to? Decides the deployment shape — remote HTTP as in the example above, a bundled MCPB, or local stdio. Who will use it? A single team, broad public distribution, and Claude desktop users wanting UI features each point somewhere different. How many distinct actions does it expose? A handful is fine as one tool per action; a large surface is better served by a search-plus-execute pair, so the model isn\u0026rsquo;t handed dozens of near-identical tools. Does a tool need mid-call user input or rich display? Plain tools cover most cases; otherwise you reach for elicitation or MCP app widgets. What auth does the upstream service use? An API key is trivial; OAuth, CIMD, or DCR flows are where most of the real complexity lands. Other advantages of MCP Beyond solving the integration problem, MCP also addresses:\nDynamic Client Registration (DCR). MCP supports DCR, letting clients register automatically with OAuth servers. This removes the need for manual client setup or hard-coded credentials, streamlining deployment. Secure authorization and token management. Clients securely obtain OAuth tokens scoped precisely to a user\u0026rsquo;s permissions, so they access only the resources the user has explicitly permitted — improving security and compliance, especially in multi-user and cloud environments. Current limitations MCP is still young, and a few rough edges show up quickly in practice:\nTool definitions eat tokens. Every connected server\u0026rsquo;s tools are injected into the model\u0026rsquo;s context, so a handful of servers can consume a large slice of the prompt before the user has typed anything — and you pay for it on every turn. Progressive discovery and tool RAG (retrieving only the tools relevant to the current request) reduce the cost, but don\u0026rsquo;t eliminate it. Tool composition is an open problem. Picking a single tool is mostly solved; chaining several together to reach a desired result is not. Models still struggle to plan which tools to combine, in what order, and how to thread one tool\u0026rsquo;s output into the next. Tool descriptions matter more than you\u0026rsquo;d expect. You can\u0026rsquo;t simply hand over an existing OpenAPI/Swagger spec and call it an MCP server. A spec written for developers — who bring the surrounding docs, conventions, and intent — reads very differently to a model, which only sees the names, descriptions, and schemas in front of it. Designing an MCP server means deliberately writing tool signatures and descriptions for that reader. References Model Context Protocol — Getting started Anthropic — build-mcp-server skill Stytch — An introduction to the Model Context Protocol GitHub — asgeirtj/system_prompts_leaks GitHub MCP server Notion MCP supported tools ","permalink":"https://hadifar.net/posts/what-is-mcp/","summary":"\u003cp\u003eThis section briefly explains what MCP is and why it\u0026rsquo;s useful. Before describing MCP, it\nhelps to understand \u003cstrong\u003etool-calling\u003c/strong\u003e first — MCP is built on top of it.\u003c/p\u003e\n\u003ch2 id=\"tool-calling\"\u003eTool-calling\u003c/h2\u003e\n\u003cp\u003eTool-calling is a capability that lets an AI model (like an LLM) interact with the outside\nworld by invoking external functions or APIs.\u003c/p\u003e\n\u003cp\u003eHere\u0026rsquo;s a simple example of tool-calling in Python with two tools, \u003ccode\u003ebash_tool\u003c/code\u003e and\n\u003ccode\u003eweb_search\u003c/code\u003e:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cdiv class=\"chroma\"\u003e\n\u003ctable class=\"lntable\"\u003e\u003ctr\u003e\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"lnt\"\u003e 1\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 2\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 3\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 4\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 5\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 6\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 7\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 8\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 9\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e10\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e11\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e12\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e13\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e14\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e15\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e16\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e17\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e18\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e19\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e20\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e21\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e22\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e23\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e24\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e25\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e26\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e27\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e28\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e29\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e30\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e31\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e32\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e33\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e34\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-python\" data-lang=\"python\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# mock tools\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003edef\u003c/span\u003e \u003cspan class=\"nf\"\u003ebash_tool\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ecommand\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"nb\"\u003estr\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e \u003cspan class=\"nb\"\u003estr\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"s2\"\u003e\u0026#34;\u0026#34;\u0026#34;Run a shell command and return its output.\u0026#34;\u0026#34;\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;index.html  main.py  styles.css  README.md\u0026#34;\u003c/span\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"n\"\u003ecommand\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;ls\u0026#34;\u003c/span\u003e \u003cspan class=\"k\"\u003eelse\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;Done\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003edef\u003c/span\u003e \u003cspan class=\"nf\"\u003eweb_search\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003equery\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"nb\"\u003estr\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e \u003cspan class=\"nb\"\u003estr\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"s2\"\u003e\u0026#34;\u0026#34;\u0026#34;Search the web and return the results.\u0026#34;\u0026#34;\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"sa\"\u003ef\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;Search results for \u0026#39;\u003c/span\u003e\u003cspan class=\"si\"\u003e{\u003c/span\u003e\u003cspan class=\"n\"\u003equery\u003c/span\u003e\u003cspan class=\"si\"\u003e}\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#39;: Found documentation.\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003etools\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;bash_tool\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"n\"\u003ebash_tool\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;web_search\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"n\"\u003eweb_search\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# Simulates the AI picking a tool based on keywords\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003edef\u003c/span\u003e \u003cspan class=\"nf\"\u003emock_llm\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003equery\u003c/span\u003e\u003cspan class=\"p\"\u003e):\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;file\u0026#34;\u003c/span\u003e \u003cspan class=\"ow\"\u003ein\u003c/span\u003e \u003cspan class=\"n\"\u003equery\u003c/span\u003e \u003cspan class=\"ow\"\u003eor\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;list\u0026#34;\u003c/span\u003e \u003cspan class=\"ow\"\u003ein\u003c/span\u003e \u003cspan class=\"n\"\u003equery\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;tool\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;bash_tool\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;arguments\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;command\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;ls\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e}}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;tool\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;web_search\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;arguments\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;query\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"n\"\u003equery\u003c/span\u003e\u003cspan class=\"p\"\u003e}}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003ewhile\u003c/span\u003e \u003cspan class=\"kc\"\u003eTrue\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003euser_query\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nb\"\u003einput\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;User: \u0026gt; \u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"n\"\u003euser_query\u003c/span\u003e\u003cspan class=\"o\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003elower\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"ow\"\u003ein\u003c/span\u003e \u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;exit\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;quit\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e]:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"nb\"\u003eprint\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;Goodbye!\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"k\"\u003ebreak\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e# Step 1: Get tool choice from LLM\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003edecision\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003emock_llm\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003euser_query\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003etool_name\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eargs\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003edecision\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;tool\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e],\u003c/span\u003e \u003cspan class=\"n\"\u003edecision\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;arguments\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nb\"\u003eprint\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"sa\"\u003ef\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;AI wants to call: \u003c/span\u003e\u003cspan class=\"si\"\u003e{\u003c/span\u003e\u003cspan class=\"n\"\u003etool_name\u003c/span\u003e\u003cspan class=\"si\"\u003e}\u003c/span\u003e\u003cspan class=\"s2\"\u003e(\u003c/span\u003e\u003cspan class=\"si\"\u003e{\u003c/span\u003e\u003cspan class=\"n\"\u003eargs\u003c/span\u003e\u003cspan class=\"si\"\u003e}\u003c/span\u003e\u003cspan class=\"s2\"\u003e)\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e# Step 2 \u0026amp; 3: execute the tool and print the output\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003etool_output\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003etools\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003etool_name\u003c/span\u003e\u003cspan class=\"p\"\u003e](\u003c/span\u003e\u003cspan class=\"o\"\u003e**\u003c/span\u003e\u003cspan class=\"n\"\u003eargs\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nb\"\u003eprint\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"sa\"\u003ef\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;Tool Output: \u003c/span\u003e\u003cspan class=\"si\"\u003e{\u003c/span\u003e\u003cspan class=\"n\"\u003etool_output\u003c/span\u003e\u003cspan class=\"si\"\u003e}\u003c/span\u003e\u003cspan class=\"se\"\u003e\\n\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003cp\u003eThat\u0026rsquo;s tool-calling in a nutshell: the model picks a tool (e.g. \u003ccode\u003eweb_search\u003c/code\u003e or\n\u003ccode\u003ebash_tool\u003c/code\u003e) and supplies the right arguments (e.g. \u003ccode\u003equery: \u0026quot;who won the 2022 World Cup\u0026quot;\u003c/code\u003e), the tool or API is executed — locally or remotely — and the model reads back the\nresult.\u003c/p\u003e","title":"What is MCP (Model Context Protocol)?"},{"content":"Conductor is a desktop app for running several AI coding agents in parallel on the same project. Instead of driving one agent at a time, you spin up multiple agents that each work independently and hand you the results to review.\nWhat it does Conductor connects to your AI provider — Claude, Codex, and others — and lets you launch multiple agents to work on your project at once. Each agent runs in its own git worktree, so their changes stay isolated from one another. When an agent finishes, its worktree makes it easy to review the diff, integrate the work, and push it to git.\nRunning agents in parallel worktrees is the key idea: several tasks progress at the same time without stepping on each other\u0026rsquo;s files, and you keep a clean path from an agent\u0026rsquo;s output to a commit.\nFor a walkthrough of the tool, see the overview video.\nDownsides macOS only. At the time of writing, Conductor is available only for Mac. References Conductor Overview video (YouTube) ","permalink":"https://hadifar.net/posts/conductor-ide-for-parallel-agent/","summary":"\u003cp\u003e\u003ca href=\"https://www.conductor.build/\"\u003eConductor\u003c/a\u003e is a desktop app for running several AI coding\nagents in parallel on the same project. Instead of driving one agent at a time, you spin up\nmultiple agents that each work independently and hand you the results to review.\u003c/p\u003e\n\u003ch2 id=\"what-it-does\"\u003eWhat it does\u003c/h2\u003e\n\u003cp\u003eConductor connects to your AI provider — Claude, Codex, and others — and lets you launch\nmultiple agents to work on your project at once. Each agent runs in its own \u003cstrong\u003egit\nworktree\u003c/strong\u003e, so their changes stay isolated from one another. When an agent finishes, its\nworktree makes it easy to review the diff, integrate the work, and push it to git.\u003c/p\u003e","title":"Conductor: IDE to run parallel coding agents"},{"content":"A quick comparison of tools people use for vibe-coding and agentic coding. Fill in your own experience/notes as you try each one.\nTool Type Runs where Notes Official site Claude Code CLI / IDE agent Terminal, VS Code, JetBrains Deep agentic loop, tool use, subagents, hooks, MCP support claude.com/claude-code Cursor IDE (fork of VS Code) Desktop Agent mode, inline edits, codebase-aware chat cursor.com GitHub Copilot / Copilot Workspace IDE extension VS Code, JetBrains, GitHub.com Autocomplete + chat + task-level \u0026ldquo;workspace\u0026rdquo; planning github.com/features/copilot Aider CLI Terminal Open-source, git-native, works with many model backends aider.chat Windsurf IDE Desktop \u0026ldquo;Cascade\u0026rdquo; agent flow, multi-file edits windsurf.com Devin Autonomous agent Cloud sandbox Longer-running autonomous tasks, less interactive devin.ai Conductor IDE Desktop (macOS) Runs multiple agents in parallel, each in its own git worktree conductor.build superset.sh IDE Desktop (macOS, Linux) Conductor alternative with Linux support; parallel agents in isolated worktrees, notifications, skills/hooks docs.superset.sh goose CLI / desktop agent Terminal, Desktop Open-source, MCP-based extensions, subagents, recipes, scheduled runs goose-docs.ai ","permalink":"https://hadifar.net/posts/tools-landscape/","summary":"\u003cp\u003eA quick comparison of tools people use for vibe-coding and agentic coding. Fill in your own experience/notes as you try each one.\u003c/p\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003eTool\u003c/th\u003e\n          \u003cth\u003eType\u003c/th\u003e\n          \u003cth\u003eRuns where\u003c/th\u003e\n          \u003cth\u003eNotes\u003c/th\u003e\n          \u003cth\u003eOfficial site\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003cstrong\u003eClaude Code\u003c/strong\u003e\u003c/td\u003e\n          \u003ctd\u003eCLI / IDE agent\u003c/td\u003e\n          \u003ctd\u003eTerminal, VS Code, JetBrains\u003c/td\u003e\n          \u003ctd\u003eDeep agentic loop, tool use, subagents, hooks, MCP support\u003c/td\u003e\n          \u003ctd\u003e\u003ca href=\"https://www.claude.com/product/claude-code\"\u003eclaude.com/claude-code\u003c/a\u003e\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003cstrong\u003eCursor\u003c/strong\u003e\u003c/td\u003e\n          \u003ctd\u003eIDE (fork of VS Code)\u003c/td\u003e\n          \u003ctd\u003eDesktop\u003c/td\u003e\n          \u003ctd\u003eAgent mode, inline edits, codebase-aware chat\u003c/td\u003e\n          \u003ctd\u003e\u003ca href=\"https://cursor.com\"\u003ecursor.com\u003c/a\u003e\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003cstrong\u003eGitHub Copilot / Copilot Workspace\u003c/strong\u003e\u003c/td\u003e\n          \u003ctd\u003eIDE extension\u003c/td\u003e\n          \u003ctd\u003eVS Code, JetBrains, GitHub.com\u003c/td\u003e\n          \u003ctd\u003eAutocomplete + chat + task-level \u0026ldquo;workspace\u0026rdquo; planning\u003c/td\u003e\n          \u003ctd\u003e\u003ca href=\"https://github.com/features/copilot\"\u003egithub.com/features/copilot\u003c/a\u003e\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003cstrong\u003eAider\u003c/strong\u003e\u003c/td\u003e\n          \u003ctd\u003eCLI\u003c/td\u003e\n          \u003ctd\u003eTerminal\u003c/td\u003e\n          \u003ctd\u003eOpen-source, git-native, works with many model backends\u003c/td\u003e\n          \u003ctd\u003e\u003ca href=\"https://aider.chat\"\u003eaider.chat\u003c/a\u003e\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003cstrong\u003eWindsurf\u003c/strong\u003e\u003c/td\u003e\n          \u003ctd\u003eIDE\u003c/td\u003e\n          \u003ctd\u003eDesktop\u003c/td\u003e\n          \u003ctd\u003e\u0026ldquo;Cascade\u0026rdquo; agent flow, multi-file edits\u003c/td\u003e\n          \u003ctd\u003e\u003ca href=\"https://windsurf.com\"\u003ewindsurf.com\u003c/a\u003e\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003cstrong\u003eDevin\u003c/strong\u003e\u003c/td\u003e\n          \u003ctd\u003eAutonomous agent\u003c/td\u003e\n          \u003ctd\u003eCloud sandbox\u003c/td\u003e\n          \u003ctd\u003eLonger-running autonomous tasks, less interactive\u003c/td\u003e\n          \u003ctd\u003e\u003ca href=\"https://devin.ai\"\u003edevin.ai\u003c/a\u003e\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003cstrong\u003eConductor\u003c/strong\u003e\u003c/td\u003e\n          \u003ctd\u003eIDE\u003c/td\u003e\n          \u003ctd\u003eDesktop (macOS)\u003c/td\u003e\n          \u003ctd\u003eRuns multiple agents in parallel, each in its own git worktree\u003c/td\u003e\n          \u003ctd\u003e\u003ca href=\"https://www.conductor.build/\"\u003econductor.build\u003c/a\u003e\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003cstrong\u003esuperset.sh\u003c/strong\u003e\u003c/td\u003e\n          \u003ctd\u003eIDE\u003c/td\u003e\n          \u003ctd\u003eDesktop (macOS, Linux)\u003c/td\u003e\n          \u003ctd\u003eConductor alternative with Linux support; parallel agents in isolated worktrees, notifications, skills/hooks\u003c/td\u003e\n          \u003ctd\u003e\u003ca href=\"https://docs.superset.sh/\"\u003edocs.superset.sh\u003c/a\u003e\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003cstrong\u003egoose\u003c/strong\u003e\u003c/td\u003e\n          \u003ctd\u003eCLI / desktop agent\u003c/td\u003e\n          \u003ctd\u003eTerminal, Desktop\u003c/td\u003e\n          \u003ctd\u003eOpen-source, MCP-based extensions, subagents, recipes, scheduled runs\u003c/td\u003e\n          \u003ctd\u003e\u003ca href=\"https://goose-docs.ai/\"\u003egoose-docs.ai\u003c/a\u003e\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e","title":"Tools landscape"},{"content":"These are the notes from talks at Y Combinator.\nGeneral rule of thumb The best technique is to do what a professional software engineer already does. Small code, modularity, and abstraction are your friends — they help both you and the LLM reason about the project.\nNote: this advice will likely shift over the next few months. As models get more capable, some of these guardrails will loosen.\nPlan before you build Don\u0026rsquo;t ask the model to one-shot the whole project. Instead, create a planning file (a CLAUDE.md or a plain markdown file) that lays out step by step what you want to build. Iterate on it over time and revise it whenever your understanding changes. You can even use a Planner agent to help revise it.\nSome sections that are useful to keep in that file:\n1 2 3 4 5 6 7 8 9 10 11 12 13 # Preliminaries - Stack: pydantic, FastAPI, pydantic-settings, ... # Priorities ## 1. General architecture for this project ## 2. Use MongoDB as the database ## 3. ... # Do not implement - (things to explicitly keep out of scope) # Ideas for later - (parking lot for scope you\u0026#39;re deferring) Then ask the LLM to implement one section at a time. Ask small. Narrow requests are easier to review, easier to test, and easier to roll back when they go wrong.\nVersion control Use git extensively — for essentially every feature:\nCreate a branch and try out your idea. If it works, merge it. If it doesn\u0026rsquo;t, go back to the branch and try again with a different prompt. Make sure what you push is clean and ready. Testing Write high-level tests rather than tests for tiny individual functions. High-level tests capture the behavior you actually care about, so that future changes — whether made by you or the model — don\u0026rsquo;t quietly destroy your logic.\nFixing bugs Often the fastest fix is the simplest: copy and paste the output of the error, the JavaScript console, or the IDE logs straight into the model. That context alone is frequently enough for it to find and fix the problem.\nDocumentation Give the model good docs to work from:\nDownload documentation locally and point the LLM at it. Reference it via a link. Or expose it through an MCP server so the model can pull it in on demand. Complex functionality For a hard or unfamiliar feature, build it in a separate project, isolated from your main codebase (sometimes this is even someone else\u0026rsquo;s project on GitHub). Then ask the LLM to implement the feature in your project while respecting your existing code. This keeps experimental complexity away from your working code until it\u0026rsquo;s ready.\nRefactor frequently Ask your LLM to refactor regularly:\nRemove dead code, repetitive code, and junk. Keep large files smaller and more modular. Frequent, small refactors keep the codebase in a shape that both you and the model can keep working in effectively.\nReferences YouTube - Tom Blomfield, \u0026ldquo;How to vibe code\u0026rdquo; Youtube - Y Combinator, \u0026ldquo;Vibe Coding Is The Future\u0026rdquo; ","permalink":"https://hadifar.net/posts/yc-guide-to-vibe-coding/","summary":"\u003cp\u003eThese are the notes from talks at \u003cem\u003eY Combinator\u003c/em\u003e.\u003c/p\u003e\n\u003ch2 id=\"general-rule-of-thumb\"\u003eGeneral rule of thumb\u003c/h2\u003e\n\u003cp\u003eThe best technique is to do what a professional software engineer already does. \u003cstrong\u003eSmall code\u003c/strong\u003e, \u003cstrong\u003emodularity\u003c/strong\u003e, and\n\u003cstrong\u003eabstraction\u003c/strong\u003e are your friends — they help both you and the LLM reason about the project.\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003eNote: this advice will likely shift over the next few months. As models\nget more capable, some of these guardrails will loosen.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003ch2 id=\"plan-before-you-build\"\u003ePlan before you build\u003c/h2\u003e\n\u003cp\u003eDon\u0026rsquo;t ask the model to one-shot the whole project. Instead, create a planning file (a\n\u003ccode\u003eCLAUDE.md\u003c/code\u003e or a plain markdown file) that lays out step by step what you want to build.\nIterate on it over time and revise it whenever your understanding changes. You can even\nuse a Planner agent to help revise it.\u003c/p\u003e","title":"YC guide to vibe coding"},{"content":"There are many vector databases available today, such as Chroma, Pinecone, Qdrant, Milvus, pgvector, and Elastic. Each offers unique capabilities and is useful in different situations. For developers integrating vector search into their applications for the first time, Chroma and Milvus tend to provide excellent documentation and straightforward implementations.\nHowever, many production systems still rely on traditional sparse or boolean retrieval engines like Elasticsearch. In those contexts, Elasticsearch remains extremely efficient and is arguably one of the best solutions available. That said, Elasticsearch joined the vector-search space relatively late (basic dense-vector support was introduced around version 8.x), and historically you needed custom scripts for many advanced features.\nI recently upgraded my Elasticsearch setup to version 9.x to explore the new additions. In this post, I briefly go over its advantages and disadvantages.\nGetting started You can visit their documentation to get started. To spin up a local environment, simply run:\n1 curl -fsSL https://elastic.co/start-local | sh This command launches three containers (elastic, kibana, and kibana_settings) and starts the stack.\nelastic-start-local setting up Elasticsearch and Kibana 9.2.1\nYou can log in using the credentials provided during setup and explore the available options. At first glance, the documentation and overall Kibana user experience are significantly improved. Creating indices, inspecting data, and running queries directly from the GUI is now much easier, and they even provide sample code for multiple languages.\nExample setup I created a small repository where you can insert documents and run searches. It\u0026rsquo;s intentionally minimalistic but enough to demonstrate basic Elasticsearch functionality.\nInstall the requirements and start the FastAPI server using:\n1 uvicorn app:app --reload --env-file .env Let\u0026rsquo;s then add some documents and populate our test index:\nAdding documents via the FastAPI server\u0026rsquo;s /add_documents endpoint\nHere, I would like to create a hybrid search, which often performs better than pure dense-vector search. The content field is a string, and content_vector is a dummy list of floats. In my own projects, I typically separate vectorization from search because it provides more flexibility later on.\nElasticsearch 9.x makes exploring your index much easier through Kibana. The data, mapping, and settings are more accessible and better organized.\nKibana\u0026rsquo;s index details page, with sample Python search code generated for the index\nThey also provide simple examples for hybrid search using RRF, as you can see in the Python sample code in the screenshot above.\nOnce everything is set up, we can run a hybrid search query against our index. I used the following request:\n1 2 3 4 { \u0026#34;query_string\u0026#34;: \u0026#34;cream\u0026#34;, \u0026#34;query_vector\u0026#34;: [0.2, 0.3, 0.1] } Running this returns two hits, as expected.\nTakeaway While Elasticsearch 9.x has improved substantially, I still feel many of the details in the query could be abstracted away for developers. Most users do not need to understand concepts like KNN or RRF (Reciprocal Rank Fusion) immediately. Writing and debugging queries can still feel intimidating, particularly for newcomers.\nElasticsearch would benefit from an additional abstraction layer to simplify the developer experience — otherwise new users may prefer more approachable vector-database alternatives.\nThat said, Elasticsearch remains extremely reliable and robust.\n","permalink":"https://hadifar.net/posts/elastic-as-a-vector-search-engine/","summary":"\u003cp\u003eThere are many vector databases available today, such as Chroma, Pinecone, Qdrant, Milvus,\npgvector, and Elastic. Each offers unique capabilities and is useful in different situations.\nFor developers integrating vector search into their applications for the first time, Chroma\nand Milvus tend to provide excellent documentation and straightforward implementations.\u003c/p\u003e\n\u003cp\u003eHowever, many production systems still rely on traditional sparse or boolean retrieval\nengines like Elasticsearch. In those contexts, Elasticsearch remains extremely efficient and\nis arguably one of the best solutions available. That said, Elasticsearch joined the\nvector-search space relatively late (basic dense-vector support was introduced around version\n8.x), and historically you needed custom scripts for many advanced features.\u003c/p\u003e","title":"Elastic as a Vector Search Engine"},{"content":"I first came across TOON (Token-Oriented Object Notation) on LinkedIn, where developers were discussing its promise: lossless compression of JSON and YAML, specifically optimized for large language models (LLMs). The core idea? Reduce token count without sacrificing information, which directly translates to lower costs and potentially faster processing.\nComparison between TOON and JSON for nested objects\nAt first glance, TOON looks familiar yet distinct. For instance, a TOON object always begins with the number of items (e.g., [2] in the figure above), and unlike JSON it drops quotation marks (\u0026quot;) around keys. This minimalism becomes especially powerful with flat data structures. In those cases, TOON starts to resemble CSV format: a header row followed by values. The result? Significant token savings (I used their Python version for my experiments).\nComparison between JSON and TOON for flat objects\nAccording to the project\u0026rsquo;s evaluation, which tested 209 questions across several tasks, TOON achieves \u0026ldquo;higher accuracy while using fewer tokens.\u0026rdquo;\nEvaluation of TOON on 209 questions\nThe question distribution breaks down as follows: Field retrieval (33%), Aggregation (30%), Filtering (23%), Structure awareness (12%), Structural validation (2%). With this distribution you can see why there\u0026rsquo;s a large gap between JSON and TOON in structural validation — they validated it on 2% of 209 questions (4 or 5 questions).\nDigging deeper into their methodology and prompt design, I\u0026rsquo;m skeptical that the reported accuracy gains are as robust as claimed. The token savings, however, are real, especially for flat data. Here is the prompt used for the evaluation:\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Given the following data in toon format: TOON: Indentation-based. Arrays declare length and fields (e.g., items[N]{f1,f2}:). Rows use single delimiter. Values may be quoted. {data_in_toon_format} Question: {question} Answer format requirements: - Provide only the value itself, no explanation - For numbers: output digits only (no commas, currency symbols, or units) - For dates/field names: use the exact string from the data - For lists: output comma-separated values with no spaces Answer: That said, there\u0026rsquo;s a caveat worth considering: LLMs are typically pretrained on standard formats like JSON and YAML, complete with proper spacing, quotes, and structure. Introducing a non-standard notation like TOON might increase the risk of hallucinations.\nSo while TOON is a clever optimization for specific use cases — especially cost-sensitive, flat-data applications — it\u0026rsquo;s not a drop-in replacement for traditional serialization formats.\n","permalink":"https://hadifar.net/posts/toon-token-oriented-object-notation/","summary":"\u003cp\u003eI first came across \u003cstrong\u003eTOON (Token-Oriented Object Notation)\u003c/strong\u003e on LinkedIn, where developers\nwere discussing its promise: \u003cstrong\u003elossless compression of JSON and YAML\u003c/strong\u003e, specifically\noptimized for large language models (LLMs). The core idea? Reduce token count without\nsacrificing information, which directly translates to \u003cstrong\u003elower costs\u003c/strong\u003e and potentially\n\u003cstrong\u003efaster processing\u003c/strong\u003e.\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"Comparison between TOON and JSON for nested objects\" loading=\"lazy\" src=\"/images/toon-token-oriented-object-notation/nested-comparison.png\"\u003e\n\u003cem\u003eComparison between TOON and JSON for nested objects\u003c/em\u003e\u003c/p\u003e\n\u003cp\u003eAt first glance, TOON looks familiar yet distinct. For instance, a TOON object always begins\nwith the number of items (e.g., \u003ccode\u003e[2]\u003c/code\u003e in the figure above), and unlike JSON it drops\nquotation marks (\u003ccode\u003e\u0026quot;\u003c/code\u003e) around keys. This minimalism becomes especially powerful with flat\ndata structures. In those cases, TOON starts to resemble CSV format: a header row followed\nby values. The result? Significant token savings (I used their Python version for my\nexperiments).\u003c/p\u003e","title":"Token-Oriented Object Notation: An Alternative to JSON?"},{"content":"I am a Machine Learning Engineer at Nokia, where I focus on exploring the field of AI/ML.\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 @@@@@@@@@@@@@ @@@% @@@ %@@ @@@ @@% @@@ @@ @@ %@@ @@ @@@@@@ @@% %@@ @@ @@ @@% @@@@@@@@@ @@ @@@@@@ @@ @@ @@@ @@% @@@ @@ %@@ @@ @@ @@ @@@ @@ @@ @@ @@ @@ @@ %@@ @@% @@ @@ @@ @@@@@@@@@ @@ %@@ @@ @@ @@ @@ @@@ @@ @@+ @@ @@@% @@ @@ @@ @@ @@@ @@ @@ @@ @@@ %@@ %@@ @@ @@@ @@@ *@@ @@ @@ @@@ @@@ @@@ @@@ @@% @@% @@@@ @@ *@@@@@@ @@@ %@@@@@@% @@% @@# @@@@ @%@@@ @@@% @@@@% @@@@ @@@@@@@@@@@@@@@@@% ","permalink":"https://hadifar.net/about/","summary":"About","title":"About"}]