From 7617374d58e77e13a9f6fe83c52313b5eb2e7f50 Mon Sep 17 00:00:00 2001 From: Yaowei Zheng Date: Thu, 23 Jul 2026 05:04:54 +0800 Subject: [PATCH] feat(blog): a Perspectives category and three posts on harness design and agent infrastructure (#45) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds three bilingual posts, each grounded in primary sources rather than secondary summaries, plus a new blog category to hold them. Simple Harness Is All You Need — opens on the counter-intuitive result in the Databricks coding-agent benchmark: on their cost-versus-pass-rate Pareto chart, the highest score on the board belongs to Opus 4.8 on the minimal Pi harness, ahead of the same model on Claude Code at maximum effort for roughly half the cost per task. Keeps Databricks' own caution and notes that Pi at max effort lands well below Claude Code at comparable spend. Maps the result onto PenguinHarness's measured design: six built-in tools with no file tools, a 72-line system prompt, a 16,000-character output cap, and compaction into a fresh context. The Easiest Way to Build AI Agents in 2026 — argues the cost of building an agent has moved out of the agent and into the stack around it: LangChain to build, LangGraph to orchestrate, LangSmith or Langfuse to observe and evaluate, LangGraph Platform to deploy. Five products, two or three vendors, and a person who becomes the optimization loop. AI Infrastructure: Past, Present, and Future — the stack used to build AI (PyTorch, vLLM, Ollama, LlamaFactory) assumes a human operator who carries state in their head and treats errors as a starting point. It needs no reinventing for agents; what was missing is the operating knowledge, which the ollama, vllm and llamafactory skills encode. Both benchmark comparisons disclose the results we lose as well as the ones we win, and the framework post names two cases where you should pick something else. Also adds the Perspectives / 观点 category with a teal badge, filter chip and both dictionaries, keeping Tech practice for the hands-on AMD walkthroughs. --- changelog/0.2.0/2026-07-22-sites-and-blog.md | 12 +- changelog/0.2.0/README.md | 2 +- ...i-infrastructure-past-present-future.en.md | 96 +++++++++++++ ...i-infrastructure-past-present-future.zh.md | 96 +++++++++++++ .../easiest-way-to-build-ai-agents-2026.en.md | 130 ++++++++++++++++++ .../easiest-way-to-build-ai-agents-2026.zh.md | 124 +++++++++++++++++ .../blog/simple-harness-is-all-you-need.en.md | 117 ++++++++++++++++ .../blog/simple-harness-is-all-you-need.zh.md | 122 ++++++++++++++++ .../public/blog-assets/databricks-pareto.png | Bin 0 -> 91406 bytes .../landing/src/components/category-badge.tsx | 6 +- packages/landing/src/lib/blog.ts | 8 +- packages/landing/src/lib/strings-en.ts | 3 +- packages/landing/src/lib/strings.ts | 3 +- packages/landing/src/pages/blog-list.tsx | 4 +- packages/landing/test/blog.test.ts | 11 +- 15 files changed, 723 insertions(+), 11 deletions(-) create mode 100644 packages/landing/content/blog/ai-infrastructure-past-present-future.en.md create mode 100644 packages/landing/content/blog/ai-infrastructure-past-present-future.zh.md create mode 100644 packages/landing/content/blog/easiest-way-to-build-ai-agents-2026.en.md create mode 100644 packages/landing/content/blog/easiest-way-to-build-ai-agents-2026.zh.md create mode 100644 packages/landing/content/blog/simple-harness-is-all-you-need.en.md create mode 100644 packages/landing/content/blog/simple-harness-is-all-you-need.zh.md create mode 100644 packages/landing/public/blog-assets/databricks-pareto.png diff --git a/changelog/0.2.0/2026-07-22-sites-and-blog.md b/changelog/0.2.0/2026-07-22-sites-and-blog.md index c56d828..adfa7d1 100644 --- a/changelog/0.2.0/2026-07-22-sites-and-blog.md +++ b/changelog/0.2.0/2026-07-22-sites-and-blog.md @@ -6,7 +6,17 @@ The two sites' navbars differed in container width (6xl vs 7xl), the docs-only b ## Blog categories, pinned posts, and page metadata -The blog list stays a single flat list with category badges and filter chips, now across three categories — Product news, Release notes, and the new Tech practice, which the AMD local-agents post moved into. Posts can be pinned to the top via `pinned: true` frontmatter; the launch post introducing PenguinHarness is pinned. A second practice post joined the blog: implementing agent self-improvement with PenguinHarness on an AMD GPU (en + zh), adopted into the same category and author conventions. The detail page moves its metadata below the title: a locale-formatted date ("July 20, 2026" / "2026年7月20日"), the author line (frontmatter `author`, defaulting to Yaowei Zheng (PrismShadow AI)), and a copy-page-link button with a safe clipboard fallback and a transient "Copied" state. +The blog list stays a single flat list with category badges and filter chips, now across four categories — Product news, Release notes, Tech practice (which the AMD local-agents post moved into), and Perspectives. Perspectives holds analysis and opinion rather than hands-on walkthroughs, keeping the practice category for posts you follow along with; it is labelled "Perspectives" / "观点" and carries a teal badge, set apart from the brand-blue product and practice badges and the neutral release-notes one. Posts can be pinned to the top via `pinned: true` frontmatter; the launch post introducing PenguinHarness is pinned. A second practice post joined the blog: implementing agent self-improvement with PenguinHarness on an AMD GPU (en + zh), adopted into the same category and author conventions. The detail page moves its metadata below the title: a locale-formatted date ("July 20, 2026" / "2026年7月20日"), the author line (frontmatter `author`, defaulting to Yaowei Zheng (PrismShadow AI)), and a copy-page-link button with a safe clipboard fallback and a transient "Copied" state. + +## Three technical posts on harness design and agent infrastructure + +The blog gains three bilingual posts in the new Perspectives category, each sourced against primary material rather than summary: + +- **Simple Harness Is All You Need** — opens on the counter-intuitive result in the Databricks coding-agent benchmark: on their cost-versus-pass-rate Pareto chart (reproduced with credit as `blog-assets/databricks-pareto.png`), the highest score on the board belongs to Opus 4.8 running on the minimal Pi harness, ahead of the same model on Claude Code at maximum effort for roughly half the cost per task, with most of the frontier held by Pi. It keeps Databricks' own caution — Pi at `max` effort lands well below Claude Code at comparable spend — and their explanation that Pi sent about a third of the context per turn. The post then maps this onto PenguinHarness's measured design: six built-in tools with no file tools at all, a 72-line system prompt, a 16,000-character output cap, and compaction into a fresh context — before arguing where minimalism must stop, since Pi ships no permission system while per-call approval and Trace auditing are load-bearing here. +- **The Easiest Way to Build AI Agents in 2026** — argues the cost of building an agent has moved out of the agent itself and into the stack assembled around it: on the most popular option that means LangChain to build, LangGraph to orchestrate, LangSmith or Langfuse to observe and evaluate, and LangGraph Platform to deploy — five products across two or three vendors, each with its own concepts and documentation, plus a person who becomes the optimization loop. Compares five representative options against PenguinHarness on facts checked 2026-07-22, notes the field's convergence on thin (AutoGen in maintenance mode, LangChain's legacy surface moved to `langchain-classic`, "harness" adopted as vendor vocabulary by AWS, Microsoft and Anthropic within two months), and sets against it a single install that ships chat, skills, models, usage, Trace and the evaluation center together, then hands the tuning loop to the agent. Includes a section on when not to use PenguinHarness. +- **AI Infrastructure: Past, Present, and Future** — argues that the AI development stack (PyTorch, vLLM, Ollama, LlamaFactory) was built for a human operator who carries state in their head, treats errors as a starting point for investigation, and reads documentation once. It needs no reinventing for agents, since it is already commands and config files; what was missing is the operating knowledge around it, which the shipped `ollama`, `vllm` and `llamafactory` skills encode — check before you change, preflight the constraint that actually binds, verify with an observation, and register the served model so the job is finished rather than started. Closes on what remains unsolved: ML-stack errors still written for humans, GPUs as a shared resource with no reservation protocol, and reproducibility. + +The landing blog list test moves to the new post count and the practice-category ordering that follows from it. ## The built-in Skills, listed where people look diff --git a/changelog/0.2.0/README.md b/changelog/0.2.0/README.md index d7a2d18..f9646e5 100644 --- a/changelog/0.2.0/README.md +++ b/changelog/0.2.0/README.md @@ -8,7 +8,7 @@ Unreleased. - [2026-07-22] Skills: vLLM and Ollama deployment plus LlamaFactory fine-tuning join the AI App Development group with a guided serving workflow that follows the user's engine preference, and `agenthub-models` tracks the AgentHub 0.4.1 API. ([details](2026-07-22-skills.md)) -- [2026-07-22] Sites: the docs and landing navbars are now identical, the blog gains a Tech-practice category, pinned posts, author/date/copy-link metadata and a second AMD practice post, and the built-in Skills are listed in the READMEs and on the landing page. ([details](2026-07-22-sites-and-blog.md)) +- [2026-07-22] Sites: the docs and landing navbars are now identical, the blog gains Tech-practice and Perspectives categories, pinned posts, author/date/copy-link metadata, a second AMD practice post and three bilingual Perspectives posts (harness minimalism against the Databricks benchmark, a sourced comparison of five agent frameworks, and the AI development stack — vLLM, Ollama, LlamaFactory — as infrastructure now driven by agents rather than people), and the built-in Skills are listed in the READMEs and on the landing page. ([details](2026-07-22-sites-and-blog.md)) - [2026-07-22] Docs and examples: two new README roadmap items, and the self-improvement example reworked to genuinely evolve itself. ([details](2026-07-22-docs-and-examples.md)) diff --git a/packages/landing/content/blog/ai-infrastructure-past-present-future.en.md b/packages/landing/content/blog/ai-infrastructure-past-present-future.en.md new file mode 100644 index 0000000..81f7be8 --- /dev/null +++ b/packages/landing/content/blog/ai-infrastructure-past-present-future.en.md @@ -0,0 +1,96 @@ +--- +title: "AI Infrastructure: Past, Present, and Future" +date: 2026-07-22 +category: perspectives +excerpt: PyTorch, vLLM, Ollama and LlamaFactory were all designed for a human who reads the docs, watches the logs and remembers what is already running. Increasingly the thing driving them is an agent. Here is what changes — and what PenguinHarness ships today to make it work. +--- + +The infrastructure we use to build AI was designed for people. PyTorch assumes someone reading a tutorial. vLLM assumes an engineer who knows how much VRAM the card has. LlamaFactory assumes a researcher who will read the training curve and decide whether it is going well. Ollama assumes you remember whether the service is already running. + +Every one of those assumptions is about a human operator. And increasingly, the operator is an agent. + +This is a short post about what that changes, and what we already ship for it. + +## 1. Past: three assumptions about a human operator + +Three assumptions run through nearly all AI tooling, and all three quietly break when the user is a program. + +### 1.1 That the user carries state in their head + +You know you started an Ollama server this morning. You know the training job from last night is still holding the GPU. None of that is in any command's output, because a human did not need it written down. + +### 1.2 That errors are a starting point for investigation + +`CUDA out of memory` is a perfectly good message for a person — you read it, you halve the batch size, you move on. It tells an agent almost nothing about what to do next, and the ML stack is full of errors like it: shape mismatches thrown eight frames deep, NCCL timeouts, a silent fallback to CPU that only shows up as everything being forty times slower. + +### 1.3 That documentation is read once, by someone who will remember it + +Tutorials are written as prose, front to back, with the important constraint — the model has to fit in VRAM — in a sentence somewhere in the middle. + +Stripe measured what this costs when they benchmarked whether agents could build real integrations against their API. The failure mode they found generalizes uncomfortably well: agents "would pass in nonexistent Stripe data, observe 400s, and consider the task complete." The error was correct. It still failed to communicate failure. + +## 2. Present: the stack is already agent-shaped + +### 2.1 The shell is the integration + +The good news is that AI infrastructure is, by accident, better suited to agents than most software. It is already command-line tools, YAML configs and Python files — text in, text out, composable. There is no need to wrap `nvidia-smi` in anything. An agent with a shell can already drive the entire stack. + +That is why PenguinHarness exposes the shell as its universal interface — `exec_command` is the whole filesystem and process interface, and there are no separate file tools. Driving vLLM is not an integration; it is a command. + +### 2.2 What actually needs building: the operating knowledge + +What is missing is not connectivity. It is the operating knowledge a competent engineer has and a model does not. We ship that as **Skills** — instruction packages an agent reads on demand. Three of them cover this stack directly, in the AI App Development group: + +| Skill | What it lets an agent do | +| --- | --- | +| `ollama` | Pull and serve local models, expose the OpenAI-compatible endpoint | +| `vllm` | Serve on GPU for high throughput, with tool-calling flags enabled for agent workloads | +| `llamafactory` | Fine-tune with LoRA/QLoRA, SFT or DPO through YAML configs | + +What is in them is more interesting than that they exist, because each one encodes a rule a human would never have needed: + +1. **Check the world before changing it.** The `ollama` skill has the agent run `ollama --version` and `ollama ps` first, and then states the rule plainly: if port 11434 is already serving, reuse that instance — *never kill an existing Ollama process*. A human knows not to kill their colleague's server. An agent has to be told. +2. **Preflight the constraint that actually binds.** The `vllm` skill confirms hardware with `nvidia-smi` (or `rocm-smi` on AMD) before anything else, because model size and context length are bounded by VRAM. The buried sentence in the tutorial becomes step zero. +3. **Verify, do not assume.** Both serving skills end with a real check — `curl http://localhost:8000/v1/models` — before the job counts as done. This is the direct answer to the Stripe failure mode: the definition of success is an observation, not the absence of a crash. +4. **Finish the job.** A served model is invisible to PenguinHarness until it is registered, so the skills close the loop with `penguin config model add --client-type openai --base-url ...` and then confirm with `penguin config model list`. Starting a server is not the task. Having a usable model is. +5. **Ask instead of guessing.** Every skill opens the same way: if the request names a skill but no concrete goal, ask first and run nothing. Engine choice, for instance, follows the user's preference rather than a hardcoded default — vLLM for high-throughput GPU serving, Ollama as the simple default and the only option on macOS or CPU-only machines. + +### 2.3 Two runtime pieces, because AI work is not shaped like web work + +**Long jobs are first-class.** Training and serving do not complete in thirty seconds. `exec_command` waits in the foreground, and once a command outruns its window it keeps running in the background and hands back a `process_id`; `input_command` then polls it, writes to stdin, or sends Ctrl-C. An agent can start a fine-tune, go do something else, and come back to check on it — without a special "training tool." + +**Failures come back as text, not exceptions.** Tools never throw into the loop. A non-zero exit, a timeout, an OOM — all of it converges into tool output the model reads and reacts to, with the exit code appended outside the truncation window so it survives even when a long log gets cut. That last detail matters more than it sounds: the one line telling you the run actually failed is usually the last one. + +## 3. Future: what is still hard + +Three problems are not solved, by us or anyone. + +### 3.1 ML-stack errors are still written for humans + +Nothing in an agent harness can fix a traceback that does not say what to change. The fix has to happen upstream, in the frameworks — and the guidance already exists: good tool errors are specific and actionable rather than opaque codes and tracebacks. Very little of the training stack meets that bar today. + +### 3.2 GPUs are a shared resource with no protocol + +An agent can read `nvidia-smi`, but there is no standard way to reserve VRAM, queue behind another job, or find out that the memory it just saw is about to be taken. Today the answer is a written rule — do not kill what you did not start — which is a convention, not a guarantee. + +### 3.3 Reproducibility is unresolved + +A fine-tune is a long, expensive, stochastic action. Agents make those cheap to launch, which makes it much easier to end up with a model nobody can reproduce. Snapshots and traces help; they are not a full answer. + +## 4. The short version + +AI infrastructure did not need to be reinvented for agents — it was already text and commands. What was missing is the operating knowledge around it: check before you change, preflight the real constraint, verify with an observation, and finish the job rather than starting it. + +That is what our skills encode, on top of a shell, a two-phase process model for long jobs, and errors that come back as readable text. + +```bash +curl -fsSL https://penguin.ooo/install.sh | sh +penguin run -m "Serve Qwen3.5-0.8B with Ollama and register it with Penguin" +``` + +--- + +- **Docs**: [Skills](https://penguin.ooo/docs/skills) · [Tools & Approval](https://penguin.ooo/docs/tools) · [Models & Providers](https://penguin.ooo/docs/models) +- **Community**: [GitHub](https://github.com/Prism-Shadow/penguin-harness) · [Discord](https://discord.gg/eFHKqqcU3D) + +**Sources**: [vLLM](https://docs.vllm.ai/) · [Ollama](https://ollama.com/) · [LlamaFactory](https://github.com/hiyouga/LlamaFactory) · [Stripe, Can AI agents build real Stripe integrations?](https://stripe.com/blog/can-ai-agents-build-real-stripe-integrations) · [Anthropic, Writing effective tools for AI agents](https://www.anthropic.com/engineering/writing-tools-for-agents) diff --git a/packages/landing/content/blog/ai-infrastructure-past-present-future.zh.md b/packages/landing/content/blog/ai-infrastructure-past-present-future.zh.md new file mode 100644 index 0000000..b3c0ceb --- /dev/null +++ b/packages/landing/content/blog/ai-infrastructure-past-present-future.zh.md @@ -0,0 +1,96 @@ +--- +title: "AI 基础设施:过去、现在与未来" +date: 2026-07-22 +category: perspectives +excerpt: PyTorch、vLLM、Ollama、LlamaFactory,都是照着"一个会读文档、会看日志、记得自己启过什么服务的人"来设计的。可现在,越来越多地在驱动它们的是 Agent。这个变化意味着什么,PenguinHarness 今天又为它准备了什么。 +--- + +我们用来构建 AI 的这套基础设施,是照着人来设计的。PyTorch 默认有人在读教程;vLLM 默认工程师清楚自己显卡有多少显存;LlamaFactory 默认研究者会盯着 loss 曲线判断训练正不正常;Ollama 则默认你记得服务是不是已经起来了。 + +**这些默认无一例外都指向一个人类操作者。而现在,操作者越来越多地是 Agent。** + +这篇文章不长,只讲两件事:这个变化带来了什么,以及我们现在为它准备了什么。 + +## 一、过去:关于"人类操作者"的三个默认 + +几乎所有 AI 工具链里都埋着三个默认。使用者一旦换成程序,这三个默认全都会悄无声息地失效。 + +### 1.1 默认使用者把状态记在脑子里 + +你知道今天早上启过一个 Ollama 服务,也知道昨晚那个训练任务还占着显卡。这些信息不会出现在任何一条命令的输出里,因为人本来就不需要它被写下来。 + +### 1.2 默认错误信息是排查的起点,而不是行动指令 + +`CUDA out of memory` 对人来说是条相当好的消息:看一眼,把 batch size 减半,接着干。可它几乎没告诉 Agent 下一步该做什么。而 ML 技术栈里满是这类错误——从八层调用栈深处抛出来的 shape mismatch、NCCL 超时,还有悄悄回落到 CPU,唯一的症状是所有东西慢了四十倍。 + +### 1.3 默认文档只读一次,而且读的人记得住 + +教程是按文章写的,讲究从头读到尾,而真正会卡住你的那条约束——模型得放得进显存——躲在中间某一句话里。 + +Stripe 评测 Agent 能不能基于他们的 API 做出真实集成时,把这笔账算了出来。他们发现的失败模式放到别处同样成立,而且让人不太舒服:Agent 传入了根本不存在的数据,收到 400,然后认为任务已经完成。**错误本身是对的,但它没能把"失败"这件事传达出去。** + +## 二、现在:这套技术栈本来就对 Agent 友好 + +### 2.1 Shell 就是集成层 + +好消息是,AI 基础设施其实比大多数软件都更适合 Agent,而且属于无心插柳:它本来就是命令行工具、YAML 配置和 Python 文件,文本进、文本出,天然可组合。没必要给 `nvidia-smi` 再包一层什么,**一个拿着 shell 的 Agent 已经能把整个栈跑通了。** + +这正是 PenguinHarness 把 shell 当作通用接口的理由:`exec_command` 就是全部的文件与进程接口,没有另外的文件工具。**驱动 vLLM 不算一次"集成",它就是一条命令。** + +### 2.2 真正需要补的,是操作经验 + +缺的从来不是连通性,而是一个称职工程师有、模型没有的那点**操作经验**。我们把它做成 **Skills**,也就是 Agent 按需读取的指令包。其中三个直接覆盖这套技术栈,归在 AI 应用开发技能组里: + +| Skill | 让 Agent 能做什么 | +| --- | --- | +| `ollama` | 拉取并启动本地模型,对外暴露 OpenAI 兼容端点 | +| `vllm` | 在 GPU 上做高吞吐服务,并为 Agent 负载打开工具调用相关参数 | +| `llamafactory` | 用 YAML 配置做 LoRA/QLoRA、SFT 或 DPO 微调 | + +比"有这三个技能"更值得说的,是它们里面到底写了什么——每一条都写下了一件人类根本不需要被叮嘱的事: + +1. **动手之前,先看清楚现场。** `ollama` 技能会让 Agent 先跑 `ollama --version` 和 `ollama ps`,然后把规矩挑明:如果 11434 端口上已经有服务,就复用它,**绝不去杀已经存在的 Ollama 进程**。人当然知道不该动同事的服务,Agent 却必须被明确告知。 +2. **先确认真正卡住你的那条约束。** `vllm` 技能在做任何事之前,先用 `nvidia-smi`(AMD 上是 `rocm-smi`)确认硬件,因为模型规模和上下文长度都被显存卡着。**教程里那句被埋起来的话,在这里被提到了第 0 步。** +3. **要验证,别想当然。** 两个服务类技能都以一次真实检查收尾——`curl http://localhost:8000/v1/models`——过了才算完成。这正好回答了 Stripe 那个失败模式:**"成功"得由一次观测来定义,而不是"没崩就算成了"。** +4. **把活干完,别只起个头。** 模型启动之后,不注册进来 PenguinHarness 是看不见它的,所以技能会用 `penguin config model add --client-type openai --base-url ...` 把这一步闭上,再用 `penguin config model list` 确认一遍。**起一个服务不叫完成任务,拿到一个能用的模型才叫。** +5. **拿不准就问,别猜。** 每个技能开头都是同一句话:如果对方只点了技能名却没说具体要干什么,先问清楚,一条命令都别跑。比如引擎选哪个就听用户的,而不是写死一个默认值——vLLM 用于高吞吐 GPU 服务,Ollama 更省事,也是 macOS 和纯 CPU 机器上的唯一选择。 + +### 2.3 还有两块运行时能力,因为 AI 的活跟 Web 不是一个形状 + +**长任务是一等公民。** 训练和服务不可能三十秒跑完。`exec_command` 先在前台等着,一旦命令超出等待窗口,它就转到后台继续跑并返回一个 `process_id`,之后由 `input_command` 去轮询、写 stdin 或者发 Ctrl-C。**Agent 可以先把微调发起来,转头去干别的,过一阵再回来看进度,不需要什么"训练专用工具"。** + +**失败以文本返回,而不是抛异常。** 工具永远不会把异常抛进循环里。非零退出、超时、OOM,最后都收敛成模型读得懂、也能据此反应的工具输出;退出码还会被追加在截断窗口**之外**,哪怕长日志被砍掉也还在。这个细节比它听上去更要紧:**告诉你这次真的跑挂了的那一行,通常正好是最后一行。** + +## 三、未来:仍然难啃的部分 + +有三个问题至今没有解决,我们没有,别人也没有。 + +### 3.1 ML 技术栈的错误信息,还是写给人看的 + +一段不说明"该改什么"的 traceback,任何 Agent harness 都救不回来。这事得在上游框架里修,而原则其实早就摆在那儿了:好的工具错误应该具体、可执行,而不是甩出一串晦涩的错误码和调用栈。**今天的训练栈里,达到这个标准的部分非常少。** + +### 3.2 GPU 是共享资源,却没有一套协议 + +Agent 能读 `nvidia-smi`,但没有标准办法去预留显存、排队等另一个任务结束,或者提前知道它刚看到的那块空闲显存马上就要被人占走。今天的答案是一条写下来的规矩:别去动不是你启的东西。**那是约定,不是保证。** + +### 3.3 可复现性还没有着落 + +一次微调是耗时、烧钱、还带随机性的动作。Agent 让"发起"这件事变得极其便宜,也就更容易攒出一个谁都复现不出来的模型。快照和 Trace 能帮上忙,但算不上完整答案。 + +## 四、小结 + +**AI 基础设施并不需要为 Agent 重新发明一遍,它本来就是文本和命令。** 缺的是围着它的那点操作经验:动手前先看现场,先确认真正的约束,用观测来确认结果,以及把活干完而不是起个头。 + +这就是我们的 Skills 写下来的东西。底下垫着的,是一个 shell、一套面向长任务的两阶段进程模型,以及以可读文本返回的错误。 + +```bash +curl -fsSL https://penguin.ooo/install.sh | sh +penguin run -m "用 Ollama 启动 Qwen3.5-0.8B 并注册到 Penguin" +``` + +--- + +- **文档**:[Skills](https://penguin.ooo/docs/skills) · [工具与审批](https://penguin.ooo/docs/tools) · [模型与供应商](https://penguin.ooo/docs/models) +- **社区**:[GitHub](https://github.com/Prism-Shadow/penguin-harness) · [Discord](https://discord.gg/eFHKqqcU3D) + +**参考来源**:[vLLM](https://docs.vllm.ai/) · [Ollama](https://ollama.com/) · [LlamaFactory](https://github.com/hiyouga/LlamaFactory) · [Stripe, Can AI agents build real Stripe integrations?](https://stripe.com/blog/can-ai-agents-build-real-stripe-integrations) · [Anthropic, Writing effective tools for AI agents](https://www.anthropic.com/engineering/writing-tools-for-agents) diff --git a/packages/landing/content/blog/easiest-way-to-build-ai-agents-2026.en.md b/packages/landing/content/blog/easiest-way-to-build-ai-agents-2026.en.md new file mode 100644 index 0000000..6680094 --- /dev/null +++ b/packages/landing/content/blog/easiest-way-to-build-ai-agents-2026.en.md @@ -0,0 +1,130 @@ +--- +title: "The Easiest Way to Build AI Agents in 2026" +date: 2026-07-22 +category: perspectives +excerpt: Writing an agent takes ten lines now. The cost has moved somewhere else — into the stack you must assemble around it, where building, observability and evaluation are three separate products from two or three vendors. This is a comparison of what that actually costs to learn, and the case for automating it away instead. +--- + +Ask "what is the easiest way to build an AI agent" and you will get answers about lines of code. Those answers are now mostly obsolete: the leading toolkits all reach a working agent in four to fifteen lines. + +The cost did not disappear. It moved. It now sits in everything *around* the agent — the orchestration layer, the observability platform, the evaluation harness — each a separate product, with separate concepts, separate documentation, and often a separate vendor. Writing the agent is an afternoon. Learning the stack is a quarter. + +This post is about that cost, and about removing it rather than paying it. + +## 1. What "building an agent with LangChain" actually costs + +LangChain is the reasonable default and the most-used option in the space, so it makes the fairest example. To take an agent from prototype to something you would run in production, here is what you assemble: + +| Layer | What you use | Who makes it | What you have to learn | +| --- | --- | --- | --- | +| Build | **LangChain** | LangChain Inc. | Tools, models, `create_agent` | +| Orchestrate | **LangGraph** | LangChain Inc. | Nodes, edges, state, checkpoints, interrupts | +| Observe | **LangSmith** or **Langfuse** | LangChain Inc. / Langfuse | SDK wiring and a hosted platform — or OpenTelemetry plus self-hosting | +| Evaluate | LangSmith evals or Langfuse evals | same | Datasets, judges, experiment configuration | +| Deploy | **LangGraph Platform** | LangChain Inc. | Yet another deployment model | + +Every one of these is a good product. That is not the problem. The problem is that they are five products. + +The observability row is where it bites hardest, because it is a fork in the road rather than a step. LangSmith is LangChain's own commercial platform with native integration — easiest if you are already on the stack, and a managed SaaS you are now dependent on. [Langfuse](https://github.com/langfuse/langfuse) is the open-source alternative: MIT-licensed apart from its enterprise folders, framework-agnostic, self-hostable via Docker or Kubernetes, and maintained by a team that joined ClickHouse in January 2026. It is genuinely excellent. It is also a second vendor, a second data model, and a service you now operate. + +So before your agent does anything useful in production, someone on your team has learned two libraries, wired a tracing SDK, stood up or subscribed to an observability platform, and built an evaluation dataset by hand. Then, when the agent underperforms, that same person reads the traces and tunes the prompts — because there is nothing in this stack that does that part for you. + +**That is the real answer to "how hard is it to build an agent in 2026." Not the ten lines. The quarter.** + +## 2. The field, as of July 2026 + +Five representative options, spanning the design space. All figures checked 2026-07-22. + +| Tool | License | ★ | Min. code | UI / CLI / server | Observability | Evaluation | +| --- | --- | ---: | --- | --- | --- | --- | +| LangChain + LangGraph | MIT | 142k / 38k | ~15 lines | — / — / Platform | LangSmith (SaaS) or Langfuse | LangSmith or Langfuse | +| CrewAI | MIT | 56k | ~55 lines, 5 files | — / scaffold / — | `verbose` logging | — | +| OpenAI Agents SDK | MIT | 28k | ~27 lines | — / — / — | OpenAI Dashboard | — | +| Google ADK | Apache-2.0 | 21k | ~8 lines | `adk web` / `adk run` / `adk api_server` | — | Built in, and deep | +| Dify | Modified Apache-2.0 | 150k | **0** | Yes / Yes / REST | — | — | +| **PenguinHarness** | Apache-2.0 | — | **0** | **Yes / Yes / Yes** | **Built in (Trace)** | **Built in** | + +Line counts come from each project's official quickstart and are not perfectly comparable. Blank cells mean *not documented in the sources we checked*, not *impossible*. + +One licensing note, since "open source" is doing heavy lifting in this market: Dify ships under a **modified** Apache 2.0 that forbids multi-tenant SaaS resale and forbids removing its branding. n8n, the most-starred project in the space at 197k, uses the Sustainable Use License and is not open source at all. PenguinHarness is plain Apache-2.0. + +## 3. The field already agrees that thin won + +The strongest arguments against heavy agent frameworks now come from the vendors themselves. + +Anthropic's engineering guidance, still their canonical reference: + +> "the most successful implementations weren't using complex frameworks or specialized libraries. Instead, they were building with simple, composable patterns." + +Microsoft's own Agent Framework documentation opens with a line most vendors would not print: + +> "If you can write a function to handle the task, do that instead of using an AI agent." + +And AutoGen — still the highest-starred multi-agent framework at 60k — now begins its README with: + +> "AutoGen is now in maintenance mode. It will not receive new features or enhancements and is community managed going forward." + +LangChain itself moved its legacy chains, retrievers and hub module into a separate `langchain-classic` package to keep the core "lean and focused." Meanwhile "harness" became the industry's word: within roughly two months, AWS renamed its agent repo to `harness-sdk`, Microsoft shipped a Harness tier in Agent Framework, and Anthropic published *"A harness for every task."* + +The category is not dying. It is admitting the abstractions were never the valuable part — which makes the assembly cost in section 1 even harder to justify. + +## 4. PenguinHarness: one install, and nothing to learn + +Our answer is not a thinner framework. It is removing the assembly step and then automating the tuning loop. + +### 4.1 The layers are already one product + +One install gives you all five rows of that first table, sharing one data directory and one message protocol: + +```bash +curl -fsSL https://penguin.ooo/install.sh | sh +penguin web # http://127.0.0.1:7364 — first login: admin / penguin-2026 +``` + +Multi-session chat, agent and skill management, model configuration, usage and cost statistics, **Trace observability**, and an **evaluation center** — in the box, wired together, nothing to subscribe to and nothing to self-host separately. Every request, tool call and approval decision is already recorded; a session restores completely from its trace. There is no tracing SDK to install because there is no seam to instrument across. + +### 4.2 Zero lines, not fewer lines + +```bash +penguin run -m "Analyze data.csv and summarize quarterly sales" +``` + +No project, no imports, no framework. The same engine drives the REPL (`penguin chat`), a headless server (`penguin server`) and the Web App. + +### 4.3 An agent builds your agent + +You describe what you want; an agent writes its `AGENTS.md`, installs the skills it needs, and hands you something that runs. One sentence produced a complete RAG application — ingestion, retrieval, cited sources, web UI — for **$0.02** of tokens on DeepSeek V4 Pro. The [runnable example](https://github.com/Prism-Shadow/penguin-harness/tree/main/examples/build-agent-with-agent) is an 82-line script that builds a new agent from a plain-language requirement and then runs it. + +This works because **agents are editable data, not hardcoded constants** — prompts, skills and configuration are plain files on disk. + +### 4.4 The tuning loop is automated too + +This is the part that answers section 1's last paragraph. Built-in skills for benchmark design, evaluation and optimization let the agent score its own output, locate where it lost points, and ship version N+1 — with a snapshot before every round and every request replayable in the trace view. + +On other stacks, *you* are the optimizer: you read the traces, you tune the prompts, you rerun the evals. Here that loop is the agent's job. **You do not have to learn to be good at it.** + +### 4.5 The controls are still there + +Every tool call gets exactly one approval decision in one of four modes — allow-all, deny-all, read-only, always-ask — and each decision is audited to the trace. It runs fully locally on as little as a single CPU, and reaches 1000+ models through any OpenAI-protocol endpoint. + +## 5. When not to use PenguinHarness + +A comparison where one option wins every row is an advertisement, not an analysis. Two cases where you should pick something else: + +- **Python shops.** Our SDK is TypeScript. The CLI and server are language-agnostic, but if your team works in Python and wants to subclass and extend these classes, most of the options above will fit better. +- **Deep cloud integration.** If you are already all-in on Azure, Microsoft Agent Framework is the path of least resistance; on Vertex, ADK is. + +## 6. The short version + +Building an agent stopped being the hard part. Assembling and learning the stack around it did not — and on the most popular option that means two libraries, an observability platform from a first or third party, an evaluation harness, and a human who becomes the optimization loop. + +PenguinHarness collapses those into one install, then hands the optimization loop to the agent. + +Not the smallest framework — **no framework, an agent to write the agent, and nothing left for you to learn.** + +--- + +- **Docs**: [Quickstart](https://penguin.ooo/docs/quickstart) · [Skills](https://penguin.ooo/docs/skills) · [Sessions & Traces](https://penguin.ooo/docs/sessions-and-traces) +- **Community**: [GitHub](https://github.com/Prism-Shadow/penguin-harness) · [Discord](https://discord.gg/eFHKqqcU3D) + +**Sources** — figures checked 2026-07-22: [LangChain v1 release notes](https://docs.langchain.com/oss/python/releases/langchain-v1) · [Langfuse](https://github.com/langfuse/langfuse) · [AutoGen README](https://github.com/microsoft/autogen) · [Microsoft Agent Framework](https://learn.microsoft.com/en-us/agent-framework/overview/) · [Google ADK](https://adk.dev/) · [CrewAI](https://docs.crewai.com/en/quickstart) · [OpenAI Agents SDK](https://openai.github.io/openai-agents-python/quickstart/) · [Dify LICENSE](https://github.com/langgenius/dify/blob/main/LICENSE) · [n8n LICENSE](https://github.com/n8n-io/n8n/blob/master/LICENSE.md) · [Anthropic, Building Effective AI Agents](https://www.anthropic.com/engineering/building-effective-agents) diff --git a/packages/landing/content/blog/easiest-way-to-build-ai-agents-2026.zh.md b/packages/landing/content/blog/easiest-way-to-build-ai-agents-2026.zh.md new file mode 100644 index 0000000..639546d --- /dev/null +++ b/packages/landing/content/blog/easiest-way-to-build-ai-agents-2026.zh.md @@ -0,0 +1,124 @@ +--- +title: "2026 年构建 AI Agent 最简单的方式" +date: 2026-07-22 +category: perspectives +excerpt: 今天写一个 Agent 只要十几行。成本没有消失,只是换了地方——挪到了它外面那一圈:构建、观测、评估分属两三家厂商的独立产品。本文算一算这笔学习成本,再说说另一条路:把它自动化掉,而不是老老实实付掉。 +--- + +问"构建 AI Agent 最简单的方式是什么",多数答案都在比代码行数。这个比法今天已经没什么意义了:主流工具包写十几行就能跑起一个可用的 Agent。 + +**成本没有消失,只是换了地方。** 它挪到了 Agent 外面那一圈:编排层、观测平台、评估体系。每一样都是独立的产品,各有各的概念、各有各的文档,甚至各有各的厂商。**写一个 Agent 是一下午的事,把这套栈学明白是一个季度的事。** + +这篇文章就来算这笔账,再说说怎么把它去掉,而不是老老实实付掉。 + +## 一、用 LangChain 做一个 Agent,代价到底是什么 + +LangChain 是这个领域用得最多的方案,也是多数团队的默认选项,拿它举例最公道。要把一个 Agent 从原型推到能上生产,你得拼出这么一套: + +| 层次 | 你要用的东西 | 出品方 | 你必须学会的东西 | +| --- | --- | --- | --- | +| 构建 | **LangChain** | LangChain Inc. | 工具、模型、`create_agent` | +| 编排 | **LangGraph** | LangChain Inc. | 节点、边、状态、检查点、interrupt | +| 观测 | **LangSmith** 或 **Langfuse** | LangChain Inc. / Langfuse | 接追踪 SDK 加托管平台,或者上 OpenTelemetry 加自建部署 | +| 评估 | LangSmith 评估或 Langfuse 评估 | 同上 | 数据集、评判器、实验配置 | +| 部署 | **LangGraph Platform** | LangChain Inc. | 又一套部署模型 | + +这五样单拿出来都是好东西,问题不在这儿。**问题在于它们是五样东西。** + +最难受的是"观测"这一行。它不是一个步骤,而是一道岔路。LangSmith 是 LangChain 自家的商业平台,原生集成,接入最省事,代价是你从此绑在一个托管 SaaS 上。[Langfuse](https://github.com/langfuse/langfuse) 是开源的那条路:除企业版目录外采用 MIT 协议,不绑定框架,可以用 Docker 或 Kubernetes 自建,团队已在 2026 年 1 月加入 ClickHouse。它确实做得很好,但它同时也意味着**多一家厂商、多一套数据模型,以及一个从此要你自己运维的服务**。 + +于是,在这个 Agent 于生产环境里做成第一件有用的事之前,团队里已经有人学完了两个库、接好了追踪 SDK、订阅或自建了一个观测平台,还手工攒出了一套评估数据集。等到 Agent 表现不好,还是这个人去读 trace、改提示词。**因为这套栈里没有任何一环会替你做这件事。** + +**这才是"2026 年构建 Agent 有多难"的真实答案。不是那十几行,是那一个季度。** + +## 二、2026 年 7 月的战场实况 + +五个覆盖设计空间的代表。数据均于 2026-07-22 核对。 + +| 工具 | 协议 | ★ | 最少代码 | UI / CLI / 服务 | 观测 | 评估 | +| --- | --- | ---: | --- | --- | --- | --- | +| LangChain + LangGraph | MIT | 142k / 38k | 约 15 行 | — / — / Platform | LangSmith 或 Langfuse | LangSmith 或 Langfuse | +| CrewAI | MIT | 56k | 5 个文件约 55 行 | — / 脚手架 / — | `verbose` 日志 | — | +| OpenAI Agents SDK | MIT | 28k | 约 27 行 | — / — / — | 官方 Dashboard | — | +| Google ADK | Apache-2.0 | 21k | 约 8 行 | `adk web` / `adk run` / `adk api_server` | — | 内置,且做得很深 | +| Dify | 修改版 Apache-2.0 | 150k | **0** | 有 / 有 / REST | — | — | +| **PenguinHarness** | Apache-2.0 | — | **0** | **有 / 有 / 有** | **内置(Trace)** | **内置** | + +代码行数取自各项目官方 quickstart,彼此并不完全可比。空白格的意思是**我们查到的资料里没有写**,不是"做不到"。 + +关于协议还得补一句,因为"开源"这个词在这个市场里被用得太宽。Dify 用的是**修改版** Apache 2.0,禁止多租户 SaaS 转售,也禁止把前端的品牌标识去掉;n8n 是这个领域星标最高的项目,197k,但它用的是 Sustainable Use License,**根本算不上开源**。PenguinHarness 是标准 Apache-2.0。 + +## 三、这个领域自己已经承认:薄的那一方赢了 + +今天反对重型 Agent 框架最有力的说法,恰恰来自厂商自己。 + +Anthropic 的工程指南至今仍是他们的权威参考,其中写道:**最成功的落地案例都没有用复杂框架或专用库,而是用简单、可组合的模式搭起来的**;这类框架往往多加一层抽象,把底层的提示词和响应挡在后面,反而更难调试。 + +微软自家 Agent Framework 文档的开篇,摆着一句多数厂商不会印出来的话:**一个函数能搞定的事,就写函数,别上 AI Agent。** + +而 AutoGen,多智能体框架里星标依然最高的那个(60k),现在 README 第一段就写着:**本项目已进入维护模式,不再接受新特性或增强,后续由社区管理。** + +LangChain 自己也把遗留的 chain、retriever 和 hub 模块挪进了独立的 `langchain-classic` 包,好让核心"精简、专注"。与此同时,"harness"成了行业通用词:两个月左右的时间里,AWS 把 Agent 仓库改名叫 `harness-sdk`,微软在 Agent Framework 里加了一层 Harness,Anthropic 发了一篇《A harness for every task》。 + +这个品类没有死,它只是承认了一件事:**真正有价值的从来不是那些抽象**。而这也让第一节那笔拼装成本更难自圆其说。 + +## 四、PenguinHarness:装一次,然后不用再学 + +我们的答案不是"做一个更薄的框架",而是**把拼装这一步取消掉,再把调优那个循环也自动化掉**。 + +### 4.1 那几层,本来就该是同一个产品 + +装一次,第一张表里的五行就都有了,而且共用同一份数据目录、同一套消息协议: + +```bash +curl -fsSL https://penguin.ooo/install.sh | sh +penguin web # http://127.0.0.1:7364 — 首次登录:admin / penguin-2026 +``` + +多会话对话、Agent 与技能管理、模型配置、用量与成本统计、**Trace 可观测**、**评测中心**,开箱即有,彼此已经打通,**不用订阅什么,也不用另外自建什么**。每个请求、每次工具调用、每个审批决策都已经记下来了,会话可以从 Trace 完整恢复。**这里没有追踪 SDK 要接,因为根本不存在需要跨越的接缝。** + +### 4.2 是零行,不是"更少的行" + +```bash +penguin run -m "分析 data.csv 并总结季度销售情况" +``` + +不用建工程,不用写 import,也没有框架要学。同一套引擎还驱动着 REPL(`penguin chat`)、无头服务(`penguin server`)和 Web App。 + +### 4.3 让 Agent 来写你的 Agent + +你把想要的东西描述出来,剩下的交给一个 Agent:它来写目标 Agent 的 `AGENTS.md`,装好需要的技能,最后把一个能跑的成品交给你。我们用一句话生成过一个完整的 RAG 应用——文档摄取、检索、带出处的引用、Web 界面一应俱全,在 DeepSeek V4 Pro 上的 token 成本是 **$0.02**。[可运行示例](https://github.com/Prism-Shadow/penguin-harness/tree/main/examples/build-agent-with-agent)是一个 82 行的脚本:从一句自然语言需求造出新 Agent,然后跑起来验证它。 + +这件事能成立,靠的是一条设计原则:**Agent 是可编辑的数据,不是硬编码的常量**。提示词、技能、配置,全都是磁盘上的普通文件。 + +### 4.4 连调优的循环也自动化了 + +这一节正面回应第一节结尾那个问题。内置的基准设计、评测与优化技能,让 Agent 自己给输出打分、找出失分在哪,然后发布第 N+1 版。每一轮开始前留快照,每个请求都能在 Trace 视图里回放。 + +在别的技术栈上,**那个优化器就是你本人**:你读 trace,你改提示词,你重跑评估。**在这里,这个循环归 Agent 管,你不必再把自己练成这方面的老手。** + +### 4.5 管控并没有因此消失 + +每次工具调用恰好触发一次审批决策,四种模式可选:全部允许、全部拒绝、只读放行、每次询问,每个决策都写进 Trace 留档。整套东西完全本地运行,单核 CPU 也带得动;通过任意 OpenAI 协议端点接得上 1000+ 模型。 + +## 五、什么时候**不该**用 PenguinHarness + +一份每一行都自己赢的对比是广告,不是分析。有两种情况,你该选别的: + +- **团队写 Python。** 我们的 SDK 是 TypeScript。CLI 和服务端与语言无关,但如果你的团队习惯在 Python 里继承、扩展这些类,上表里的多数选项都会更顺手。 +- **深度绑定某一家云。** 已经全面押注 Azure 的话,Microsoft Agent Framework 阻力最小;如果是 Vertex,那就是 ADK。 + +## 六、小结 + +**难的早就不是构建 Agent 本身,而是把它周围那套栈拼起来、学明白。** 在最流行的那个选项上,这意味着两个库、一个自家或第三方的观测平台、一套评估体系,外加一个人肉充当的优化循环。 + +PenguinHarness 把这些收进一次安装,然后**把优化循环交给 Agent 自己**。 + +我们做的不是最小的框架。**是没有框架,有一个替你写 Agent 的 Agent,以及一份不再需要你去学的清单。** + +--- + +- **文档**:[快速开始](https://penguin.ooo/docs/quickstart) · [Skills](https://penguin.ooo/docs/skills) · [会话与 Trace](https://penguin.ooo/docs/sessions-and-traces) +- **社区**:[GitHub](https://github.com/Prism-Shadow/penguin-harness) · [Discord](https://discord.gg/eFHKqqcU3D) + +**参考来源**(数据均于 2026-07-22 核对):[LangChain v1 发布说明](https://docs.langchain.com/oss/python/releases/langchain-v1) · [Langfuse](https://github.com/langfuse/langfuse) · [AutoGen README](https://github.com/microsoft/autogen) · [Microsoft Agent Framework](https://learn.microsoft.com/en-us/agent-framework/overview/) · [Google ADK](https://adk.dev/) · [CrewAI](https://docs.crewai.com/en/quickstart) · [OpenAI Agents SDK](https://openai.github.io/openai-agents-python/quickstart/) · [Dify LICENSE](https://github.com/langgenius/dify/blob/main/LICENSE) · [n8n LICENSE](https://github.com/n8n-io/n8n/blob/master/LICENSE.md) · [Anthropic, Building Effective AI Agents](https://www.anthropic.com/engineering/building-effective-agents) diff --git a/packages/landing/content/blog/simple-harness-is-all-you-need.en.md b/packages/landing/content/blog/simple-harness-is-all-you-need.en.md new file mode 100644 index 0000000..d1e6b3e --- /dev/null +++ b/packages/landing/content/blog/simple-harness-is-all-you-need.en.md @@ -0,0 +1,117 @@ +--- +title: "Simple Harness Is All You Need" +date: 2026-07-22 +category: perspectives +excerpt: Databricks benchmarked coding agents against real pull requests from its own multi-million-line codebase. The best score on the entire board did not belong to the most capable harness — it belonged to the simplest one, at roughly half the cost. Here is why context discipline beats feature count, and how PenguinHarness is built around that bet. +--- + +You would expect a feature-rich agent harness to beat a minimal one. More tools, more context, more scaffolding, better decisions. That is the intuition the entire category was built on. + +Databricks tested it against real work — roughly a hundred pull requests pulled from their own multi-million-line production monorepo, graded by restoring the held-out tests and running them. Here is the result: + +![Databricks' Pareto chart: pass-rate against cost per task. The frontier is dominated by the minimal Pi harness, and the highest score on the chart is Opus 4.8 on Pi](/blog-assets/databricks-pareto.png) + +_Pass-rate against cost per task. Red points form the Pareto frontier. Source: [Databricks](https://www.databricks.com/blog/benchmarking-coding-agents-databricks-multi-million-line-codebase)._ + +Read the top of that chart carefully, because it is the opposite of what the intuition predicts. **The single highest pass-rate — about 90% — belongs to Opus 4.8 running on [Pi](https://github.com/earendil-works/pi), a harness whose entire core is read, write, edit, and a shell.** The same model on Claude Code at maximum effort scores slightly lower, at roughly twice the cost per task. And of the points on the Pareto frontier, most are Pi. + +The minimal harness did not merely hold its own on price. **At the top of the board, it won.** + +Databricks were careful not to overclaim, and so are we: their stated lesson is not that one harness is always cheaper or that vendor harnesses are worse. The chart backs that caution up — Opus on Pi at `max` effort lands around 81%, well below Claude Code at comparable spend. Simplicity is not a guarantee. But the direction is unmistakable, and their explanation of the mechanism is a single sentence: + +> "Pi sent about 3x less context per turn. It managed context better, keeping a tighter working set and finishing the tasks in fewer runs." + +One more detail worth noting, since it is rarer than it should be: they refused to grade with a model, on the grounds that doing so "rewards sounding right over being right." + +## 1. A harness is an information budget + +A model is a function behind an API. It receives a system prompt, tool definitions, and a message history; it returns text and tool calls. That contract is fixed and public. **Everything else — every piece of software deciding what goes into that request — is the harness.** + +Which means a harness only ever makes one kind of decision: what occupies the finite context window. It is not a feature list. It is a budget, spent on the model's behalf, on every single turn. + +That reframing explains the chart immediately. Two harnesses calling the same model are not running different intelligence. They are running different budgets — and the one that spent less scored higher. + +## 2. Where the weight accumulates + +Context bloat is never one bad decision. It is four defensible ones, compounding every turn. + +**The tool surface.** Every tool costs its name, description, and full JSON Schema in *every* request. Thirty tools is not thirty conveniences — it is a permanent tax plus a wider decision space to get lost in. And the marginal ones usually re-implement something a shell already does. + +**Tool output.** A dependency install dumps thousands of lines. That output is not billed once; it becomes history and gets resent every subsequent turn. Uncapped output is the fastest way to turn a cheap task into an expensive one. + +**The system prompt.** Long behavioral rulebooks encode judgment the model already has. Telling a frontier model not to hardcode credentials spends tokens restating its training. Worse, over-specification implies the model is not trusted to reason — which makes it hesitant precisely in the cases the rules failed to anticipate. + +**Per-turn injections.** Environment snapshots, status blocks, re-sent config files, stapled onto every message. Individually tiny, structurally permanent. + +None of these are wrong ideas. They are unpriced ones. + +## 3. How PenguinHarness is built + +We made this bet before the benchmark existed, and it is visible in the source rather than the marketing. Every number below is checkable in the repo. + +**Six tools, and no file tools at all.** PenguinHarness ships [six built-in tools](https://penguin.ooo/docs/tools); any session sees five, since the two image tools are mutually exclusive by model class. + +| Tool | Purpose | +| --- | --- | +| `exec_command` | Run a shell command via `bash -lc`, streaming stdout/stderr | +| `input_command` | Drive a running command: write stdin, send Ctrl-C, poll output | +| `run_subagent` / `input_subagent` | Delegate a subtask to a child agent, then poll or follow up | +| `read_image` / `describe_image` | Return an image, or have a vision model describe it in text | + +There is no read tool, no write tool, no edit tool, no glob, no grep. Reading, writing, editing and searching all go through the shell, because the shell already does them and the model already knows how. Where a four-tool minimal core spends read, write and edit on the filesystem, **we spend one**. We are not claiming the smallest absolute tool count — Pi's core is tighter by one — but the smallest schema surface for what agents actually do all day. + +**A 72-line system prompt.** The default template is 72 lines, about 6,600 characters before substitution ([source](https://github.com/Prism-Shadow/penguin-harness/blob/main/packages/core/src/state/default-config.ts)). Role, success criteria, constraints, stop rules, filesystem layout, a short list of suggested workflows — then it stops. + +**Output capped by default.** Every tool call truncates at 16,000 characters, enforced centrally by the Environment. Exit codes are appended *outside* the truncation window, so the line telling the model whether the command succeeded survives even when the middle is cut. + +**Skills that cost nothing until used.** There is no skill tool. The prompt carries only each skill's name and one-line description; the body is read on demand with an ordinary shell command. A skill you do not use costs you a single line. + +**Compaction into a clean context.** Past 128,000 tokens, the engine summarizes into a `` and continues in a *fresh* context rather than appending to a swollen history — so one trace file is always exactly one model context. + +**A clean message protocol.** No environment metadata stapled to user messages. The model receives the conversation: user turns, assistant turns, tool results. + +## 4. Why less wins + +The intuition that more context means better decisions is not stupid. It is wrong at the margin, for two reasons. + +**Attention is a fixed budget that gets divided.** Self-attention weighs every token against every other. Grow a request from 20K to 60K tokens and the decisive parts — the actual error, the actual constraint — hold a smaller share. Five rules that are followed beat fifty that compete; five tools chosen correctly beat thirty that widen the search. + +**Redundant instruction costs more than tokens.** Rules restating training data do not add capability, they add the suggestion that judgment is unwanted. The failure mode is not rule-breaking — it is freezing on the case the rules did not cover. + +There is a third, practical reason: **portability**. Post-training binds models to the *protocol*, not to a harness. Every serious model trains on the same function-calling contract. From the model's side, a lean harness is just a standard request that happens to be short — which is why several vendors' models plus open-weight GLM all did well through the same minimal wrapper, and why lean designs keep working when you switch models. For a project whose proposition is 1000+ models behind one interface, that is the foundation. + +It is also why our own numbers land where they do. On complex data analysis, PenguinHarness on DeepSeek V4 Pro took the highest accuracy of the three harnesses we tested (66.67% against 53.33% for both) at **$0.55** against Claude Code's **$38.48** — roughly 1/70 the bill. On coding we tie Codex at 71.25% and trail Claude Code's 86.25%, but the suite cost **$3.81** against **$220.08** and **$146.97**. We do not claim to beat a frontier model on every axis. We claim the quality gap is one to two orders of magnitude smaller than the price gap. + +## 5. What minimalism must not cost + +Here is where we part company with minimalism as a philosophy. + +Stripping a harness down is easy if you also strip out what makes an autonomous process safe on a real machine. Pi's own README is upfront that it *"does not include a built-in permission system"* and suggests containers instead. Reasonable for a personal CLI. Not a trade an enterprise can make. + +We treat safety and observability as load-bearing, and they are cheap in context precisely because they live in the runtime rather than the prompt: + +- **Every tool call gets exactly one approval decision**, in one of four modes — allow-all, deny-all, read-only, always-ask. The SDK denies by default when no approver is supplied, so nothing runs unattended by accident. +- **Every decision is audited** to the Trace as an `approval_decision` event. +- **Tools never throw into the engine.** Failures become tool output the model reads and reacts to — which is also why a lean prompt is safe: the environment reports its own errors clearly enough that the prompt does not have to anticipate them. + +Zero extra tokens per turn, fully auditable. Discipline in the context window; rigor in the runtime. + +## 6. The takeaway + +The result worth internalizing is not that simple harnesses are cheaper. It is that at the top of a real benchmark, on real pull requests, **the simplest harness produced the best result** — and did it by sending less. + +If you are building agents, the audit is short. How many tools does your model see, and how many re-implement a shell? What is your hard cap on tool output? How many lines of your system prompt teach the model things it learned in pre-training? What gets injected into every message? + +Every answer is a line item, charged on every turn, for the life of the task. + +```bash +curl -fsSL https://penguin.ooo/install.sh | sh +penguin web +``` + +--- + +- **Read the internals**: [Tools & Approval](https://penguin.ooo/docs/tools) · [The Agent Loop](https://penguin.ooo/docs/agent-loop) · [Skills](https://penguin.ooo/docs/skills) +- **Come argue with us**: [GitHub](https://github.com/Prism-Shadow/penguin-harness) · [Discord](https://discord.gg/eFHKqqcU3D) + +**Sources**: [Databricks — Benchmarking Coding Agents on Databricks' Multi-Million Line Codebase](https://www.databricks.com/blog/benchmarking-coding-agents-databricks-multi-million-line-codebase) · [Pi (earendil-works/pi)](https://github.com/earendil-works/pi) · [SaladDay, "Less is More"](https://x.com/Salad95238547/status/2079508549382644194) diff --git a/packages/landing/content/blog/simple-harness-is-all-you-need.zh.md b/packages/landing/content/blog/simple-harness-is-all-you-need.zh.md new file mode 100644 index 0000000..79c91ff --- /dev/null +++ b/packages/landing/content/blog/simple-harness-is-all-you-need.zh.md @@ -0,0 +1,122 @@ +--- +title: "精简的 Harness 就够了" +date: 2026-07-22 +category: perspectives +excerpt: Databricks 拿自家百万行代码库里的真实 PR,评测了多个 coding agent harness。全场最高分不属于功能最全的那个 harness,而属于最简单的那个,成本还只有一半左右。本文讲清楚上下文纪律为什么胜过功能数量,以及 PenguinHarness 怎么把这个判断写进了代码。 +--- + +按直觉想,功能丰富的 Agent harness 应该赢过精简的那个:工具更多、上下文更全、脚手架更厚,决策自然更好。整个品类就是建立在这个直觉上的。 + +Databricks 拿真实工作检验了它——从自家百万行的生产级 monorepo 里挑出约一百个 Pull Request,把此前抽走的测试恢复回去跑一遍来判分。结果是这样的: + +![Databricks 的 Pareto 图:任务通过率对单任务成本。前沿几乎被精简的 Pi harness 占满,全图最高分是跑在 Pi 上的 Opus 4.8](/blog-assets/databricks-pareto.png) + +_横轴是单任务成本,纵轴是整体通过率,红点构成 Pareto 前沿。图片来源:[Databricks](https://www.databricks.com/blog/benchmarking-coding-agents-databricks-multi-million-line-codebase)。_ + +请仔细看这张图的顶部,因为那里的结论和直觉完全相反。**全场最高的通过率,约 90%,属于跑在 [Pi](https://github.com/earendil-works/pi) 上的 Opus 4.8**——而 Pi 的整个内核只有读、写、编辑,加一个 shell。同一个模型跑在 Claude Code 上、开到最高档,分数略低,单任务成本却是它的两倍左右。而 Pareto 前沿上的点,大部分都是 Pi。 + +精简的那个 harness 不只是在价格上守住了阵地。**在榜首,它赢了。** + +Databricks 自己很谨慎,我们也该同样谨慎:他们明确说过,这里的教训**不是**某个 harness 永远更便宜,也**不是**厂商自家的 harness 更差。这张图本身就佐证了这份谨慎——Opus 跑在 Pi 上开 `max` 档时只有 81% 左右,明显低于同等花费下的 Claude Code。**精简不是保票。** 但方向不会看错,而他们对机制的解释只有一句话: + +> Pi 每轮发送的上下文大约少三倍。它把工作集管得更紧,用更少的轮次完成了任务。 + +还有一个细节值得一提,因为这么做的人比应该有的少得多:他们拒绝用模型来判分,理由是那样会奖励"听起来对",而不是"真的对"。 + +## 一、Harness 的本质是一份上下文预算 + +模型是 API 背后的一个函数。它接收 system prompt、工具定义、消息历史,返回文本和工具调用。这份契约是固定的,也是公开的。**除此之外的一切——所有决定"这个请求里放什么"的软件——就是 harness。** + +也就是说,harness 从头到尾只做一类决策:**有限的上下文窗口,究竟被什么占着**。它不是一张功能清单,而是一份替模型花出去的预算,每一轮都要重花一次。 + +换了这个视角,那张图立刻就讲得通了:两个 harness 调的是同一个模型,跑的不是不同的智能,而是不同的预算——**而花得更少的那个,分数更高。** + +## 二、重量到底堆在哪里 + +上下文膨胀从来不是一个糟糕的决定,而是四个各自都说得通的决定,在每一轮里复利叠加。 + +**工具面。** 每个工具在**每一次**请求里都要付出名字、描述和完整 JSON Schema 的代价。三十个工具不等于三十份便利,而是一笔常驻的税,外加一个更大的、够模型迷路的决策空间。而那些边际工具,往往正是在重新实现 shell 早就有的能力。 + +**工具输出。** 一次依赖安装吐出几千行。这些输出不是只计费一次,它们会变成历史,在之后的每一轮里被重新发送。**不设上限的工具输出,是把便宜任务变贵最快的途径。** + +**System prompt。** 冗长的行为守则,编码的是模型本来就有的判断力。告诉一个前沿模型别硬编码密钥,等于花 token 复述它的训练数据。更微妙的是,规定得太细本身就在暗示模型的判断不被信任,于是碰上规则没覆盖的情形,它反而更容易犹豫——而那恰恰是最需要它自己拿主意的时候。 + +**每轮注入。** 环境快照、状态块、被反复重发的配置文件,统统钉在每条消息上。单看微不足道,结构上却是永久的。 + +这些都不是错的想法,只是**没被定价**的想法。 + +## 三、PenguinHarness 是怎么做的 + +在这份评测出现之前,我们就下了这个赌注,而且它写在源码里,不在宣传页上。下面每个数字都能在仓库里核对。 + +**六个工具,而且完全没有文件工具。** PenguinHarness 内置[六个工具](https://penguin.ooo/docs/tools),任一会话实际只看到五个——两个图像工具按模型类别互斥。 + +| 工具 | 作用 | +| --- | --- | +| `exec_command` | 通过 `bash -lc` 执行 shell 命令,流式返回 stdout/stderr | +| `input_command` | 驱动运行中的命令:写 stdin、发送 Ctrl-C、轮询输出 | +| `run_subagent` / `input_subagent` | 把子任务委派给子 Agent,之后轮询或追加指令 | +| `read_image` / `describe_image` | 返回图像,或交给视觉模型转成文字描述 | + +没有 read 工具,没有 write 工具,没有 edit 工具,没有 glob,也没有 grep。读、写、编辑、搜索全部走 shell,因为 shell 本来就能做这些,模型本来就会用它。当一个四工具的最小内核把 read、write、edit 三个名额花在文件系统上时,**我们只花一个**。我们不宣称绝对工具数最少(论内核,Pi 比我们还紧一个),我们宣称的是:**在"Agent 每天真正在做的事"上,我们的 schema 面积最小。** + +**72 行的 System Prompt。** 默认模板在变量替换前是 72 行、约 6,600 字符([源码](https://github.com/Prism-Shadow/penguin-harness/blob/main/packages/core/src/state/default-config.ts))。角色、成功标准、约束、停止规则、文件系统布局,外加一小段建议工作流,然后就结束了。 + +**输出上限是默认行为。** 每次工具调用截断在 16,000 字符,由 Environment 统一执行。退出码被追加在**截断窗口之外**,所以哪怕输出中段被砍掉,那条告诉模型"命令到底成没成"的信息依然还在。 + +**用不到就不花钱的 Skills。** 系统里没有 skill 工具。Prompt 只带上每个 skill 的名字和一行描述,正文等到需要时用一条普通 shell 命令读进来。这次用不到的 skill,只花你一行的代价。 + +**压缩之后是干净的上下文。** 超过 128,000 tokens 后,引擎把历史摘要成 ``,在一个**全新的**上下文里继续,而不是接在一段已经臃肿的历史后面——于是一个 trace 文件恰好对应一个模型上下文。 + +**干净的消息协议。** 不把环境元信息钉在用户消息上。模型收到的就是对话本身:用户轮、助手轮、工具结果。 + +## 四、为什么"更少"反而赢 + +"上下文越多,决策越好"这个直觉并不蠢,只是在边际上不成立,原因有两个。 + +**注意力是固定预算,而且会被摊薄。** Self-attention 让每个 token 都要和其余所有 token 算权重。当请求从 20K tokens 涨到 60K,真正起决定作用的那部分——那条实际的报错、用户实际的约束——占的份额就变小了。**五条被执行到位的规则,胜过五十条互相抢注意力的规则;五个被正确选中的工具,胜过三十个把搜索空间撑大的工具。** + +**冗余指令的代价不止是 token。** 复述训练数据的规则不增加能力,只增加"这里不需要你判断"的暗示。它的失效模式不是模型违反规则,而是**模型在规则没覆盖的场景下卡住**。 + +还有第三个更实际的理由:**可移植性**。后训练绑定的是**协议**,不是 harness。所有严肃的模型都在同一套 function calling 契约上训练。从模型的角度看,一个精简的 harness 不过是一个恰好比较短的标准请求——这就解释了为什么多家厂商的模型、加上开放权重的 GLM,在同一个精简 harness 下都表现不错,也说明精简的设计最有可能在你换模型之后依然好用。对于一个价值主张是"一套接口接 1000+ 模型"的项目,这是地基。 + +我们自己的数字落在那个位置,也是同一个道理。复杂数据分析上,PenguinHarness 搭配 DeepSeek V4 Pro 拿到了三者中最高的准确率(66.67%,两个对手各 53.33%),花费 **$0.55**,Claude Code 是 **$38.48**,账单约为其 1/70。编程题上,我们和 Codex 以 71.25% 打平,落后于 Claude Code 的 86.25%,但整套题我们花了 **$3.81**,它们分别是 **$220.08** 和 **$146.97**。我们不宣称在每个维度上都赢过前沿模型,我们宣称的是:**效果的差距,比价格的差距小一到两个数量级。** + +## 五、精简不该牺牲什么 + +这里是我们和"极简主义"分道扬镳的地方。 + +要把 harness 削薄其实很容易,前提是你连"让一个自主进程敢在真机上跑"的那部分也一并砍掉。Pi 的 README 就坦率写明它**不包含内置权限系统**,并建议改用容器隔离。对个人 CLI 来说这是合理取舍,对企业不是。 + +我们把安全和可观测当成承重结构,而它们在上下文里几乎不花钱,恰恰因为**它们活在运行时,不活在 prompt 里**: + +- **每次工具调用恰好触发一次审批决策**,四种模式:全部允许、全部拒绝、只读放行、每次询问。SDK 在没有注入审批回调时**默认拒绝**,不会有东西在无人值守时意外跑起来; +- **每个决策都以 `approval_decision` 事件写入 Trace**,形成完整审计记录; +- **工具永远不向引擎抛异常**。失败会收敛成模型读得懂、也能据此反应的工具输出——这也正是精简 prompt 依然安全的原因:**环境把自己的错误讲清楚了,prompt 就不必去替它预判。** + +每轮零额外 token,同时完全可审计。**上下文窗口里讲纪律,运行时里讲严谨。** + +## 六、结论 + +值得记住的结论不是"精简的 harness 更便宜",而是:在一套基于真实 Pull Request 的评测里,**最简单的那个 harness 拿到了最好的成绩**——靠的是发得更少。 + +如果你在构建 Agent,自检清单很短: + +- 你的模型看到多少个工具?其中多少个在重新实现 shell? +- 你的工具输出硬上限是多少? +- 你的 system prompt 里,有多少行在教模型它预训练时就学会的事? +- 每条消息里到底被注入了什么? + +每一个答案,都是一个**按轮计费、贯穿整个任务生命周期**的成本项。 + +```bash +curl -fsSL https://penguin.ooo/install.sh | sh +penguin web +``` + +--- + +- **读实现**:[工具与审批](https://penguin.ooo/docs/tools) · [Agent Loop](https://penguin.ooo/docs/agent-loop) · [Skills](https://penguin.ooo/docs/skills) +- **来讨论**:[GitHub](https://github.com/Prism-Shadow/penguin-harness) · [Discord](https://discord.gg/eFHKqqcU3D) + +**参考来源**:[Databricks — Benchmarking Coding Agents on Databricks' Multi-Million Line Codebase](https://www.databricks.com/blog/benchmarking-coding-agents-databricks-multi-million-line-codebase) · [Pi (earendil-works/pi)](https://github.com/earendil-works/pi) · [SaladDay《Less is More》](https://x.com/Salad95238547/status/2079508549382644194) diff --git a/packages/landing/public/blog-assets/databricks-pareto.png b/packages/landing/public/blog-assets/databricks-pareto.png new file mode 100644 index 0000000000000000000000000000000000000000..80be831a6dea8cacd9dad53e9f420374a5705b50 GIT binary patch literal 91406 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

nPc`&K?4S8)HaaB{PrbdWa;?m}1{FuBZtv_cX0r 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

}_ZQm-`oKM6kB z$?v@{QU9kp6I6?1`q|qnr0HI6^sQuFPm>z6(BO-E0A~N6!Tvvm5da8`|40ZZ2>JiZ zpFrnXhi@ke`5hy#MqiB;{{2^)^6~8Rv|ZMIrm_>sEScH|qIgtMsSD$LkCXq?0n}-= z%bMBr)J2@}<#}BmHaVqzrfs)hWl2RL|I&WQ?!w@A7IpLC{0dBQp~8)+L#`>d&vC3; zYkl|GSoO6Qr7CONcO93t<6{h8t>&MO9CyV=4p{DNKmFv?tm5|M=s0Mm!^62t=ZVc6 zCht@x{)xwj$9XbI0spI+>wap2>DHl%gkGge7YW7CJK&9)nlLcSQ|ETM zF?P~2hqn%~l?wA-N9LNy^fSMGdY;tWpwr_twLB-Cl47mzrQbb#6F|KhcO$gJ>~pZw z?2^ZKI1_}M59+Y-oNV(7QD>J_d{Qiq2u`K`-Q9M$>m_!wDM64mMRNP&yKfvk~+P5kUyDH*-C{7&(U~I%tNbvdWC4ebz`TL%D}wc z^E1PeEuRL~%7bmDWcs!RL`3|*YZT0K9B48hekhN^& zFOfm+igo4G+gU{DkEOf!lP0|Q(<(ZONU7-V%)tgW1l>n90?`8I@Rc{j4>mMY3=T5uXVe!Wb&Js%?8@p5hvB~&kN~31G zN)KPY9?xuP>{GtNZA&0Ip%kIC(vriDx_zFTI+xO#_{9BJenwQ)#TS?_#Jg0@yL8ip zzY2V#+!Q9N?gC1Lxsa#KTt+HOSOqfsg`KvTv zUIyZHuBm>GN{V*ZA;Csr^H6=CW51Vg{{DyxjbQC1{6)mfE}PEE-11&Np#(Y^llYT1HfF|N4>}@<}?x+mdy^%&pw*_eV}=OJIBG^%|#hn&u6G zFS}7_!ZL5*hR=ivA+(V}S`ndO+IV($Y{XvtOFSke@J|*|zUPo2YJJW~^OzPOdp$|O zX&)Ud10q^GYp|Twk?rxfU^yrXpW*Q?2UIzmuYW$oh&) zJN}(-&Wo1^5{3LK(?%`WqK zaG`4JT|AH|fhusL%V)E!i4iozlg~uI?)GQpJ3WQ(fq*Hs=>SDa?_V0}SdaQ0&w-Ts3T;u2I|5>zA}BlL5)ow20a2_e9U6vVhym|5BV z%~{usrbYEB+6nZgU>`~1GSKjGtk_i#i^psXi8y+(!=NpW+@r*xzDTJOR7FYjI|h; zqRlU3;>=PiSpbfPd_M`yf%_c$={*K>|yAgCuQ~iG3 zAzFKFxVTW@glSJ-mqj6&7t|f~Sbmy3?3=Yu5;U32WGRoY z94mHyQ={CpW4Xtej*)dRTg{imP8R-{ljOOUf|Qjy9*C;FOvnb!30$rzY^ekV(U21oT|RsPlH0||1W*Mk;?PgS!Yh{lG;2bHL5bUz z@`ER_hPz96f|vu^Wza7zt&&wM7X^LSk82>G ztiv(Nb!ZS(&X`)}ud>k=an(w)P3j1DxJWw0Cdp~6O_pCXdtWR_00-Uet`@$>zFbGq zAsNj>KWw?$_Z)0_(WtX#H{rC-Ap_G!rY{E5R?CoDnKJrjM6F7y5-|DmdR{qp&Ma|aBcixsHy zq`Qj4pN1pMIrUeCU_G{E5S7vr&~3EadGc=rPWwc%-EX{-8X-|!nK)Odv-<)g3-c*r z-WQY=!88da?*uuOB^P~sD`&z`A#QT>9_e8rFl(f+SJ$GK$Qlybx^=xi>s#pkoAnsi zEWFteUEr|n)(X+b!byfIxSE0OrCWc7 zRLMWNi1G)c6R>aNeWppmPUrRlfIBo$!2bqpjdi@Qs6J%6qQBBY*KQ4q>O0aa%_X#Y zqilGQ=$xRM$bZHbA`FWiR~bfLWY!Ucs)M8LKCtumwqR|4KTPJ<@_c0MqV@cAMXwl+ zPN9XuF|0GAoe{h{y{M+|Te)zi@_BMy*Yw4bV;GZy1~~ek%A(7{d>5_ya8b<+CEd3u zGG~}y=sQqv{dUn`k0-|8Y3ctpA%-dvJWDUbmS#i9oP$L1H336&Eh?%v3@zP#voA}9 zFOuMd4ti7Wx-I#L#%fQS0e_nny|65*pL0Ts&&#B&d?C|H?wiH7$6*S=E$^}x*I1#e z+X1A4k=9iloWfYqWiRgEb~${3jCtE~i_VKV1XpT!qgs}q$ci(+Z2prc*zi&Pob$Tk zt>ZFZa9WWuj$;hV-j0tGx<7O3TJu6t?naATwy`bRlU1)1b2LWJmoDh24xi&aZ97`JKoKKt!^Cwvu!~exgNL)e1q?J*2xsyy z{i>1#vtEf^Sji4}EomDQeDEa_f@nL$^^dms#X}b4Vj0Qom??JVOR=%$g6Ywh4!itE zx9n}xB^%U>~mJB5XfE- z0>({O=cC16E;u2Tr@vEVK9&5v#g*lGyg(IVYTr~|MLz9qjZE>)n0!wORb0*=3d%SQ zv;&$rtL(m_wqkU?6orZmKMKWDK(Z8Sc9)_@MozSj+=&!Z-0FE(f5*kTvkovAXT=F7 zY`zyGH@jSA0bf&+=Ypsh@T*E>a2Q5h+tqFJ1|uXLvEm!W)(MU4lx#>88KIBWdX(JB z*ZP1E6q_4AtCU z3YWLxfv>1g$~NzAN+QX@!+m|X`KcLj9P}8@#C6<6$8#s+2dLY$Jh9b4(x-xCaGybI#ldtJ?#uNPa+%yv&0 z{f_M(jTlljXB04Hoy`>O-eC|NoF_4%7=u&-wR{2T`7f-R!tMv2RT@}*TjeE~{s+v6 zHgoMlLMrXPc@sF667a?^FYBD64ZhqNQ<3!E4BfW?2bNYw z#E5>MhFkVc;ADBoC&?Y~ISiruSqUb+yO_9*?1RE!=vFvb=X^mezv(WQbXFl;o3g_@ z_2B5)eW>7ii%LPx_9zF)U_ADZqRqJ$CtpXw9ixV-g807$PP>&mh|o>G%!Bpee=sZuBwV>t7QAp?;7AN1Sg5$V$@KoorryT^A7UK*t|?JVJ?@6W@xZbSe*;b5;kIKG^i z)R)FS1dSK@#;V*}WmYO~C>n+mV+1 z%&vzRzqVqCDmm{1K)(4eCR&jsB;a@@zYr4BQjD)1f)>gd5xL))wEP9H9(v3Bm$;rY zkqiJC4L?8x6-gx!Rla8DzDFk@ zB=zEeHODRBxU=M3>?w*^0(U+zq9#FbsX3jV+pmOby!_zB`|Z=P;=&l=v6$#|`=>tx zTftyXoH89id7}9|sJNFcyzS_TG{Gga!@-xTZ~GfwW-HGcnXi`Q0Qjb*rl(r{7#{Oq DQ8tmk literal 0 HcmV?d00001 diff --git a/packages/landing/src/components/category-badge.tsx b/packages/landing/src/components/category-badge.tsx index 343aee0..7e5ba76 100644 --- a/packages/landing/src/components/category-badge.tsx +++ b/packages/landing/src/components/category-badge.tsx @@ -1,6 +1,6 @@ /** - * Blog badges: category (news = brand fill, practice = brand outline, changelog = - * neutral) + the pinned marker, all sharing the same pill shape. + * Blog badges: category (news = brand fill, practice = brand outline, perspectives = + * teal fill, changelog = neutral) + the pinned marker, all sharing the same pill shape. */ import { S } from "../lib/strings"; import type { BlogCategory } from "../lib/blog"; @@ -9,6 +9,8 @@ const CATEGORY_STYLES: Record = { news: "border-brand-200 bg-brand-50 text-brand-700 dark:border-brand-800 dark:bg-brand-950 dark:text-brand-300", practice: "border-brand-200 bg-transparent text-brand-700 dark:border-brand-800 dark:text-brand-300", + perspectives: + "border-teal-300 bg-teal-50 text-teal-800 dark:border-teal-700 dark:bg-teal-950 dark:text-teal-300", changelog: "border-gray-200 bg-gray-50 text-gray-600 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-300", }; diff --git a/packages/landing/src/lib/blog.ts b/packages/landing/src/lib/blog.ts index 4f110e1..34a7e09 100644 --- a/packages/landing/src/lib/blog.ts +++ b/packages/landing/src/lib/blog.ts @@ -7,7 +7,7 @@ import { parseFrontmatter } from "./frontmatter"; import type { Locale } from "../state/locale"; -export type BlogCategory = "news" | "practice" | "changelog"; +export type BlogCategory = "news" | "practice" | "perspectives" | "changelog"; /** Byline used when a post has no `author` frontmatter. */ export const DEFAULT_AUTHOR = "Yaowei Zheng (PrismShadow AI)"; @@ -53,7 +53,11 @@ function toPost(path: string, raw: string): BlogPost | null { if (!match) return null; const { meta, body } = parseFrontmatter(raw); const category: BlogCategory = - meta.category === "changelog" || meta.category === "practice" ? meta.category : "news"; + meta.category === "changelog" || + meta.category === "practice" || + meta.category === "perspectives" + ? meta.category + : "news"; return { slug: match[1]!, lang: match[2] as Locale, diff --git a/packages/landing/src/lib/strings-en.ts b/packages/landing/src/lib/strings-en.ts index 8b15c6f..0a4d9c3 100644 --- a/packages/landing/src/lib/strings-en.ts +++ b/packages/landing/src/lib/strings-en.ts @@ -414,10 +414,11 @@ export const en: Strings = { blog: { title: "Blog", - subtitle: "Product news, tech practices and release notes", + subtitle: "Product news, tech practices, perspectives and release notes", all: "All", news: "Product news", practice: "Tech practice", + perspectives: "Perspectives", changelog: "Release notes", pinned: "Pinned", copyLink: "Copy page link", diff --git a/packages/landing/src/lib/strings.ts b/packages/landing/src/lib/strings.ts index fc77ecc..209ad21 100644 --- a/packages/landing/src/lib/strings.ts +++ b/packages/landing/src/lib/strings.ts @@ -408,10 +408,11 @@ export const zh = { blog: { title: "博客", - subtitle: "产品动态、技术实践与更新日志", + subtitle: "产品动态、技术实践、观点与更新日志", all: "全部", news: "产品动态", practice: "技术实践", + perspectives: "观点", changelog: "更新日志", pinned: "置顶", copyLink: "复制页面链接", diff --git a/packages/landing/src/pages/blog-list.tsx b/packages/landing/src/pages/blog-list.tsx index 690e47a..495cfd8 100644 --- a/packages/landing/src/pages/blog-list.tsx +++ b/packages/landing/src/pages/blog-list.tsx @@ -1,5 +1,5 @@ /** - * Blog list: category chips (all / product news / tech practice / release notes) + + * Blog list: category chips (all / product news / tech practice / perspectives / release notes) + * post cards. A flat list in every view — each card carries its category badge, * chips filter by category, and pinned posts sort first. */ @@ -13,7 +13,7 @@ import { CategoryBadge, PinnedBadge } from "../components/category-badge"; type Filter = "all" | BlogCategory; -const FILTERS: Filter[] = ["all", "news", "practice", "changelog"]; +const FILTERS: Filter[] = ["all", "news", "practice", "perspectives", "changelog"]; export function BlogListPage() { const { locale } = useLocale(); diff --git a/packages/landing/test/blog.test.ts b/packages/landing/test/blog.test.ts index 32b0456..80f2034 100644 --- a/packages/landing/test/blog.test.ts +++ b/packages/landing/test/blog.test.ts @@ -96,7 +96,7 @@ describe("frontmatter mapping (author / pinned / category)", () => { it("reads the pinned flag and sorts the pinned post first", () => { for (const locale of ["en", "zh"] as const) { const posts = postsFor(locale); - expect(posts.length).toBe(5); + expect(posts.length).toBe(8); expect(posts[0]?.slug).toBe("introducing-penguinharness"); expect(posts[0]?.pinned).toBe(true); } @@ -108,4 +108,13 @@ describe("frontmatter mapping (author / pinned / category)", () => { "local-agents-on-amd-gpus", ]); }); + + it("filters by the perspectives category", () => { + expect(postsFor("en", "perspectives").map((p) => p.slug)).toEqual([ + // All three share 2026-07-22, so slug ascending is the tie-break. + "ai-infrastructure-past-present-future", + "easiest-way-to-build-ai-agents-2026", + "simple-harness-is-all-you-need", + ]); + }); });