00 · 시작하기 전에
시작하기 전에
공식 튜토리얼은 소스에서 DeepSeek Harness를 실행할 수 있다고 가정합니다. 저장소 루트에서 작업하세요.
- deepseek-ai/deepseek-harness 로컬 체크아웃
- 저장소 패키지 관리자로 의존성 설치 완료
- 저장소 루트에 열린 터미널
- 체크아웃과 호환되는 Node.js 및 pnpm
DeepSeek Harness와 플러그인 계약은 개발자 프리뷰입니다. 개발 revision을 고정하세요.
1단계
로컬 플러그인 프로젝트 생성
Harness 저장소 안에 임시 프로젝트를 만들어 로드 경로를 명확하고 쉽게 제거할 수 있게 합니다.
mkdir -p scratch-plugin/src2단계
플러그인 모듈 작성
Harness 플러그인은 apply 함수를 내보내는 TypeScript 모듈입니다. Cordis Context를 통해 기능을 등록합니다.
scratch-plugin/src/my-plugin.ts를 만들고 로그로 로드 성공을 확인합니다.
import type { Context } from '@deepseek-ai/cordis'
export const name = 'hello-plugin'
export function apply(ctx: Context) {
// Required dependencies are ready before apply runs.
console.log('[hello-plugin] plugin loaded!')
}3단계
cordis.yml에 등록
저장소 루트에서 pwd를 실행하고 scratch-plugin/cordis.yml을 만듭니다. 예제 경로를 실제 절대 경로로 바꾸세요.
- insert:
- id: hello
name: '/absolute/path/to/deepseek-harness/scratch-plugin/src/my-plugin.ts'4단계
오버레이로 Web UI 시작
저장소 루트에서 Patch 파일로 Web UI를 시작하고 http://127.0.0.1:3080을 엽니다.
pnpm dsh web --patch ./scratch-plugin/cordis.yml05 · Cordis
수명 주기와 서비스 의존성
타이머, 연결, 도구 또는 공유 기능을 소유하기 전에 Cordis의 정리와 의존성 메커니즘을 이해하세요.
ctx.effect()로 부작용 정리
Context 등록은 플러그인과 함께 제거됩니다. 타이머나 연결처럼 명시적 해제가 필요한 자원은 ctx.effect()에서 정리 함수를 반환합니다.
import type { Context } from '@deepseek-ai/cordis'
export function apply(ctx: Context) {
ctx.effect(() => {
const timer = setInterval(() => {
console.log('heartbeat')
}, 5000)
// Runs automatically when the plugin unloads.
return () => clearInterval(timer)
})
}inject로 서비스 의존성 선언
tools, llm 또는 다른 서비스가 필요하면 inject에 선언합니다. 서비스 준비 후 apply가 호출됩니다.
import type { Context } from '@deepseek-ai/cordis'
export const name = 'my-tool-plugin'
export const inject = ['tools']
export function apply(ctx: Context) {
// ctx.tools is ready here.
ctx.tools.register(/* ... */)
}06 · API
가장 단순한 플러그인 형태 선택
함수, 객체와 클래스 형태를 지원합니다. 함수로 시작하고 다른 플러그인에 서비스를 제공할 때만 Service 클래스를 사용하세요.
함수
집중된 기능에 적합하며 읽고 테스트하고 언로드하기 쉽습니다.
객체
name, inject, apply와 메타데이터를 함께 구성할 때 유용합니다.
Service 클래스
명명된 Cordis 서비스를 제공하고 수명 주기를 소유할 때 사용합니다.
객체
export default {
name: 'my-plugin',
inject: ['tools'],
apply(ctx: Context) {
// Register capabilities here.
},
}Service 클래스
import { Service, type Context } from '@deepseek-ai/cordis'
export default class MyService extends Service {
static inject = ['tools']
constructor(ctx: Context) {
super(ctx, 'myService')
// Perform synchronous initialization here.
}
}07 · Verify
검증 체크리스트
프로세스 시작만 확인하지 말고 로드 경로, 수명 주기와 제거 동작을 확인하세요.
- 127.0.0.1:3080에서 Web UI가 열립니다.
- hello-plugin 로드 메시지가 한 번 출력됩니다.
- 잘못된 절대 경로에서 이해 가능한 오류가 발생합니다.
- 언로드 후 타이머와 효과가 정리됩니다.
- Patch 제거 후 원래 Web Profile 동작으로 돌아갑니다.
자주 발생하는 문제
모듈을 찾을 수 없음+
cordis.yml 경로가 절대 경로이며 현재 .ts 파일을 가리키는지 확인하세요.
로드 로그 없음+
저장소 루트에서 실행하고 --patch 경로를 확인하세요.
서비스가 undefined+
서비스 이름을 inject에 넣고 apply 이후에 접근하세요.
3080 포트 사용 중+
해당 프로세스를 중지하거나 현재 업스트림 옵션을 확인하세요.