[{"data":1,"prerenderedAt":651},["ShallowReactive",2],{"blog:\u002Fblog\u002Fpi-vs-deepseek-harness":3,"site":639},{"id":4,"title":5,"author":6,"body":7,"ctaLine":621,"ctaTitle":622,"date":623,"description":624,"extension":625,"heroAlt":626,"heroImage":627,"meta":628,"navigation":229,"ogImage":629,"path":630,"seo":631,"stem":632,"tags":633,"updated":637,"__hash__":638},"blog\u002Fblog\u002Fpi-vs-deepseek-harness.md","Pi vs. DeepSeek Harness: why we chose Pi","Michael Ruescher, Founder",{"type":8,"value":9,"toc":610},"minimark",[10,14,17,20,37,42,45,63,66,70,77,85,88,91,107,114,118,133,143,152,155,158,330,333,336,339,343,346,441,444,448,457,460,469,472,475,484,487,491,500,503,521,524,528,531,534,537,540,544,547,564,567,571,574,591,594,597,600,606],[11,12,13],"p",{},"An early version of BitterClip's in-product agent got confused about a missing\ntool, searched through the server filesystem, and then told us BitterClip could\nnot add background music.",[11,15,16],{},"BitterClip could add background music. The agent just couldn't see the right way\nto do it.",[11,18,19],{},"That was the moment our harness decision became much simpler. Inside a video\neditor, we did not want a coding agent with a side job. We wanted an agent that\ncould do exactly what BitterClip could do, through the same operations every\nother client uses, and nothing else.",[11,21,22,23,30,31,36],{},"We chose the ",[24,25,29],"a",{"href":26,"rel":27},"https:\u002F\u002Fpi.dev\u002F",[28],"nofollow","Pi agent harness"," for that job.\n",[24,32,35],{"href":33,"rel":34},"https:\u002F\u002Fgithub.com\u002Fdeepseek-ai\u002Fdeepseek-harness",[28],"DeepSeek Harness"," arrived\nafter that decision, so this is not a story about rejecting it in a bake-off.\nIt is an impressive foundation and, for some products, the better choice. For\nBitterClip, we would still choose Pi.",[38,39,41],"h2",{"id":40},"what-is-an-agent-harness","What is an agent harness?",[11,43,44],{},"The model is the intelligence. The harness is everything that lets that\nintelligence get work done: the conversation loop, tools, streaming, retries,\nmemory, compaction, and the connection to a user interface.",[11,46,47,48,53,54,62],{},"That makes the title easy to misread. This isn't Pi versus a DeepSeek model.\nBoth harnesses can call models from multiple providers. Can Pi run a DeepSeek\nmodel? ",[24,49,52],{"href":50,"rel":51},"https:\u002F\u002Fapi-docs.deepseek.com\u002Fquick_start\u002Fagent_integrations\u002Fpi_mono\u002F",[28],"Yes—DeepSeek publishes an official Pi integration guide",".\nThat is a separate decision from using DeepSeek Harness. In fact, one DeepSeek\nHarness adapter uses Pi's lower-level\n",[24,55,58],{"href":56,"rel":57},"https:\u002F\u002Fgithub.com\u002Fdeepseek-ai\u002Fdeepseek-harness\u002Fblob\u002Fdsh-v0.1.0-rc.7\u002Fpackages\u002Fllm\u002Fllm-pi-ai\u002FREADME.md",[28],[59,60,61],"code",{},"pi-ai","\npackage.",[11,64,65],{},"Models and harnesses are separate choices. We can change the model without\nrebuilding the product around it.",[38,67,69],{"id":68},"what-bitterclip-actually-needed","What BitterClip actually needed",[11,71,72,76],{},[24,73,75],{"href":74},"\u002Fdocs\u002Fgetting-started\u002Fwhat-is-bitterclip","BitterClip"," is a transcript-first\nmedia workshop. You can ask the agent to find a moment, trim a section, create a\nClip, start a Render, or undo an edit without leaving the editor.",[11,78,79,80,84],{},"Most of that machinery already existed before the embedded agent. Rails owns\nthe recordings, transcripts, edit operations, permissions, revisions, renders,\nand account boundaries. ",[24,81,83],{"href":82},"\u002Fdocs\u002Fassistants\u002Foverview","ChatGPT and Claude already reach those operations\nthrough BitterClip's MCP server",".",[11,86,87],{},"The new agent didn't need another workflow engine. It needed to become one\nmore careful client of the product we already had.",[11,89,90],{},"That gave us four requirements:",[92,93,94,98,101,104],"ol",{},[95,96,97],"li",{},"The model should see only BitterClip's MCP tools: no shell, filesystem,\nbrowser, skills, or subagents.",[95,99,100],{},"The editor should receive live text, progress, tool activity, cancellation,\nand usage events while the agent works.",[95,102,103],{},"Conversations should survive a reload, and the stored copy should stay with\nBitterClip.",[95,105,106],{},"The harness should remain replaceable without rewriting the editor or the\nproduct's operations.",[11,108,109,110],{},"Our internal shorthand is: ",[111,112,113],"strong",{},"BitterClip remembers the video. The harness\nremembers the conversation. MCP is the only way between them.",[38,115,117],{"id":116},"how-we-embedded-pi-in-bitterclip","How we embedded Pi in BitterClip",[11,119,120,121,126,127,132],{},"Two protocols keep those jobs separate.\n",[24,122,125],{"href":123,"rel":124},"https:\u002F\u002Fagentclientprotocol.com\u002Fget-started\u002Fintroduction",[28],"ACP"," carries the\nconversation between the editor and the agent.\n",[24,128,131],{"href":129,"rel":130},"https:\u002F\u002Fmodelcontextprotocol.io\u002Fdocs\u002Fgetting-started\u002Fintro",[28],"MCP"," gives the model\na typed set of things BitterClip can do. In production, the path looks like\nthis:",[134,135,141],"pre",{"className":136,"code":138,"language":139,"meta":140},[137],"language-text","BitterClip editor\n      │  ACP: prompts, progress, tool activity, cancellation\n      ▼\nRails bridge\n      │  ACP\n      ▼\nPi session\n      │  MCP: BitterClip tools only\n      ▼\nRails operations, authorization, recordings, and edits\n","text","",[59,142,138],{"__ignoreMap":140},[11,144,145,146,151],{},"Pi owns the middle. Its\n",[24,147,150],{"href":148,"rel":149},"https:\u002F\u002Fgithub.com\u002Fearendil-works\u002Fpi\u002Fblob\u002Fv0.84.1\u002Fpackages\u002Fcoding-agent\u002Fdocs\u002Fsdk.md",[28],"SDK","\ngives us the agent loop, streaming events, provider adapters, retries,\ncompaction, and tree-structured sessions. We wrote the two adapters around it:\nan ACP server facing the editor and an MCP client facing BitterClip.",[11,153,154],{},"We use ACP's session and activity vocabulary, plus small BitterClip-specific\nupdates for save receipts and diagnostics. A replacement harness could keep the\neditor and product operations, but its adapter would still need to implement\nthat contract.",[11,156,157],{},"The important part is how we create the session. This is a simplified version\nof our Pi 0.84.1 setup:",[134,159,163],{"className":160,"code":161,"language":162,"meta":140,"style":140},"language-ts shiki shiki-themes github-dark-dimmed","const tools = await loadBitterClipMcpTools()\nconst names = tools.map((tool) => tool.name)\n\nconst { session } = await createAgentSession({\n  tools: names,\n  customTools: tools,\n  excludeTools: [\"read\", \"bash\", \"edit\", \"write\", \"grep\", \"find\", \"ls\"],\n  resourceLoader: lockedDownResourceLoader,\n  sessionManager,\n})\n","ts",[59,164,165,192,224,231,256,262,268,312,318,324],{"__ignoreMap":140},[166,167,170,174,178,181,184,188],"span",{"class":168,"line":169},"line",1,[166,171,173],{"class":172},"scLw-","const",[166,175,177],{"class":176},"sDGpf"," tools",[166,179,180],{"class":172}," =",[166,182,183],{"class":172}," await",[166,185,187],{"class":186},"sLyBy"," loadBitterClipMcpTools",[166,189,191],{"class":190},"s1ain","()\n",[166,193,195,197,200,202,205,208,211,215,218,221],{"class":168,"line":194},2,[166,196,173],{"class":172},[166,198,199],{"class":176}," names",[166,201,180],{"class":172},[166,203,204],{"class":190}," tools.",[166,206,207],{"class":186},"map",[166,209,210],{"class":190},"((",[166,212,214],{"class":213},"s7B5-","tool",[166,216,217],{"class":190},") ",[166,219,220],{"class":172},"=>",[166,222,223],{"class":190}," tool.name)\n",[166,225,227],{"class":168,"line":226},3,[166,228,230],{"emptyLinePlaceholder":229},true,"\n",[166,232,234,236,239,242,245,248,250,253],{"class":168,"line":233},4,[166,235,173],{"class":172},[166,237,238],{"class":190}," { ",[166,240,241],{"class":176},"session",[166,243,244],{"class":190}," } ",[166,246,247],{"class":172},"=",[166,249,183],{"class":172},[166,251,252],{"class":186}," createAgentSession",[166,254,255],{"class":190},"({\n",[166,257,259],{"class":168,"line":258},5,[166,260,261],{"class":190},"  tools: names,\n",[166,263,265],{"class":168,"line":264},6,[166,266,267],{"class":190},"  customTools: tools,\n",[166,269,271,274,278,281,284,286,289,291,294,296,299,301,304,306,309],{"class":168,"line":270},7,[166,272,273],{"class":190},"  excludeTools: [",[166,275,277],{"class":276},"sP_-H","\"read\"",[166,279,280],{"class":190},", ",[166,282,283],{"class":276},"\"bash\"",[166,285,280],{"class":190},[166,287,288],{"class":276},"\"edit\"",[166,290,280],{"class":190},[166,292,293],{"class":276},"\"write\"",[166,295,280],{"class":190},[166,297,298],{"class":276},"\"grep\"",[166,300,280],{"class":190},[166,302,303],{"class":276},"\"find\"",[166,305,280],{"class":190},[166,307,308],{"class":276},"\"ls\"",[166,310,311],{"class":190},"],\n",[166,313,315],{"class":168,"line":314},8,[166,316,317],{"class":190},"  resourceLoader: lockedDownResourceLoader,\n",[166,319,321],{"class":168,"line":320},9,[166,322,323],{"class":190},"  sessionManager,\n",[166,325,327],{"class":168,"line":326},10,[166,328,329],{"class":190},"})\n",[11,331,332],{},"The allowlist comes straight from BitterClip's MCP server. If a tool isn't on\nthat list, Pi never registers it. We also turn off extension, skill,\nprompt-template, theme, and context-file discovery, then replace Pi's coding\nprompt with BitterClip's own prompt.",[11,334,335],{},"At startup, we inspect Pi's live tool registry and refuse to serve unless it\ncontains every expected BitterClip tool and zero built-ins.",[11,337,338],{},"That may sound fussy. It is cheaper than discovering later that an inactive\nshell could be switched back on.",[38,340,342],{"id":341},"pi-vs-deepseek-harness-at-a-glance","Pi vs. DeepSeek Harness at a glance",[11,344,345],{},"The two projects overlap, but they start from different centers of gravity.",[347,348,349,365],"table",{},[350,351,352],"thead",{},[353,354,355,359,362],"tr",{},[356,357,358],"th",{},"Question",[356,360,361],{},"Pi in BitterClip",[356,363,364],{},"DeepSeek Harness v0.1.0-rc.7",[366,367,368,380,391,402,413,424],"tbody",{},[353,369,370,374,377],{},[371,372,373],"td",{},"What do you start with?",[371,375,376],{},"A small TypeScript agent runtime with an SDK",[371,378,379],{},"A plugin-based agent platform with web and headless profiles",[353,381,382,385,388],{},[371,383,384],{},"How do you customize it?",[371,386,387],{},"Construct a session in code with a prompt, model, tools, resources, and storage",[371,389,390],{},"Assemble or replace Cordis plugins",[353,392,393,396,399],{},[371,394,395],{},"What does it provide?",[371,397,398],{},"Loop, streaming, retries, providers, compaction, and session history",[371,400,401],{},"Those foundations plus a UI, jobs, goals, workflows, subagents, policy, and more",[353,403,404,407,410],{},[371,405,406],{},"Which tools reach the model?",[371,408,409],{},"The exact custom-tool allowlist we construct and check",[371,411,412],{},"The tools registered by the chosen plugin profile; the shipped base is broad but can be recomposed",[353,414,415,418,421],{},[371,416,417],{},"How does its current ACP path fit our editor?",[371,419,420],{},"We own the adapter, including live deltas, tool traces, history loading, and BitterClip receipts",[371,422,423],{},"The upstream adapter creates fresh sessions and sends committed answers; live progress, tool activity, resume, fork, and delete are not exposed over ACP",[353,425,426,429,432],{},[371,427,428],{},"What evidence do we have today?",[371,430,431],{},"Pi 0.84.1 is pinned and serving in BitterClip; upgrades still need tool-surface, migration, and resume tests",[371,433,434,435,440],{},"v0.1.0-rc.7 is a ",[24,436,439],{"href":437,"rel":438},"https:\u002F\u002Fgithub.com\u002Fdeepseek-ai\u002Fdeepseek-harness\u002Fblob\u002Fdsh-v0.1.0-rc.7\u002FREADME.md#developer-preview",[28],"developer preview"," whose maintainers warn of breaking changes",[11,442,443],{},"DeepSeek Harness is aiming at a larger problem. That is precisely what makes it\ninteresting.",[38,445,447],{"id":446},"what-we-like-about-deepseek-harness","What we like about DeepSeek Harness",[11,449,450,451,456],{},"DeepSeek Harness is built around one powerful idea:\n",[24,452,455],{"href":453,"rel":454},"https:\u002F\u002Fgithub.com\u002Fdeepseek-ai\u002Fdeepseek-harness\u002Fblob\u002Fdsh-v0.1.0-rc.7\u002Fdocs\u002Farchitecture.md",[28],"everything is a plugin",".\nModels, tools, sessions, policies, jobs, and the UI all plug into Cordis. Its\nappend-only session log makes runs easier to replay and inspect, and you can\nreplace one capability without forking the core.",[11,458,459],{},"If we were building a general agent workbench, that would be hard to ignore. The\nweb UI, job panel, goals, workflows, sandbox policies, and subagent providers\nwould save real work.",[11,461,462,463,468],{},"It isn't limited to the bundled web UI. DeepSeek Harness also has public agent\nAPIs and ",[24,464,467],{"href":465,"rel":466},"https:\u002F\u002Fgithub.com\u002Fdeepseek-ai\u002Fdeepseek-harness\u002Fblob\u002Fdsh-v0.1.0-rc.7\u002Fpackages\u002Fsdk\u002FREADME.md",[28],"an out-of-process TypeScript SDK","\nfor custom integrations. For agents that genuinely need shell and filesystem\naccess, its approval, policy, and sandbox seams provide controls Pi doesn't\nsupply by itself.",[11,470,471],{},"BitterClip already has a backend, an editor, jobs, permissions, and one\nestablished set of editing operations. Putting another full platform in the\nmiddle would force us to answer the same question over and over: does this state\nbelong to Rails or to the harness?",[11,473,474],{},"DeepSeek Harness can be pared down. That is one of its strengths. For\nBitterClip, though, we would need to build a custom profile, keep conversation\ndata on our side of the boundary, extend ACP, and adapt its MCP tool names and\npresentation to our existing editor. Most of that work would be spent making\nthe platform deliberately smaller.",[11,476,477,478,483],{},"The current upstream\n",[24,479,482],{"href":480,"rel":481},"https:\u002F\u002Fgithub.com\u002Fdeepseek-ai\u002Fdeepseek-harness\u002Fblob\u002Fdsh-v0.1.0-rc.7\u002Fpackages\u002Facp\u002Facp\u002FREADME.md",[28],"ACP adapter","\nis the clearest example. The harness has live internal events—its own web UI uses\nthem—but the upstream ACP adapter is built for clean automation: create a fresh\nsession, submit a prompt, wait for a committed answer, cancel if needed. Our\ninteractive editor lets people watch tools run, reopen old conversations,\ninspect what changed, and undo edits. We would have to extend the adapter before\nthe harness could replace what is serving today.",[11,485,486],{},"All of that is possible. It just wouldn't improve BitterClip enough to justify\nthe work today.",[38,488,490],{"id":489},"pi-is-not-a-security-boundary","Pi is not a security boundary",[11,492,493,494,499],{},"There is an important caveat. Pi's normal coding-agent experience includes\nfile and shell tools, and Pi\n",[24,495,498],{"href":496,"rel":497},"https:\u002F\u002Fgithub.com\u002Fearendil-works\u002Fpi\u002Fblob\u002Fv0.84.1\u002FREADME.md#permissions--containerization",[28],"doesn't provide a built-in permission system",".\nBy default it runs with the permissions of its process.",[11,501,502],{},"Our safety doesn't come from the word “minimal.” It comes from the system we\nbuilt around the runtime:",[504,505,506,509,512,515,518],"ul",{},[95,507,508],{},"the unwanted tools are absent from the live registry, not hidden by the UI;",[95,510,511],{},"the agent runs as a non-root user in a separate container, with bounded,\nprivate, non-executable temporary storage and no persistent volume;",[95,513,514],{},"every product action goes back through Rails authorization;",[95,516,517],{},"the model never chooses which account it is acting for; and",[95,519,520],{},"agent edits carry a revision and receipt, so people can see exactly what\nchanged and undo it.",[11,522,523],{},"The container is useful hardening, not a complete sandbox around Bun. This is\nalso why we don't call our setup “Pi out of the box.” We use Pi as a library\nand take responsibility for the boundary.",[38,525,527],{"id":526},"the-tradeoffs-we-accepted","The tradeoffs we accepted",[11,529,530],{},"Pi is small, but the integration work is still ours. We own the ACP adapter, the\nMCP-to-Pi tool bridge, conversation storage, and the tests around them.",[11,532,533],{},"There is another catch: Pi owns the format for conversation history. Rails\nstores those session bytes without parsing the conversation itself. That keeps\nus from quietly rebuilding Pi in Ruby, but upgrades need careful migration and\nresume testing.",[11,535,536],{},"Finally, a narrow system can fail quietly. An empty allowlist leaves you with an\nagent that chats perfectly and cannot do a thing. So startup checks both\nfailures: zero Pi built-ins and every expected BitterClip tool. That turns the\nbackground-music failure from our opening into a boot error instead of a bad\nanswer in front of a user.",[11,538,539],{},"Those are real costs. They are still smaller than owning two product backends.",[38,541,543],{"id":542},"when-we-would-choose-deepseek-harness-instead","When we would choose DeepSeek Harness instead",[11,545,546],{},"We would put DeepSeek Harness near the top of the list if the harness itself\nwere the product:",[504,548,549,552,555,558,561],{},[95,550,551],{},"a coding or research workbench with several frontends;",[95,553,554],{},"a system where users assemble agents from plugins;",[95,556,557],{},"a multi-agent environment with jobs, goals, workflows, and shared policy;",[95,559,560],{},"a platform that needs a rich, replayable event model as its primary state; or",[95,562,563],{},"a new product without an existing backend that already owns tools,\nauthorization, and durable work.",[11,565,566],{},"In that situation, DeepSeek Harness's larger surface is not overhead. It is the\nthing you would otherwise have to build.",[38,568,570],{"id":569},"the-five-questions-we-would-ask-again","The five questions we would ask again",[11,572,573],{},"If you are choosing an agent harness for an application, start with the product\nboundary rather than a feature matrix:",[92,575,576,579,582,585,588],{},[95,577,578],{},"What must the model never be able to do?",[95,580,581],{},"Which system stores the real customer data and enforces permissions?",[95,583,584],{},"Do you need an agent platform, or only an agent loop inside an existing\nproduct?",[95,586,587],{},"At runtime, can you prove exactly which tools the model can use?",[95,589,590],{},"Can you replace the harness without replacing your product?",[11,592,593],{},"For BitterClip, those answers pointed to Pi. It isn't a universal winner. It\nlet us keep the agent narrow without rebuilding the parts of BitterClip that\nalready worked.",[11,595,596],{},"If we had to make the choice again, we would start with the same question: where\nshould the harness stop and the product begin?",[598,599],"hr",{},[11,601,602],{},[603,604,605],"em",{},"Version note: this field report describes BitterClip's pinned Pi 0.84.1\nintegration and DeepSeek Harness v0.1.0-rc.7, reviewed on August 18, 2026.\nDeepSeek Harness is in developer preview and changing quickly. We will revisit\nthe comparison as its embedded interfaces mature.",[607,608,609],"style",{},"html pre.shiki code .scLw-, html code.shiki .scLw-{--shiki-default:#F47067}html pre.shiki code .sDGpf, html code.shiki .sDGpf{--shiki-default:#6CB6FF}html pre.shiki code .sLyBy, html code.shiki .sLyBy{--shiki-default:#DCBDFB}html pre.shiki code .s1ain, html code.shiki .s1ain{--shiki-default:#ADBAC7}html pre.shiki code .s7B5-, html code.shiki .s7B5-{--shiki-default:#F69D50}html pre.shiki code .sP_-H, html code.shiki .sP_-H{--shiki-default:#96D0FF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":140,"searchDepth":226,"depth":226,"links":611},[612,613,614,615,616,617,618,619,620],{"id":40,"depth":194,"text":41},{"id":68,"depth":194,"text":69},{"id":116,"depth":194,"text":117},{"id":341,"depth":194,"text":342},{"id":446,"depth":194,"text":447},{"id":489,"depth":194,"text":490},{"id":526,"depth":194,"text":527},{"id":542,"depth":194,"text":543},{"id":569,"depth":194,"text":570},"The Creator trial lasts seven days and requires a card: $0 today, then $24\u002Fmonth unless you cancel before it ends. It includes $5 of agent work for one recording up to two hours. Upload a recording and ask for a moment, a Clip, or a Render—then inspect exactly what changed before you export.","Put the agent to work on a real recording","2026-08-18","A concrete look at why BitterClip uses the Pi agent harness for its embedded AI agent, how it works, and when DeepSeek Harness would fit better.","md","BitterClip's embedded-agent architecture, with the editor speaking ACP to Pi and Pi limited to BitterClip MCP tools, beside DeepSeek Harness as a larger plugin platform.","\u002Fimages\u002Fblog\u002Fpi-vs-deepseek-harness\u002Fpi-vs-deepseek-harness.svg",{},"\u002Fimages\u002Fblog\u002Fpi-vs-deepseek-harness\u002Fpi-vs-deepseek-harness-og.png","\u002Fblog\u002Fpi-vs-deepseek-harness",{"title":5,"description":624},"blog\u002Fpi-vs-deepseek-harness",[634,35,635,131,636],"Pi","agent harnesses","engineering",null,"82Oi1XctzVOIYxjeRGXpLnbEQneZ-nSHDoO5NqMiPWU",{"id":640,"app_origin":641,"extension":642,"mcp_resource_url":643,"meta":644,"og_image_default":645,"pricing_url":646,"signup_url":647,"stem":648,"support_email":649,"__hash__":650},"site\u002F_data\u002Fsite.yml","https:\u002F\u002Fapp.bitterclip.com","yml","https:\u002F\u002Fapp.bitterclip.com\u002Fmcp",{},"\u002Fimages\u002Fbitterclip-og-iso4.png","https:\u002F\u002Fbitterclip.com\u002F#pricing","https:\u002F\u002Fapp.bitterclip.com\u002Fsign_up?plan=clip","_data\u002Fsite","hello@bitterclip.com","qhdf75srfVvPCSkmwBfhqfuL5nIuRZQnT7y4uv0sjHA",1787569708331]