Så bygger vi delade arbetsytor för människor och agenter
Så gör Projekt i Perplexity långvarigt arbete beständigt, parallellt och spårbart.
Vi lanserade nyligen Projekt, där människor och agenter arbetar tillsammans med långvariga uppgifter i Perplexity Computer. Varje projekt bygger på en delad arbetsyta med ett filsystem som samlar kontext över sessioner, agenter och användare. Samarbete mellan många deltagare som sträcker sig över månader kräver beständighet, samtidighet och spårbarhet:
- Beständighet: Arbetet ska bestå längre än en enskild agentsession eller sandlåda, så att samma användare eller agent kan fortsätta arbetet senare och alla medarbetare kan bygga vidare på det.
- Samtidighet: Flera användare i samma projekt kan var och en ha flera agenter som gör redigeringar parallellt och för ett gemensamt tillstånd framåt i stället för att skriva över varandra.
- Spårbarhet: Både användare och agenter ska kunna se historiken, så att de kan kontrollera vem som har ändrat vad sedan deras senaste session utan att läsa om hela projektet, och återställa redigeringar vid behov.
Mjukvaruutvecklare känner igen de här utmaningarna. Kodplattformar för Git, så kallade forges, växte fram för flera decennier sedan för att uppfylla just de här kraven: en värdbaserad tjänst som kombinerar versionshantering med samarbetsfunktioner så att många bidragsgivare kan samlas kring en enda sanningskälla. Filsystemet som driver Projekt är en sådan kodplattform för Git, byggd för samarbete mellan människor och agenter och mellan agenter.
Arkitektur
Git hanterar redan beständighet, samtidighet och spårbarhet. Git identifierar varje fil utifrån dess innehåll, så oförändrade filer lagras en gång och sparade kopior blir aldrig inaktuella. Varje commit sparar alla uppdaterade filer på en gång, så medarbetare ser aldrig ett halvfärdigt tillstånd. När två skrivande parter krockar kan den som förlorade tillämpa sina ändringar på nytt ovanpå den nya versionen och försöka igen. Kedjan av commits visar vem som ändrade vad och gör det enkelt att återställa tidigare versioner. Det agenter inte behöver är resten av en kodplattform byggd för människor, som granskningsvyer, grenhantering och aviseringar.
Vår arkitektur kör hela processen i molnet och stöder alla former av kunskapsarbete, inte bara programmering. Varje projekt i Computer backas upp av ett Git-repo som betjänas av 5 komponenter:
- CLI-verktyget underhåller lokala utcheckningar, synkroniserar uppdateringar och skickar in agentens ändringar i varje sandlåda.
- Kontrollplanet hittar projektets repo och utfärdar kortlivade autentiseringsuppgifter för att nå det.
- Git-tjänsten skickar repodata till sandlådor, tar emot deras inskickningar och avgör vilken inskickning som blir den senast accepterade commiten.
- AWS S3-baserad lagring lagrar repodata beständigt.
- Nedströmsbearbetning extraherar text och annan användbar information från sparade dokument och gör den tillgänglig när agenter läser in eller uppdaterar projektet.
Varje agent har sin egen isolerade sandlåda. I sandlådan arbetar agenten med en lokal kopia av repot, som hanteras av ett litet CLI-verktyg. CLI-verktyget ber kontrollplanet att hitta repot och hämtar och skickar sedan in ändringar via Git-tjänsten. En agentproxy kontrollerar åtkomsten för förfrågningar från sandlådan innan de når Git-tjänsten. Git-tjänsten läser och skriver repon på ett delat filsystem och avgör om varje inskickning blir den senast accepterade commiten. Filsystemet tillhandahålls av AWS S3Files, som gör S3-baserad lagring tillgänglig som vanliga filer och kataloger. Lagringen är uppdelad i isolerade celler, var och en med ett eget filsystem och egna repliker av Git-tjänsten. När en commit har accepterats extraherar bakgrundsprocesser text och annan användbar information från ändrade dokument, lagrar resultaten separat från repots historik och gör dem tillgängliga när agenter läser in eller uppdaterar projektet.
Härnäst går vi igenom komponenterna en i taget.
CLI: arbeta med lokala filer i sandlådor
Agenter körs i SPACE, vår egenutvecklade sandlådeplattform. Varje sandlåda har ett litet CLI-verktyg som materialiserar repot och håller det synkroniserat. För varje meningsfull arbetsenhet som agenten utför skickar verktyget in ändringarna som en commit.
Agenter rör vanligtvis bara en liten del av projektfilerna, så det är inte nödvändigt att materialisera hela repot i förväg. CLI-verktyget använder därför lat materialisering: stora filer och binärfiler som lagras via Git Large File Storage (LFS) kommer fram som små pekarfiler som anger objektets verkliga storlek, så att agenten kan använda namnet och storleken för att avgöra om en nedladdning är värd det. För dokument som PDF-filer läser agenten först den parsade texten och laddar bara ned källfilerna när det behövs.
Ett annat naturligt alternativ vore att använda ett virtuellt filsystem. Vi testade en FUSE-baserad implementering, men den var ungefär 400 gånger långsammare än lokala filer vid filsystemsintensiva arbetsbelastningar, eftersom varje förfrågan kräver en tur och retur över nätverket. Den kräver dessutom vanligtvis privilegierade behörigheter från värden, så varje agent skulle behöva köras i en privilegierad sandlåda.
Kontrollplanet: hitta repon och utfärda åtkomst
Kontrollplanet tar reda på var varje repo lagras och utfärdar åtkomst till det. När ett repo skapas tilldelar kontrollplanet det till en lagringscell, en isolerad lagringsenhet med egna repliker av Git-tjänsten. När en agent börjar arbeta i ett projekt frågar CLI-verktyget kontrollplanet var repot lagras. Kontrollplanet returnerar platsen och tillfälliga autentiseringsuppgifter för Git-tjänsten. Kontrollplanet läser eller skriver aldrig data i repot. Det är Git-tjänsten som avgör vad som kommer in i ett repo.
Git-tjänsten: flytta data och samordna uppdateringar
Git-tjänsten utför Git-operationer och överför repoinnehåll och versionshistorik mellan sandlådor och lagring. Den är ett tunt skal runt Gits egna serverkommandon. Den stöder ref discovery för att tala om för klienten var repots head-commit finns, upload-pack för kloning och hämtning samt receive-pack för att ta emot nya objekt och en begäran om att flytta fram repots head-commit. Den tillhandahåller också Git LFS-API:t: för stora filer och binärfiler utfärdar den kortlivade länkar så att sandlådor kan ladda upp och ladda ned filerna direkt till och från S3.
Vi började med en färdig kodplattformsserver, så att vi kunde ta fram prototyper av agent- och användargränssnitten parallellt med att vi byggde vår egen lättviktiga kodplattform, inriktad enbart på de Git-operationer vi behöver.
Tjänsten består av en flotta av repliker, där var och en är en körande instans av samma server. En cell samlar delad lagring med en uppsättning repliker och deras stödtjänster. Repliker inom en cell kan då komma åt samma delade filsystem i stället för att hålla egna kopior av varje repo.
Tack vare den delade lagringen kan replikerna förbli tillståndslösa. Vilken replik som helst i cellen kan betjäna vilket som helst av cellens repon, så det krävs ingen flytt av repodata mellan servrar när repliker ersätts eller läggs till. Förfrågningar för ett repo går normalt till samma replik så att dess cacheminnen förblir användbara, men repot är inte beroende av att just den instansen förblir tillgänglig.
Acceptanssteget kontrollerar repots invarianter för att säkerställa att en accepterad commit motsvarar ett giltigt tillstånd för repot. Vi definierar ett explicit kontrakt för varje repo, så att mekaniska kontroller kan hindra det från att växa sig för stort. Stora filer och binärfiler, som PDF-filer och bilder, lagras via Git LFS i stället för som råa Git-blobbar. Kompaktering håller den senaste historiken tillgänglig samtidigt som repots storlek begränsas. Efter en lyckad inskickning frågar CLI-verktyget Git-tjänsten om repot behöver kompakteras. Om antalet sparade commits överstiger ett tröskelvärde behåller Git-tjänsten bara en mindre uppsättning av de senaste commitsen. Äldre historik ersätts med en enda ögonblicksbild som startpunkt, och de senaste commitsen spelas upp igen för att uppdatera commit-identifierarna.
Ett enkelt synkroniseringssteg hanterar samtidiga skrivningar. Det håller reda på den senast accepterade commiten, även kallad head-commit. När det tar emot en inskickning accepterar det den bara om den bygger på den head-commiten. Om inte skickar det ett strukturerat svar om inaktuell bas; förloraren måste då spela upp sin ändring igen ovanpå den nya head-commiten och skicka in den på nytt. Den här designen säkerställer att samtidiga agenter inte i tysthet skriver över varandra, utan att orsaka några betydande fördröjningar. I våra produktionsarbetsflöden avvisas färre än 2 % av inskickningarna som inaktuella. Totalt sett är medianlatensen för inskickningar under 1,7 sekunder och p99-latensen under 8 sekunder.
Git-tjänsten registrerar också varje accepterad ändring. För varje accepterad skrivning lägger den till en post i en utkorg, en logg som anger repot, den nya commiten, användaren som gjorde ändringen och de sökvägar som ändrades. Nedströmstjänster som parsern läser den här loggen för att hitta nytt arbete.
Tillsammans bildar de här delarna ett lager för repohantering, utan de delar som agenter inte behöver. Pull requests behövs inte, eftersom ingen människa granskar varje ändring. I stället kontrollerar Git-tjänsten kontraktet vid inskickningen, den agent som förlorar en kapplöpning tillämpar sin egen ändring på nytt och commit-historiken visar vem som ändrade vad. Deterministiska kontroller håller varje repo inom sitt kontrakt, i stället för att en mänsklig operatör ska behöva hantera tillväxten.
Lagring: håll arbetet beständigt
Lagringslagret sparar repodata beständigt, oberoende av sandlådorna och Git-tjänstens repliker. Repona finns på AWS S3Files, som exponerar S3-baserad lagring via ett filsystemsgränssnitt som standardversionen av Git kan använda utan ändringar. Varje repo är ett bart Git-repo på det delade filsystemet, som innehåller repots objekt och referenser i stället för en utcheckad arbetskopia.
Genom att frikoppla lagring och beräkning kan sandlådorna förbli kortlivade. Varje agent får sin egen sandlåda, och många agenter kan arbeta i samma projekt utan att dela maskin. Om en sandlåda kraschar är det bara arbete som inte har skickats in som riskerar att gå förlorat.
Vi skulle i stället kunna ge varje projekt en långlivad sandlåda som alla dess agenter delar, så att projektets filer finns på den maskinens disk. Det skulle dock knyta agenternas beräkningskapacitet till den plats där maskinen körs och kräva att maskinen dimensioneras för sina mest belastade perioder. Den skulle också behöva fungera stabilt i månader, med säkerhetskopiering och återställning som en del av projektets lagringssystem.
Nedströmsbearbetning: gör dokument läsbara för agenter
Den viktigaste nedströmskomponenten är en parsningspipeline som extraherar text och metadata från nyligen tillagda eller uppdaterade dokument, så att agenter enkelt kan läsa projektfilerna. En parsningsprocess konsumerar uppdateringar från kön för ändringsströmmen, härleder de ändrade filerna från commit-metadata och hämtar rådata med hjälp av innehållshashen. Därefter parsar den dokumentet för att ta fram den extraherade texten och dokumentets metadata.
Parsade utdata lagras utanför repot, i ett lager där nyckeln är källdokumentets hash. Dessa artefakter committas aldrig tillbaka till repot, eftersom det i onödan skulle förorena historiken och öka antalet samtidiga skrivningar. I stället når de parsade utdata en sandlåda via utcheckning och synkronisering. Varje utcheckning innehåller en reserverad katalog som CLI-verktyget använder för att materialisera artefakter. Parsningen sker asynkront, så en parsningsprocess i bakgrunden blockerar inte utcheckningar.
Så använder agenter arbetsytan
Agenter utforskar den version av repot som har lästs in i sandlådan med hjälp av vanliga filsystemverktyg. I stället för att följa en fast pipeline där de först söker och sedan läser, listar de mappar, söker i filinnehåll med grep, läser relevanta avsnitt och använder det de hittar för att avgöra var de ska leta härnäst.
I likhet med Computer använder Search samma metod via sina vanliga filverktyg. En separat utforskningsagent söker igenom projektet inom en mer begränsad budget och returnerar relevanta filsökvägar och stödjande utdrag. Svarsmodellen läser sedan de valda filerna och genererar svaret. Att återanvända en befintlig projektsandlåda minskar uppstartstiden: att ansluta till en varm utcheckning tar ungefär 2,9 sekunder, jämfört med cirka 8 sekunder vid en kallstart.
Parsad text gör större dokument som PDF- och Office-filer sökbara med samma verktyg. Agenten kontrollerar först ett manifest, en lista som visar vilka dokument som har extraherad text tillgänglig, och söker sedan i och läser texten som vanliga filer. Agenten laddar bara ned originaldokumentet när texten inte räcker, till exempel för att granska figurer, layout eller inbäddade data.
Vi jämförde den här metoden med semantisk sökning i ett index, med 150 finansiella frågor som var och en gällde ett enskilt dokument i samma korpus. Utforskningsagenten fick 0,867 på att hämta rätt dokument och 0,627 på att svara korrekt, mot ungefär 0,39 respektive 0,37 för semantisk sökning. Det är ungefär 1,7 gånger bättre på svar och 2 gånger bättre på hämtning, med cirka 25 % lägre latens. Utforskningsagenten arbetar mest med extraherad text och laddar sällan ned de ursprungliga PDF-filerna.
En gemensam infrastruktur
Det beständiga minnet i Computer använder samma filsysteminfrastruktur. Perplexity Brain, kunskapswikin i Computer, lagrar minnet i kunskapsrepon med egen historik och egna policyer. Eftersom kunskapen hålls åtskild från projektfilerna konkurrerar minnesuppdateringar i bakgrunden inte med redigeringar av de filerna. En session som behöver båda läser in båda repona.
Bakgrundsagenter läser befintlig kunskap, införlivar ny information och sparar uppdaterade sidor som commits. Andra agenter läser sidorna med vanliga filverktyg, och människor kan också redigera dem. De som skriver delar sitt arbete via repot i stället för att samordna sig direkt med varje läsare. Commit-historiken visar vem som ändrade vad, medan utkorgen rapporterar accepterade uppdateringar till nedströmstjänster. Människor och agenter kan bygga vidare på varandras arbete, med ett spår av hur kunskapen har utvecklats.
Slutsats
När människor och agenter delar ett projekt gör arbetsytan mer än att lagra filer. Den utgör en gemensam plats där bidrag kan kombineras och där man kan följa vad som har ändrats. Git står redan för mycket av den grunden. Vi lägger till samordning och automatiserade kontroller så att agenter kan skicka in arbete utan att en person behöver godkänna varje uppdatering. Resultatet är en kodplattform som skalats ned till det väsentliga, eftersom samarbete mellan agenter och mjukvaruutveckling med många bidragsgivare i grunden är samma problem.
Agenter arbetar i oberoende, tillfälliga sandlådor samtidigt som de bidrar till beständiga repon. Gränser för repona håller tillväxten hanterbar, explicita nedladdningar låter agenterna välja vad de ska hämta och vanliga filer låter dem utforska med välbekanta verktyg. Bakgrundsuppdateringar, interaktiva redigeringar och schemalagda uppgifter kan bygga vidare på varandras arbete utan direkt samordning.
I takt med att fler agenter arbetar självständigt i Projekt måste deras delade arbetsyta förbli tillförlitlig och begriplig för människor. Målet är enkelt: varje ändring ska vara mer beständig än agenten som skapade den, bli tillgänglig för nästa medarbetare och lämna ett tydligt spår av vad som ändrades.
Citering
@online{perplexity2026BuildingSharedWorkspacesForPeopleAndAgents,
author = {{Perplexity} and Se Won Jang and Peter Hart and Kartik Kapur and Kevin Lau and Sidhant Rajadnya and Ishbir Singh and Thomas Wang and Jarrod Bryan and Claire Beamer and Jeremy Yang},
title = {{Building shared workspaces for people and agents}},
date = {2026-10-12},
url = {https://www.perplexity.ai/hub/blog/building-shared-workspaces-for-people-and-agents}
}