Усё — гэта плагін: дыяграма Cordis у спадчыне DeepSeek Harness
Як DeepSeek Harness стварае рэнтайм-серавер агента на базе плагінаў, выкарыстоўваючы ідэі Cordis, такія як зворачныя эфекты, рэакtyўныя залежнасці і агентскі цыкл, які можа быць заменены.
Крыніцы: DeepSeek Quietly Built a Different Kind of AI Agent Framework
Звычны рэцепт і дзе ён выклікае проблемы
Большасць фрэймворкаў для агентаў пачынаюцца з тых сабе інгрэдыянтав: модэль языка, калькі інструментаў, зберажаная розмова і цыкл, які абёруе ўсё гэта. Ніжышчэй паказанае схематычнае зображэнне дапамагае разумець структуру.
User asks something
↓
LLM thinks
↓
LLM calls a tool
↓
Tool returns data
↓
LLM continues
↓
Final answer
Па прызначэнні гэта ужо лягае ў кантакт з агентам. Проблемы пачынаюцца, калі сістэма расце. З’яўляецца множына трэбаванняў: калькольныя прадаўцы, інструменты браузера, выкананне з шэлу, серверы MCP, працэсы затверджэння, памяць, тэлеметрыя, аўтэнтыфікацыя, розныя інтэрфейсы, фонавыя агенты, спецыяльныя запіты, правы прыступ і гарачая перзагрузка. Шырока ўсе часткі становяцься залежнымі ад усіх іншых частак. Змена калькольнага прадаўцы вплывае на цыкл агента, выдаленне плагіна залішае слухачы запуска ўвесь час, а перзагрузка інструмента можа зламаць агенты, якія працуюць у той момант. Плагіны таксама залежнаць ад служб, якія могу з’явіцца чы растаяць пад час работы.
DeepSeek Harness падходзіць да гэтага аблічна іншым спосабам. Яго цэнтральная ідэя звучыць майжэ занадта проста: усё ёсць плагіном, включаючы тыя часткі, якія большасць фрэймворкаў называе ядром.
Пад тым усім знаходзіцца каркас пад назвай Cordis, які выйшаў з нарадчага артыкула пад назвай „A Programming Paradigm for Spatiotemporal Composability“. Гэты артыкул ўскаржыў заінтэрэсаванасць, адколькі праект – гэта не проста ўзрастаючая схема для арганізацыі модуляў JavaScript. Ён ставіць мярку на глыбокія інжынерныя пытанні: як компоненты можаць з’яўляцца, з’яўляцца, заменяць адна другую і зміняць залежнасці ў працюючай працэсе, калі толькі рантайм не пастане хаосам?
Што такое harness
DeepSeek Harness, скаратка dsh, – гэта агентскі harness з адкрытым кодам, выданы DeepSeek. Harness – гэта інфраструктура, якая абгружае мадэль. Незалежна ад таго, чыя мадэль – DeepSeek, Claude, GPT, Gemini чы сяроднія, harness абгружае все, што знаходзіцца ў яе абліку.
┌───────────────┐
│ LLM │
└───────┬───────┘
│
┌──────────▼──────────┐
│ Agent Harness │
│ │
│ Prompt construction │
│ Tool execution │
│ Session history │
│ Permissions │
│ Streaming │
│ Agent lifecycle │
│ Model adapters │
└─────────────────────┘
Эта разліка мае вельмі важлівыя наследкі. Зазвычай увага зосераджваецца на тым, насколькі розумны мадэль, пры тым часе стварэнне такіх програм, як Claude Code, Codex, Cursor чы або автонамных агентаў, якія працуюць дзеякі час, паказвае, што час ўработы таксама мае вельмі важлівое значэння. DeepSeek Harness керуе часам уработы за дапамою набора дынамічна складзеных плагінав, а не як адной монолітнай прыемлі, і гэта рашэнне было пераданае безпосерэдна з Cordis.
Загадка залежнасцяў
Уявіце сабе стварэнне агента для програмавання з трох плагінаў.
GitPlugin
TerminalPlugin
CodingAgent
Для працы з кодаваннем патрэбны Git і Terminal. Пры запуске простэйшы спосаб — гэта завантажыць іх па адзіну.
load Git
load Terminal
load CodingAgent
Гэта проста, і большасць фрэймворкаў для впрыску залежнасцяў справляюцца з гэтым добра. Складнейшы вопыт — што будзе, калі плагін Git з’явіцца ў момент запуску програмы. Можа, яго было аптэмператавана, можа змянілася яго настройка, можа корыстувач яго выключыў, або ж з’явілася іншая рэалізацыя. У такім случае сістэма запуску павінна зупініць усё, што залежыць ад гэтага сервісу.
CodingAgent
↓ -------->depends on
GitPlugin
Калі Git з’являецца, аплікацыя для кодавання не павінна продовжваць ведацца так, нібы ён існуе. А калі пазней з’явіцца іншы прадаўцу Git, можабы аплікацыя павінна знову запрацаваць. Чэрз гэта крыюцца два адналежныя проблемы, якія ў стацыі Cordis называюцца тэмпаральной і прасторовай композабельнасцю.
Тэмпаральная композабельнасць: чыстае выйшча
Падазроўваюць, што плагін завантажаецца і рэгіструець слухальнік западання.
events.on("message", handler)
Пазней плагін адзягаецца, і выступае пытанне: што станэцца з абяроннікам. Калі нічто яго не адзягаецца, плагін знікае па назве, а частка яго продовжвае працаваць. Да гэтаму плагін могаў запусціць таймеры, ачысціць з’язкі з базой дадзеных, зарэўструваць команды, змяніць спакульнае стана, дадаць інструменты, прыўяжыць апрацоўшчыкі здарэнняў і запусціць рабох. Адзяганне яго значыць абворачэнне кожнага з гэтых крокаў.
Гэта ёсць тэмпаральная композабельнасць: кампонент, які прыўяжаецца да сістэмы, павінен заставіць сістэму магчымае абворачыць усё, што зробіў кампонент. Cordis спрацоўвае такія змены як адворачымыя эфекты.
Эфекты без жаргану
Эфект — гэта проста тое, што робіць ваш код і чыяе падае на вучорашні свет або стан працы. Возьмем рэўстрацію інструменту.
toolRegistry.add("search", searchTool)
Даўжыню рэйтынгу можна пабачыць да пачатку календара.
tools = {}
Пасля чаго ён зберагае новы інструмент.
tools = {
search: searchTool
}
Операцыя «фарвард» — гэта адынаван.
add(searchTool)
Адзеўніка Cordis хочаць кашто больш. Яна жадае, каб аперацыя мела свой сопрацэс відворачэння. Канцэптуальна, кожны эфект супакоўвае дзеянне з яго анулюванням.
Effect:
do: add search tool
undo: remove search tool
Без матэматычнай пазначкі ідэя выглядае так.
state --effect--> new state
new state --inverse--> original state
Гэты адварсны элемент ёсць ключовым, і Cordis называе весь комплекс такім эфектам, які можна анулюваць.
Кожная змяна выклікае неабходнае падчысткаванне
Cordis адкрывае гэта праз што-сабой на кшталт следуючага патэрна, дзе функцыя выконвае зміну і вяртае функцыю, якая ёё скасоўвае.
ctx.effect(() => {
registerSomething()
return () => {
unregisterSomething()
}
})
Час выканання прыкладніка застаўляе эфект, зберагае функцію для чысткі і вызывае яе пазней, калі прыкладнік знікае.
apply effect
↓
store cleanup function
↓
plugin runs
↓
plugin unloads
↓
run cleanup
Калі плагін мае калькольныя эфекты, яны прыкладзены ў аднам парадку.
effect A
effect B
effect C
Прачыцкія працэсы пасля гэтаго адбываюцца у зворачным напрамку, як распаковываецца стак.
undo C
undo B
undo A
Чаму трэба перадвінуць? Разглядзім плагін, які запускаецца так.
1. open database
2. start service using database
3. start agent using service
Закрыць усё за аднаковым порадком было б небяспечна, адзінакова база дадзеных закрываецца, калі прылады яшчэ ўжоўаюць яе.
close database
stop service
stop agent
Безпечны выклік — гэта працоўнае працэса.
stop agent
stop service
close database
Гэтае — пасляльгаванае, першыя выйдзе.
Last In
First Out
Cordis уключае такую прыемкі ў кантроль жыцёвага цыклу компонентаў.
Толькі зворачная чыстка недастаткова
Тут артыкул становіцца цякавей. Спачатку Плагін А зменяе спакульную значэнне, пасля чыго Плагін B таксама зменяе тое ж значэнне, а пасля чаго А прагча вярнуць тое, што бачыў спачатку. Гэта можа стэрць змяны, якія здзейсніў B.
Initial: x = 10
Plugin A: x = 20
Plugin B: x = 30
Plugin A unloads: restore x = 10
B яшчэ актыўны, але яго стан знік. Таму перадворачальныя эфекты ў безпекі толькі пад певнымі прыязначэннямі незалежнасці, якія артыкул формалізуе як незалежнасць эфектаў. У неформальным сэнсе два эфекты ёсць незалежныя, калі пры застосаванні або перадворачэнні адного не стае недзейнасцю значэння другога. Рэгістрацыя разных інструментоў зазвычай падпарадна, адколі яны вплываюць на разныя месца.
Plugin A registers tool "search"
Plugin B registers tool "calculator"
Замена той самай настройкі, верагацельна, не дапяе.
Plugin A replaces configuration X
Plugin B also replaces configuration X
Гэта разліка знову выйдзе на першы план, калі будзе вікорыстоўвана сістэма кантэксту Cordis.
Просторная складнасць: разумеўшы, што патрэбна плагіну
Часовая складнасць стосуецца таго, чы можа компонент быць адключаны без пахібок. Просторная складнасць стосуецца таго, чы сістэма розумее, ад чаго залежыць компонент. Уявіце сабе гэты плагін.
CodingAgent
Яму трэба тры рэчы.
LLM
ToolRegistry
SessionStore
Традыцыйны код можа выкарыстоўваць глобальныя зместы.
global.llm
global.tools
global.sessions
У такім случае архітэктура не мае рэальных ведамаў пра залежнасці. Cordis яныя выражае чыстаю мовай. Канцэптуальна плагін адзначае, што ён вводзіць.
inject: [
"llm",
"tools",
"sessions"
]
Цяпер жа час адканалення можа бачыць трэбаванні плагіна у вачынку дрэва.
CodingAgent
├── requires LLM
├── requires ToolRegistry
└── requires SessionStore
Гэта дазволяе яму рэагаваць, калі змянююцца тыя службы.
Рэактыўныя залежнасці
Гэта можа быць найлепшая ідэя ў Cordis. Падазроўваючы, што компоненту патрэбен LLM.
LLM
Спачатку нічога не існуе.
LLM unavailable
Таму компанент не можа стаць актыўным. Пазней запускаецца плагін-прадаўца і задае адны.
OpenAI Plugin loads
↓
provides LLM
↓
dependency becomes satisfied
↓
component activates
Як толькі такій аптэка будзе знішчана, яе можлівасці таксама знікаюць.
OpenAI Plugin unloads
↓
LLM disappears
↓
dependency becomes unsatisfied
↓
dependent component unloads
Калі запускаецца іншы прадаўца, гэтая можлівасць вяртаецца.
DeepSeek Plugin
↓
provides LLM
↓
component becomes active again
Залежнасці, такім чынам, не перакантролююцца аднойчы пад запуск. Яны ў рэакtyўнам стане, і самэ гэта прычына, чаму ў стацыянарным даследжэнні гаворыцца пра рэакtyўныя коефекты.
Эфекты проты коефектаў
Тэрмінологія здаецца складной, але разлік просты. Эфект — гэта тое, што зменяе компанента, праходзячы з плагіна ў сэрאвіс.
Plugin → Environment
Прыкладамі ўключаюцца гэтыя дзеянні.
register tool
open database
subscribe to event
start timer
Коефект — гэта тае, чаго компанент патрабуе ад свайго абявальнага прастору, калі гэта відбываецца у зворачным напрамку.
Environment → Plugin
Тыповымі прыкладамі ўсё гэтая патрабаванні.
need an LLM
need a logger
need session storage
need a tool registry
Спаўніце гэтыя два элементы, і трэбованні будуць трапляцца толькі ў адным напрамку.
requirements
Environment ───────────────────> Plugin
колі калянкі вяртаюцца назад.
Environment <─────────────────── Plugin
effects
Гэтае базовая ідэя, якая стоіць за Cordis. Компанента паказвае, чаго яна патрэбуе, што яна задаёць і якія зворачныя эфекты яна выканае.
I NEED these services.
I PROVIDE these services.
I PERFORM these reversible effects.
Прыгвыканне тады коордынуе цікл жыцця.
Звядзе каму падае тэрмін «спатыя-часовы»
Тады заглавье статты стае зрозумелым. Спатыяльная складаемасць стосуецца адносінаў межа компанентамі.
A depends on B
B provides X
C depends on X
Тэмпаральная складнасць стосуецца таго, як компаненты рухаюцца ў часе.
load
activate
replace
deactivate
unload
reload
Ўнія ўтвараюць цэлую філасофію.
Spatiotemporal composability = dependency-aware composition + reversible lifecycle changes
Об’ект кантэксту
DeepSeek Harness не перадае дзесяткі засобаў праз канстрактары вручную. Плагіны взаімаюцца праз спяльны кантэкст, які зазвычай называецца так.
ctx
У концэптуальнам сэнсе ён адкрывае основныя службы.
ctx
├── llm
├── tools
├── sessions
├── agents
├── agentLoop
├── logger
└── ...
Адзначыце, ctx — гэта не проста аб’ектура JavaScript, заполненая глобальнымі зместамі. Праз яе плагіні можаць знаходзіць свае залежнасці, запрошваць сервісы, рэгіструваць эфекты, слухаць за здарэннямі, ізаліцаваць рычаслі, перэхопляць доступ да сервісаў і коордынаваць цыклы жыцця, таму-ж Cordis прастаўляе кантэкст як аб’ект уніфікацыі.
З тэорыі да рэальнага праекту
DeepSeek Harness адкрывае сваія основныя падсістэмы праз гэты спакульны кантэкст.
ctx.sessions
ctx.systemPrompt
ctx.tools
ctx.agents
ctx.agentLoop
ctx.llm
Заўважыце нешта незвычнае: нават цыкл агента ёсць проста служба.
ctx.agentLoop
Такім чынам гэты цыкл можна заменіць, і ён не ўжо ёсць свяшчэнным кодам фрэймворку. Гэта ведае да галоўнага прынцыпа дызайну: не існуе прывілейваванага ядра, якое кожная функцыя павінна падтрымваць.
Чаму цыкл у фармаце плагіна мае значэнне
Большасць фрэймворкаў агентаў маюць центральны цыкл, падобны да гэтага.
while not finished:
response = model(history)
if response.tool_call:
result = execute_tool(response.tool_call)
history.append(result)
else:
return response
Потым кожна прыглая функцыя начынае яго мэнтаваць. Апраўленне пры выкананні каманд? Патч для ціклу. Аналіз падыходаў? Патч для ціклу. Перапрыбуткі, дэлегаванне многа-агентаў, іншы бэкенд для вычыслення? Патч для ціклу. У канцэ выходзіць гэта ў вачоўку, дзе знаходзяцца інструменты, мадэлі і памяць, якія ўсе прыўязаны да яго.
Agent Loop
/ | \
/ | \
tools models memory
/ | \
approvals retries tracing
Гэты цыкл стаець «богам об’ектам» прыкладнення. DeepSeek Harness ухілваецца ад гэтага, дазволяючы цыклу браты участак у той жа архітэктурэ плагінаў, як і всі іншы элементы.
Форма адной з роўнаў агента
Па суты, адносы межу прыкладненням і корантам праходзяць праз этапы, падобныя гэтым.
turn/start
↓
claim incoming user input
↓
assemble prompt + available tools
↓
agent/pre-step
↓
step/start
↓
record user message
↓
reconstruct conversation history
↓
send model request
↓
stream assistant response
↓
tool call?
│
├── yes → execute tool
│ record result
│ continue another step
│
└── no → finish
↓
step/end
↓
turn/end
Гэта важна таму, што кожны ўзлок паказвае запускаваныя заходы і меса з’ўязку служб, чым дае плагінам можлівасць браты удзел без перапісву всей сістэмы выканання.
Заходы у фармаце «водоспад» як мідлвэр
Cordis падтрымляе калькі спосабаў запуску заходаў. Аднам з прыемных спосабаў, «водоспад», ёсць працэс, які дзейнае як мідлвэр. Уявіце запіт, які праходзіць праз ланцюг аперацый.
request
↓
Plugin A
↓
Plugin B
↓
Plugin C
↓
LLM
Плагін B можа абсарбаваць выкананне за дапамою хэндлера, які прыме наступны крок.
async function handler(next) {
console.log("before")
const result = await next()
console.log("after")
return result
}
Выкананне тады ўскладнюецца, калі кожны плагін дзейнае як да, так і пасля внутраняга вызову.
Plugin A before
Plugin B before
Plugin C before
LLM
Plugin C after
Plugin B after
Plugin A after
Гэта включае правы на доступ, перапісвачанне запітоў, тэлеметрыю, кэшаванне, маршрутызацыю модэля, перакананні ў безпеці і введэнне кантэксту; нічога з гэтага не трэба прыўязваць жорстка ў адаптар модэля.
Модэль знаходзіцца за межамі можлівасцяў
Шасі таксама абстрагуе LLM, таму агенту не трэба розумець кожны SDK прадаўця — ён вяршыць вяснаўленні з аднам сервісам.
Agent
↓
ctx.llm
↓
Model Adapter
↓
Provider API
Адзін прадаўцы могу ўжоўваць гэта для API DeepSeek.
DeepSeek API
Іншыя статты прасвятаваюць OpenAI.
OpenAI
Трэці раздзел прысвечаны Anthropic.
Anthropic
Іншыя элементы архітэктуры агента таксама стосуюцца той самай можлівасці LLM. У дакументацыі Harness гэта іноды называецца «шваўком можлівасцяў», які складаецца з апісання службы і ўсталявальніка службы.
Service Definition
↓
Service Provider
↓
Consumer
Для LLM гэты ланцуг праходзіць ад інтарфейса да конкрэтнага прадаўцы.
LLM interface
↓
OpenAI provider
↓
Agent loop
Таму ададзенне прадаўцы модэля не значыць прынцыпова перапісвае рантайму. Вы проста задаёце іншую рэалізацыю той самай можлівасці.
Сесіі, базаваныя на з’явленнях
Размовы не зберагаюцца ў сістэме як адна вялікая зменная маса, якая служыць аднаковай інформацыёй. Сесіі замест таго зберагаюцца як струмэнь з’явленняў, да якога можна толькі дадаць новыя элементы.
turn/start
user/message
assistant/chunk
assistant/chunk
assistant/message
tool/call
tool/result
assistant/message
turn/end
Історыю модэлю можна перзбудаваць на адказе тых падзей, што робіць лог сэсіі аднаго правдзівым джэрэлам.
Session log = source of truth
Эта версія заменяе звычную альтэрнатыўную.
Mutable chat history = source of truth
Чаму агенты выгадваюць ад іспанавання event sourcing
Агенты сталі настолькі складнымі, што простая ліста паведамленняячасов часта не ўсё.
[
{"role": "user", "content": "..."},
{"role": "assistant", "content": "..."}
]
Для дырактуравання частае патрэбна інформацыя пра тое, які інструмент быў выкорыстаны і які запрашаны, якая модэль напісала адпаведны адказ, які сістэмны прамт быў застосаваны, дзе пачалося запрашанне, дзе завершылася практыка разумавання, якая конфігурацыя была актыўная, чыраз быў практыкаваны новы спроба і які выходны тэкст быў атрыманы. Сістэма фіксуе структураваныя запісы падзей сесіі, ўнаследке чаго можна перадаць усё, што могла бачыць модэль. Адна з прынцыпаў яе праектавання гласі, што все, што відна модэль, павінна быць можліва да вярнення з логаў. Уместа таго, каб спекуляваць пра тое, чаму агент павёл ся так, можна перадаць сама запрашанне, якое стало прычыной такога паведання.
Файберы і статус жыцёвага цыклу
Cordis выражае работаючыя компаненты за дапамою файбераў. Гэта не мае нічынага з файберамі операцыйной сістэмы. Файбер Cordis — гэта экземпляр компаненты часу выканання, які пераходзіць праз розныя статусы.
PENDING
↓
LOADING
↓
ACTIVE
↓
UNLOADING
↓
DISPOSED
Існуюць таксама станы неудачы. Што ўжо важлівей, волокно фіксуе кальколькі фактов пра сябе.
what dependencies I need
what providers currently satisfy them
what effects I have created
what cleanup functions belong to me
Калі змянююцца залежнасці, файбер можа аднавіць свой цыкл жыцця.
Чаму важна ідэнтыфікацыя прадаўца
Падазроўваючы, што компанента залежыць ад службы базы дадзенаў.
database
Зараз яго апраняець — адзін прадастальнік.
DatabaseProvider A
Падчас гарачага перзагрузкі ён заменяецца іншым.
DatabaseProvider B
Нават калі оба вяртаюць эквівалентныя об’екты JavaScript, Cordis можа розразіць ідэнтычнасць прадаўцаў. Прычына ў тым, што значэнне залежнасці — гэта не толькі наявнасць значэння.
"value exists"
Гэта таксама можа значыць, што значэнне падазало з іншага экземпляра компонента.
"this value came from a different component instance"
Такім чынам змена прадастоўца можа спрыяць правільнаму перзагрузчыку залежнасцяў, што дапамагае ухіліцца ад вялкай колькасці багоў, вызваных застарэлымі канектамі.
Звярнуць рэсурсы за порадкам залежнасцяў
Разглядзім чэргу, у якой адны плагін забезпечвае базу дадзенаў.
Plugin A provides database
Другі плагін завісіць ад базе дадзеных, а трэці — ад другога.
Plugin B depends on databasePlugin C depends on Plugin B
Ланцюг залежнасцей выглядае так.
A
↓
B
↓
C
Цяпер першы ўдалены. Наўатоўны час адработкі можа негайна закрыць базу дадзеных, хоця два іншыя элементы можа ўсё яшчэ выкананы. Cordis замест таго коордынуе граф завіснасцей. Пачынаецца выкачванне.
A begins unloading
Потым залежныя элементы адпрацоўваюцца па парадку, прычаму асалодны элемент завершае свою чыстку.
↓ mark A unavailableB notices dependency disappeared↓ B unloadsC notices B disappeared↓ C unloadsthenA completes cleanup
Парадак мае вельмі важлівое значэнне, адколі ён не дазволяе тым, хто залежыць ад іншых, вжываць тое, што ужо напалову знішчана.
Ізоляцыя: адна назва, разныя светы
Адзін глобальны прастор імен для служб можа стаць обмежэнням. Уявіце сабе два агента, якім патрэбны разныя базы дадзеных.
Agent A → Database A
Agent B → Database B
Оба яшчэ прасяць тое ж самае.
database
Cordis падтрымляе ізоляцыю, таму рашэнне проблем заслугвачае на адпрацоўку ў парах.
service name + isolation realm
і не толькі за іменем.
service name
Канцэптуальна кожны рэйм рашыяе тое ж самае імя на свой сабэй прыклад.
Realm A: database → DB_A
Realm B: database → DB_B
Тая ж самая логічная залежнасць можа рашыляцца адразу інакш, залежна ад кантэкста, што дапамагае у сістэмах з калькольнікаў, колькіх агентах, срэдах тэставання, плагінах у «сандбоксе» і адзельных рабочых прасторах.
Перэхопленне
Cordis таксама можа кантролюваць доступ да службаў за дапамогою метаданых. Узглядзіце рэжыстр інструментаў, дзе адміністратыўны агент можа бачыць гэтыя інструменты.
shell
browser
filesystem
deploy
У тое жа час агент з обмежанымі правамі бачыць меньшы набор.
browser
filesystem-readonly
У зменшэньне стварэння абсалютна самастоятнай базы даных, доступ можа быць перэхоплены ў залежнасці ад кантэксту.
ctx + metadata
↓
service resolution
↓
modified view of capability
Гэта сільны ўзор для сістэм правіл.
Безпечнейшая замена гарачага модуля
Гарачая перзагрузка здаецца простай.
file changed
↓
reload module
У часах выканання плагіна сітуацыя стае складней. Што, як новы модуль містыць бяг, і што тады станэцца застарэлай працюючай версіяй? Завантажвач Cordis падтрымае функцыю перзавантажэння, якая дзейнае як транзакцыя.
working plugin
↓
code changes
↓
attempt new import
↓
success?
┌───────┴───────┐
yes no
↓ ↓
replace rollback
plugin old module
Гэта парадоксальна гэта супакоўваецца з можлівасцю адворачэння эфектаў. Плагін з чыстым жыцёвым цыклам, наборам залежнасцей і спосабамі чысткі ў значныя меры менш апасны для замены.
Практычны прыклад
Cordis быў створаны не толькі для DeepSeek Harness. У стацыянцы рассматрываецца Koishi — фрэймворк чат-бота з адкрытым кодам, пабудаваны на ям, з экасістэмай спялочніны, якая, за словамі автараў, налічвае тыячы плагінаў. Працоўная экасістэма робіць дынамічную композіцыю значна пераканальвейшай, чым дзесяць ручна створаных модуляў. Тым не менш, у стацыянцы пазірна астарожнасць — автары не стверджуюць, што кантролюемыя тэсты паказалі значныя прыбыткі ў выдатнасці чы аўтаномнасці. Патрэбны ўжо большыя адлікі.
Не все можна анулюваць
Тут тэорыя зустрычаецца з рэальнасцю. Дзеякія эфекты пад час выканання справдзіва ўможлівыя да адворачэння, напрыклад, ачыненне і закрыцце файла.
open file
→ close file
Іншыя таксама добра паўтараюцца ў пары.
allocate memory
→ free memorystart worker
→ terminate workerregister event listener
→ unregister listener
Потым ідзе апрадка электрана.
send email
Калкулярным адварсам яго будзе што?
unsend email?
Зазвычай гэта немагчыма, і тое ж самае стосуецца групы іншых дзеянняў.
send HTTP request
transfer money
publish message
delete external data
Калі ўсё які-небудзь паўтарыцца ў зовнішнім свеце, справжняя перадзмена можа не існаваць. Найлепшыя доступныя варыянты — гэта компенсацыя.
payment → refund
message → follow-up correction
database mutation → compensating transaction
Кампенсацыя не ўзмаўляецца з матэматычным адворачэнням. У дакладзе чыста прызнаёмаецца гэтыя межы, і Cordis работае наўздоўж найкрашча для эфектаў, якія час выканання можа практычна контролаваць і вярнуць.
Cordis паверае вашаю чыстка
Падазроўваеце, што плагін запускае сервер унутрь эфекта і вяртае функцыю чысткі.
ctx.effect(() => {
startServer()
return () => {
// supposedly cleanup
}
}))
Cordis не мае можлівасці даказаць, чы рэальна процедура чысткі справаўна зворачае працэс запуску. Формальная модэль стверджвае, што інверсія павінна вярнуць срэду ў яе пачатковы стан, але рэалізацыя залежыць ад таго, чы програміст напісае правільны код для звярнення рэсурсоў. Таму спаўненне певнага эфекту разам з процедурой чысткі ўтварае адзін практычны прыем.
effect + cleanup
Гэта не автаматычная формальная верыфікацыя, і гэта важныя разлік.
Чаму гэта падходзіць для агентаў AI
Традыцыйныя прыкладнікі застаюцца досыта стабільнымі пасля запуску. Агенты рухаюцца в іншым напрамку. Будучыя сістэмы агентаў можаць неперывна выкананы такія операцыі.
install tool
remove tool
change model
spawn agent
kill agent
load skill
reload code
switch permissions
connect service
disconnect service
modify environment
Уявіце агента, які рашыраецца, што ў яго патрэбна падтрымка GitHub, і заваношае адпаведную можнасць GitHub, а пазней адмовляецца ад яе, калі ёна больш не патрэбная, або заменяе нерабочую рэалізацыю. Такой сістэме патрэбны значна сільнейшыя семантыкі складання пад час выканання, чым можа запростаць звычны інжэктар залежнасцяў. Без іх агент, які працуе довга, мога скупляць залішкі.
orphan listeners
stale tools
dangling processes
broken dependencies
zombie services
duplicated handlers
Cordis стараецца ператворыць кампанаванне пад час выканання ў прынцыповую канцэпцію програмнага забезпечэння.
Чаму дызайн здаецца элегантным
Калі Cordis абавяраецца кампанаванням, DeepSeek Harness можа мадэляваць практычна все адной і той жа способам.
Model provider → plugin
Tool → plugin
Agent loop → plugin
Session store → plugin
UI → plugin
Telemetry → plugin
Approval system → plugin
Sandbox → plugin
Credential store → plugin
Новыя функцыі не стаюць спецыяльнымі варыянтамі ў мэжах фрэймворку. Яны становяцца ўчаснікамі адной сістэмы складання.
Прафілі і пакеты
Калі ўсё ёсць плагінамі, ніхто не хоча кожы раз вручную складаць п’ятдэсят з іх. Таму фрэймворк додае складанні вышэйшага роўня. Профіль опісвае названую конфігурацыю сістэмы, а пакет распадзяляе групы плагінаў разам з іх конфігурацыямі. Базовы пакет можа выглядаць так.
Base Bundle
├── model adapters
├── tools
├── sessions
├── sandbox
├── approvals
├── credentials
├── settings
└── telemetry
Іншы пакет можа дадзіць веб-даплікацыю.
Web Application
Іншы варыянт могаў бы стварыць агента без галавы.
Headless Agent
Архітэктура застаецца модульной, не ператвараючы ўжыванне ў часоўны трыбулет.
Пяць ідэй, якія варта запамятаць
Калі все інша знікне, гэтыя пяць пунктав ўважаюцца тымі, якія трэба памятаць.
Перш за ўсё — можлівасць вярнуць стан: кожныя змены, якія вносіць компонент, должны маты спосаб іх анулювання.
change + inverse
Другій разлік — рэакtyўныя саэфекты. Компаненты заявляюць, што ў іх патрэбна, а сістэма запуску рэагуе, калі з’яўляюцься, знікаюць або зміняюцца залежнасці.
dependency available → activate
dependency gone → deactivate
Трэці элемент — гэта кантэкст. Эфекты, залежнасці і доступ да службах выконваюцца в межах адного аб’еднанага кантэкста выканання.
ctx
Чатвертым ёсць дынамічны калькул складовых, які опісвае складовую па тым, калі ёй трэба, калі ёна задае і калі ў яе відбуваюцься змяны, задаючы часе адработкі достатню структуру для аналізу завантажэння і вывантажэння.
Dependencies + Provisions + Effects
Пятым ёсць прастора-часовая складнасць, якая спаўнюе прасторовыя і часовыя аспекты.
spatial:
who depends on whom?
+
temporal:
how can components safely enter and leave?
Якфраза, гэта — зворачныя змены плюс рэакtyўная залежнасць.
Чаму гэта мае значэнне не толькі для адного праекту
Большасць сучасных фрэймворкаў агентаў яшчэ прыпускае дасыць статычныя прыкладнення: запускаецца програма, завантажуюцься інструменты, завантажваецца модэль, запускаецца агент, ён зупіняецца. Аўтонамныя агенты прагнуць да такіх срэдаў выканання, якія можуць самі сабе менаваць, заставаючыся актыўнымі. Уявіце сабе агента, які можа выконваць такую последовасць дзеянняў.
discover a capability
install it
use it
upgrade it
replace it
remove it
continue running
У такі моменты калектраванне жыццёвага цыклу плагіна перастае быць прыемным архітэктурным элементам і стае фундаментальной інфраструктурой. Самэць гэта і робіць праект цікавым. Мадэль не ўсё така ужо і новая частка; новыя ўмовы яе працы.
Глэбэйшы урок
Архітэктура програмнага забезпечэння зазвычай стосуецца складання элементаў у певны момент часу. Вы складаеце часткі і запускаеце прыграму.
A + B + C
Cordis задае ўжо болей складныя запытанні.
What if A disappears?
What if B is replaced?
What if C suddenly gains a dependency?
What if another implementation of A appears?
What if all of this happens while the system is running?
Гэта цэлкам змінюе проблему. Компаненты перастаюць быць статычнымі блакамі і працуюць як жывыя учаснікі: яны прыбываюць, ствараюць адносіны, зменяюць свое абаканаве, залежаць ад іншых і ў канцы канца выйшаюць.
Вывад
DeepSeek Harness можа выглядаць як ўсё той жа фрэймворк агента, і яго прыемнасць не ў тым, што ён можа вызваць LLM або запускаць інструменты, што робяць багато фрэймворкаў. Глыбокая ідэя заключаецца ў тым, што сама сістэма складання являецца архітэктурой. Кожная можлівасць — гэта компанент, кожная залежнасць ёсць явной, кожны контролюемы эфект ведае, як сам сабе адчыстыць, компаненты рэагуюць, калі змінююцца залежнасці, а нават цыкл агента можа быць заменены і не ёсць недаступным кодам фрэймворка. Кансэпт закладаецца на тое, каб кожная можлівасць была компанентам, кожная залежнасць — явной, а кожны эфект меў свой спосаб анулювання.
У звычных прытках гэта ўпорадкованая архітэктура плагінаў. У дзейнічых, самамодыфікуючыхся агентах ШЫ гэта можа мець набагато большое значэнне. Калі агенты з часам будуць змянюваць свой сэрвісны час, програмнае забезпечэнне будзе патрабаваць прыемлівага спосабу змены, калі не паспяшаць поступова пашкадзіць серавысьць, у якой яно працюе. Гэтая проблема, яку прагне рашыць DeepSeek Harness і даследжэння Cordis, якія стояць за ўсім гэтым.