Cordis 입문
Cordis는 DeepSeek Harness의 기반이 되는 벤더링된 플러그인 프레임워크입니다. 이 입문서에서는 하위 시스템 페이지의 서비스/이벤트 참조를 읽기 전에 Harness 플러그인 작성자가 알아야 할 Cordis 개념을 설명합니다. Cordis 튜토리얼에서는 같은 개념을 실습으로 안내합니다. 벤더링된 소스와 동기화 절차는 vendor/README.md에 있습니다.
Cordis의 다섯 가지 핵심 개념
- 플러그인은 Service를 구현하는 객체입니다. 선택적
inject및apply(ctx)필드를 가진 함수이거나, Cordis가 현재 컨텍스트에 수명 주기를 마운트하는Service하위 클래스일 수 있습니다. - 컨텍스트는 서비스 저장소입니다. 서비스는 컨텍스트에서
ctx.<key>,ctx.tools또는ctx.llm같은 안정적인ctx.sessions를 점유합니다. 다른 플러그인은 구체적인 구현을 가져오는 대신 키를 통해 서비스를 찾습니다. inject를 통해 서비스 종속성을 선언합니다. 필수 서비스를 지정한 플러그인은 해당 서비스가 존재할 때까지 대기하므로, 수동 부팅 순서 지정이 아니라 서비스 요구 사항으로 로드 순서를 표현합니다.- 통신을 위한 타입 지정 이벤트입니다. 서비스는 TypeScript 선언 병합을 통해 이벤트 이름을 선언한 다음, 리스너가 관찰, 래핑, 팬아웃 또는 순차 실행하는 방식에 따라
emit,waterfall,parallel또는serial로 이를 디스패치합니다. - 등록은 되돌릴 수 있는 효과입니다. 프롬프트 섹션, 도구 스키마, 어댑터, 프로바이더 및 리스너는
ctx.effect()또는ctx.on()를 통해 설치되므로, 다시 로드하거나 해제할 때 예측 가능하게 되돌릴 수 있습니다.
디스패치 모드
각 이벤트는 다음 디스패치 모드 중 하나를 가질 수 있으며, 이에 따라 해당 메서드로만 디스패치할 수 있습니다.
| 모드 | 대기 여부 | 디스패치 순서 | 반환 값 여부 |
|---|---|---|---|
emit | 아니요 | 리스너가 등록 순서대로 관찰 | 아니요 |
waterfall | 아니요 | 리스너가 등록 순서대로 관찰 | 예 |
parallel | 예 | 모든 리스너가 이벤트를 병렬로 관찰 | 아니요 |
serial | 예 | 리스너가 등록 순서대로 관찰 | 예 |
디스패치 모드는 이벤트 공개 계약의 일부입니다. 새 Harness 이벤트는 @mode 태그로 이를 문서화하므로, 생성된 카탈로그가 선언과 디스패치 지점을 대조할 수 있습니다.
Cordis 워터폴 의미론
ctx.waterfall는 주변 미들웨어입니다. 리스너는 (...args, next)를 받습니다. next()를 호출하면 래핑될 수 있는 결과를 다음 서비스에 위임하며, next() 없이 반환하면 단락합니다. 값은 next()의 반환 값을 통해 전파됩니다.
협력하는 리스너는 일반적으로 공유 요청 또는 결정 객체를 변경한 후 위임합니다. 리스너는 결과 전체를 교체할 수도 있으며, 이후 리스너는 교체 후의 결과만 볼 수 있습니다. 리스너가 일반 등록보다 먼저 실행되어야 할 때만 prepend: true를 사용합니다.
단일 결정 이벤트에서는 단락이 설계 의도입니다. 정책 리스너는 결정을 담당할 때 next() 없이 반환할 수 있지만, 주석을 추가하거나 관찰만 하는 리스너는 위임해야 합니다.
로더 구성
@deepseek-ai/cordis-plugin-include는 !!js를 표현식 노드로 구문 분석합니다. Loader는 항목의 config(선언된 주입이 활성화된 후 해당 플러그인 컨텍스트를 기준으로 — ctx.serviceName)와 disabled 필드(모든 마운트 결정 시 로더 컨텍스트를 기준으로)를 보간합니다. Include는 대상 활성화 시점까지 중첩 행 표현식을 보존합니다. 다른 항목 메타데이터는 리터럴로 유지됩니다. 환경에서 플러그인을 선택하는 경우 오버레이를 사용합니다.
실용적인 규칙
동작을 플러그인으로 캡슐화합니다. 도구 파이프라인 이벤트는 ctx.tools에, 모델 스트리밍은 ctx.llm에, 실시간 에이전트 조정은 ctx.agents에 속합니다. 가로채기와 정책에는 이벤트를, 직접 기능 호출에는 서비스 메서드를 우선 사용합니다.
모든 등록에는 해제자가 있어야 합니다. ctx.effect()에서 해제자를 반환하거나 이를 대신 처리하는 Cordis 도우미를 사용합니다. 해제 순서가 중요하다면 관련 작업을 하나의 효과에 유지하여 의도한 순서로 정리가 되돌려지도록 합니다.