Issue 01중국 AI
AC POST
중국 AI 목록
掘金2026년 11월 4일 22:21중국어 → 한국어

dsh-superagent, DeepSeek이 공개한 능동형 코딩 에이전트原型

deepseek harness 팀이 공개한 슈퍼 에이전트 아키텍처 원형 dsh-superagent는 스스로 작업을 맡아 처리하며 사람의 주의를 적게 차지하는 것을 핵심 원칙으로 한다.

중국어 원문을 AI로 번역했습니다. 고유명사와 수치는 원문 표기를 우선하며, 중요한 판단에는 아래 출처 원문을 함께 확인하세요.

서문

팀 전체의 일을 대신 처리할 수 있는 에이전트는, 팀 전체의 주의를 낭비하게 만들 수도 있다.

이 글은 "하루에 하나씩 오픈소스 프로젝트" 시리즈의 253번째 글이다. 오늘 소개할 프로젝트는 dsh-superagent (deepseek-ai/dsh-superagent-prototype)이다.

먼저 README 첫머리의 선언을 앞에 두겠다. 그것이 중요하기 때문이다. 이것은 오직 참고용 연구 프로토타입이며, DeepSeek의 공식 제품이 아니다. 코드는 팀의 일상 개발에서 나온 것이고, 그중 상당한 엔지니어링 작업은 프로그래밍 에이전트가 완성했다. 이는 내부 버전과 완전히 같지도 않고, 논문 《Exploring Super-agent Design: Towards a More Autonomous Agent System》에 묘사된 구현과도 같지 않다. 글에서 논의하는 일부 설계는 미래의 방향일 뿐이며, 프로토타입에는 구현되어 있지 않다.

그렇다면 읽을 가치가 있는 곳은 어디일까? 코드의 성숙도가 아니라 설계 문서에 있다. 저장소 안의, 순서대로 읽도록 된 아홉 편의 문서가 "능동적으로 일하는 에이전트는 어떻게 자제해야 하는가"를 매우 구체적으로 설명한다. 언제 나서야 하고, 언제 반드시 입을 다물어야 하며, 권한을 어떻게 부여하고 어떻게 회수할지, 하나의 티켓이 어떻게 시작되고 이어지고 끝나는지를 다룬다.

무엇을 배우게 되는가

- dsh-superagent가 무엇이며, 그것이 DeepSeek Harness와 어떤 관계인지

- 핵심 원칙 "주의를 적게 차지하고 가치를 많이 준다"가 어떻게 구체적 설계로 구현되는지

- Source, Trigger, Thread, Eval, Mandate, Ticket이라는 도메인 모델

- 권한 부여와 진입 허가: 누가 에이전트를 일하게 할 수 있는지, 능동적으로 일하는 것이 왜 기본적으로 기록만 하고 실행은 하지 않는지

- 하나의 티켓에 대한 실행, 전달, 그리고 장애 복구

- 한계와 적용 경계

사전 지식

- GitHub의 Issue, Pull Request, 알림을 사용해 본 적

- 프로그래밍 에이전트(Claude Code, Codex, DeepSeek Harness 등)의 기본 개념을 이해

- "자동화 에이전트에 어떻게 경계를 설정할 것인가"에 관심이 있음

프로젝트 배경

프로젝트 소개

dsh-superagent는 단일 GitHub 저장소를 지키는 능동형 프로그래밍 에이전트로, bundle 형태로 DeepSeek Harness(약칭 DSH)에 패키징되어 제공된다.

README의 설명은 이렇다. 그것은 GitHub를 감시하고, 페이수(Feishu)도 감시할 수 있다. 허가된 사람이 그것에 작업 요청을 하면, 그것은 티켓을 열고 자신의 Agent Session과 디렉터리 안에서 일하며, 원래의 대화에 회신한다. 예를 들어 하나의 Pull Request를 통해 회신한다. 웹 패널은 사람이 처리해야 할 것만 보여준다.

DeepSeek Harness에 관해: 공식 사이트의 설명에 따르면, 그것은 DeepSeek이 오픈소스로 공개한 harness로, Cordis의 "모든 것이 플러그인" 아키텍처 위에 세워졌으며, 데스크톱 애플리케이션으로 실행할 수도 있고 코드에서 Web 인터페이스를 시작할 수도 있으며, 현재 전 세계 공개 프리뷰 단계에 있다. dsh-superagent는 바로 이 체계 안의 플러그인 패키지다.

저자와 팀

- 제작: DeepSeek (GitHub 조직 deepseek-ai)

- 생성 시각: 2026-10-31, 현재 커밋이 한 번뿐임 ("feat: add the dsh-superagent research prototype")

- 상태: 연구 프로토타입, README는 "여전히 버그가 있을 수 있고, 코드 스타일과 엔지니어링 관행이 일관되지 않을 수 있으니, 사용 전에 검토하고 조정하라"고 알린다

프로젝트 데이터

데이터는 2026-11-03의 GitHub에서 가져온 것으로, 참고용이다:

- ⭐ GitHub Stars: 약 15,500 (생성된 지 겨우 사흘)

- 🍴 Forks: 약 1,660

- 📄 License: MIT

- 💻 언어 구성: TypeScript 약 200만 바이트, 그 밖에 소량의 CSS와 Python

- 📦 의존 실행 환경: Node.js 22.19+ 또는 24+, pnpm, git 2.32+, tmux, Python 3.8+, GitHub CLI 2.48+, 그리고 engines.dsh 범위에 부합하는 DSH

- 🌐 DSH 공식 사이트: deepseek.com/en/harness

주요 기능

핵심 역할

그것이 하고 있는 일은 다음과 같은 하나의 흐름이다:

- 감시: GitHub의 알림, 관심 있는 Issue와 PR, CI 변화, PR 병합 또는 종료; Feishu의 실시간 이벤트와 토픽 폴링

- 판단: 허가된 사람이 여기서 명확히 @IT를 해야만 하나의 요청으로 간주된다. 아무도 요구하지 않은 일은 팀이 미리 작성한 규칙이 있어야만 할 수 있다

- 착수: 요청마다 티켓을 하나 열고, 그것에 독립적인 Executor Session과 독립 디렉터리를 부여한다

- 전달: 결과를 원래 대화로 회신한다. 보통 하나의 Pull Request로

- 보드: Web 패널은 사람이 처리해야 할 것만 나열하며, 건강 상태는 자리를 차지하지 않는다

사용 사례

팀 저장소의 일상적인 잔일

- Issue에서 @agent 요청: 1분 정도 지나면 티켓이 나타나고, 이어서 확인 회신과 후속 PR을 본다

Feishu 그룹에서 요구 사항 제기

- 봇을 구성한 뒤, 허가된 사람이 그룹에서 그것을 @한다

PR 리뷰 후의 후속 조치

- 리뷰 의견과 CI 결과가 "구독"을 통해 해당 티켓으로 돌아오고, 에이전트가 계속 수정한다

팀 규칙에 따라 능동 작업 수행

- 예를 들어 특정 유형의 의존성 업데이트를 처리하도록 규칙을 작성해, 먼저 observe 모드에서 "원래라면 수주했을 것"을 기록만 하고, 확실하다고 확인되면 auto로 전환한다

에이전트를 동료처럼 관리하기

- 패널에서 할 일, 승인, 재시도, 일시정지를 보는 것이지, 잔뜩 쌓인 로그를 들여다보는 것이 아니다

빠른 시작

공식 방식 자체가 흥미롭다. 설치 단계가 많아서, 에이전트가 함께 해주도록 하는 것이다.

당신의 프로그래밍 에이전트에게 이렇게 말한다:

Read SETUP.md in this repository and set up dsh-superagent with me.

SETUP.md는 에이전트가 읽도록 쓰인 설치 절차로, 그것은 이 설치 에이전트 자신도 "주의를 적게 차지한다"를 준수하도록 규정한다:

- 먼저 SETUP.md와 docs/000-philosophy.md만 읽고, 탐지 명령을 한 번 실행하며, 답을 다 모으기 전까지는 아무것도 더 읽지 않는다

- 각 메시지마다 한 번에 한 가지 질문만 하고, 한 메시지마다 300자를 넘지 않으며, 모든 질문에는 "한 단어로 수락할 수 있는" 추천 답을 붙인다

- 질문하는 동안에는 실행하지 않고, 답을 다 모은 뒤 완전한 방안을 제시하며, 당신이 확인한 다음에야 움직인다

- 채팅에서 절대 키를 요구하지 않는다. 당신이 직접 해야 하는 단계(계정 생성, CLI 로그인, 앱 키 입력)는 하나의 메시지로 모아서, 당신의 터미널에서 실행할 명령을 제시한다.

질문의 순서는 도메인 모델을 따라간다. 먼저 요청이 어디서 오는지(깃허브만인지 페이수(飞书)도 함께인지, 어느 저장소인지, 어느 깃허브 계정인지) 묻고, 그다음 누가 요구 사항을 제기할 수 있는지 묻고, 마지막으로 에이전트가 티켓을 어떻게 처리할지(로컬 클론 위치, 커밋 서명, 자동 병합 여부) 묻는다.

기본값도 매우 보수적이다:

- 별도의 profile superagent, 포트 3082

- 브랜치 접두사 agent/

- 접수 모드 observe (기록만 하고 실행하지 않음)

- 커밋 서명은 에이전트 자신의 계정 사용

- 자동 병합 기본값은 关闭(꺼짐): 에이전트의 PR이 한동안 신뢰할 만해지기 전까지는 사람이 병합

수동 설정 예시 profile은 아주 짧다:

- id: webserver config: host: 127.0 .0 .1 port: 3082 - id: dsh-superagent config: stateDir: <절대 경로, 예: /home/me/.dsh/state/superagent> # 페이수(飞书) 선택 사항 # - id: dsh-superagent-feishu # disabled: false

개발자 명령: pnpm check 는 타입 검사, 테스트, 빌드를 순서대로 실행한다.

핵심 특성

요청받거나 규칙이 허용할 때만 행동한다

- 요청은 반드시 에이전트를 직접 지목해야 하며, 팀이 허용한 사람으로부터 와야 한다

누군가 반드시 행동해야 하거나 결과를 쓸 수 있을 때만 말한다

- 한 번 확인하고, 작업할 때는 조용히 있다가 결과가 나오거나 결정이 필요하거나 완료할 수 없을 때만 다시 메시지를 보낸다

한 번에 하나의 구체적인 질문만 한다

- 구조화된 필드로 질문해서, 질문이 긴 보고서에 묻히지 않고 실제로 사람에게 전달되게 한다

작업량이 아니라 영향으로 멈춘다

- 국소 변경은 리뷰 가능한 결과까지 한다; 설계 결정이 필요한 변경은 멈추고 묻는다

정직하게 보고한다

- 초안은 미완성으로 표시하고, 실패하면 실패라고 보고하며, 제약을 만나면 우회하지 않고 묻는다

팀이 글로 행동을 빚는다

- 세 개의 팀 프롬프트 단락(커뮤니케이션, 티켓 범위, 납품 요건)에 팀 Skill을 더해 대부분의 요구를 커버한다

프로젝트 장점

비교 항목 dsh-superagent 터미널에서 수동으로 프로그래밍 에이전트를 부르기 흔한 깃허브 봇 트리거 방식 Issue / 그룹에서 @ 하면 되고, 비동기 터미널 앞에서 사람이 대기 고정 이벤트 트리거 권한 경계 화이트리스트 + 권한 부여 기록 + 입장표, 호스트가 강제 집행 현재 세션에 따라 다름 스크립트에 따라 다름 주동성 있음, 그러나 기본은 기록만, 규칙은 팀이 작성 없음 있음, 그러나 로직이 하드코딩됨 사람에 대한 방해 설계 목표 자체가 최소화 없음 흔히 매우 시끄러움 감사 가능 패널에서 Trigger → Eval → Ticket 추적 가능 터미널 기록 열람 로그 열람

왜 읽을 가치가 있는가?

- "주동적 에이전트"의 절제를 구호가 아니라 실행 가능한 규칙으로 써 놓았다

- 권한 모델이 매우 세밀하다: 누가 착수하게 할 수 있는지, 착수 후 어디까지 갈 수 있는지, 규칙이 바뀌면 어떻게 되는지 모두 설명되어 있다

- 문서가 번호 순서대로 점진적이며, 각 문서는 앞선 문서에만 의존하므로 하나의 설계 문서 표본으로 삼을 수 있다

프로젝트 상세 분석

한 문장 철학: 주의력은 비용이다

docs/000-philosophy.md 는 3천 바이트에 불과하지만, 프로젝트 전체가 이로부터 펼쳐진다:

Take as little human attention as possible, and give as much value as possible.

모든 메시지, 알림, 질문, 설정, 패널 요소, 나아가 문서 한 단락까지도 누군가의 주의력을 소모하므로, 모든 항목은 그것이 소모하는 것보다 더 많은 가치를 내놓아야 하며, 그렇지 않으면 삭제한다.

이 원칙은 에이전트에 대한 요구(앞의 "핵심 특성"에 이미 나열됨)를 이끌어내는 동시에 설계 자체에 대한 요구도 이끌어낸다:

- 개념이 적어야 한다: 설계에는 도메인 개념(예: Source)과 그 구체적 구현(예: GitHub, 페이수)만 있고, 비즈니스 요구는 새로운 개념을 추가하는 대신 그중 어떤 개념의 속성이나 에이전트가 따르는 프롬프트가 된다

- 설정이 적어야 한다: 하나의 기본값이 거의 모든 팀에 적합하면 설정 대신 기본값을 쓴다; 팀이 글로 설명할 수 있는 행동은 프롬프트 텍스트이지 설정이 아니다

- 패널은 사람이 처리해야 할 것만 보여준다: 건강 상태는 공간을 차지하지 않는다

- 문서는 순서대로 읽는다: 각 번호 문서는 앞선 문서에만 의존한다

마지막 절은 "책임"이며 아주 직설적으로 쓰여 있다: 에이전트는 팀이 매일 볼 수 있는 계정으로 댓글을 달고, PR을 열고, 메시지를 보내며, 그것이 보내는 모든 한 줄 한 줄은 동료의 주의력을 소모하므로, 책임은 운영자에게 있다.

- 좁게 시작하라: 화이트리스트를 짧게, 주동적 작업은 먼저 기록만; "본래 무엇을 할지"가 맞아 보이면 그때 넓혀라

- 소음을 줄이도록 조율하라: 시끄러울 때는 프롬프트를 더 짧고 엄격하게 쓰거나 잠시 멈춰라, 소음을 설명하려고 메시지를 더 보태지 마라

- 그것으로 양을 채우지 마라: 대량 PR, 브로드캐스트 메시지, 분주한 움직임은 팀이 쓰는 것보다 더 많이 소모한다

- 그것이 하는 말에 책임져라: 그것이 당신의 이름으로 보내는 내용을 읽고, 틀렸으면 프롬프트에서 바로잡아라

마지막 문장은 이렇다: "목표는 맞는 시간에 맞는 도움을 주는 것이고, 그 밖의 시간에는 아무것도 하지 않는 것이다."

도메인 모델: Trigger에서 Ticket으로

docs/001-domain.md 는 전체 개념 체계를 정의한다. 주된 흐름은:

작업은 Trigger에서 Eval을 거쳐 실행으로 흐른다. Source가 Trigger를 생성하고, Trigger는 그 Thread를 구독한 Ticket에 컨텍스트로서 팬아웃된다. 이런 방식으로 어떤 Ticket에 도달한 사람의 메시지는 그 Ticket에 남고, 그 밖의 모든 Trigger는 Eval로 들어가 Eval이 새로운 작업 요청인지 판단한다. Eval이 접수하면 Mandate를 가진 Ticket을 생성한다. Assignment가 Ticket을 Executor에 넘기고, 결과는 Channel을 거쳐 Source로 돌아간다.

핵심 개념(괄호 안은 문서에서 제시한 중국어 명칭):

개념 의미 그것이 유지하는 규칙 Source(来源) 이벤트 흐름, 가령 GitHub나 페이수. 자신의 읽기 위치와 봇 신원을 저장한다. 자신의 봇 메시지는 버린다. 재시작해도 이벤트를 재생할 수 없다. Trigger(触发) 하나의 불변 이벤트. 두 번 접수해도 Ticket을 하나만 생성한다. 감사와 멱등성의 단위다. Thread(스레드) 시간순으로 배열된 Trigger. 같은 시각에 최대 하나의 Eval만 존재할 수 있다. Ticket은 여러 장일 수 있다. Channel(채널) Thread의 쓰기 끝단. 확인, 답장, PR, 해결된 리뷰가 모두 쓰기다. Policy(정책) 버전이 붙은 평가 규칙, 그리고 각 Source의 일부(누가 작업을 발의할 수 있는지 등). 규칙이 바뀌면 실행 중인 Eval은 반드시 폐기해야 한다. Eval(평가) 한 무리의 Trigger에 대한 판단으로, 진입과 판단 두 계층으로 나뉜다. 상태가 없으며, 하나의 Decision을 출력한다. Mandate(위임) 수주 시 부여되는 것: 정책 버전, 범위, 강도, 매칭 규칙, 발신자 신원. 불변이다. 범위가 넓어지면 새 Ticket을 열어야 한다. 사람의 중지만이 이를 철회할 수 있다. Ticket(티켓) 위임된 작업 단위. 오직 Eval만 생성할 수 있다. 자체 상태를 가지며, Executor를 따르지 않는다. Assignment(배정) Ticket과 하나의 Executor 인스턴스의 결속. 하나의 Ticket은 시간에 따라 여러 개를 가질 수 있다. Subscription(구독) Ticket과 Thread의 다대다 관계. 후속 논의는 더 이상 @ 없이도 실행자에게 도달할 수 있다.

두 가지 설계는 잠시 멈춰 볼 만하다.

첫째, "사람"은 도메인 개념이 아니다. Trigger는 Source가 제공한 발신자 식별자를 지닌다. 화이트리스트는 특정 Source가 Policy 안에서 가지는 일부이며, 해당 Source 자신의 신원 체계를 사용한다. 같은 사람이 GitHub와 페이수에서 각각 계정을 가지는 이 사실은, 에이전트가 필요할 때 읽는 프롬프트 텍스트 이지, Source를 가로지르는 신원 매핑 테이블이 아니다.

둘째, 문서에는 "부결된 개념"이라는 절이 따로 있어, 채택하지 않은 방안과 그 이유를 기록하고 있다. 예를 들면:

부결된 것 이유 Ticket 상태를 DSH Session에 묶는 것. Ticket은 인계, 복원될 수 있거나 여러 Executor에 의해 실행될 수 있으므로, 자체 상태를 정의한다. Executor가 "누군가 나에게 멈추라고 했다"고 선언하는 것. 종료의 강도는 오직 Eval이 결정한다. 정책이 변할 때 실행 중인 Ticket을 취소하는 것. 취소는 반제품을 남긴다. 대신 변화를 기록하고 전달하는 것으로 바꾼다. 리포트의 자유 텍스트로 "사람을 기다리는 중"을 추론하는 것. 분류에는 구조화된 사실이 필요하다. Executor는 구조화된 필드로 질문한다. 각 Thread에 최대 하나의 활성 Ticket. 하나의 Thread 안에 서로 독립적인 일이 여러 건 있을 수 있다.

"무엇을 하지 않는지, 그리고 왜"를 적어 두는 것은 많은 프로젝트에 빠져 있는 부분이다.

권한 부여와 진입: 누가 그것을 착수하게 할 수 있는가

docs/002-authorization.md의 첫 문장이 기조를 정한다:

호스트는 화이트리스트, 규칙, Mandate를 강제한다. 메시지, 댓글, 인용된 문서는 결정의 입력이며, 이러한 권한을 바꿀 수 없다 .

Trigger는 두 갈래 길을 간다:

- Eval 경로 : 새 작업을 열지 판단한다. Source는 메시지가 에이전트를 지목했는지( mention 멘션, 또는 direct 다이렉트 메시지)를 기록한다. 허용된 사람이 그것을 지목하는 것은 명확한 요청 이다. 다른 사람의 메시지는 진입표를 거친다. 화이트리스트에 있는 봇은 "추론 후보"를 발생시킬 수 있지만, 결코 명확한 요청은 아니다

- 구독 경로 : 기존 작업을 이어간다. 구독한 Thread의 모든 메시지(봇과 CI의 메시지 포함)는 맥락으로서 구독된 Ticket에 도달하며, 진입을 우회하지만 어떤 새로운 권한도 부여하지 않는다 . 각 Ticket은 여전히 자신의 Mandate 제약을 받는다

강도는 두 단계로 나뉜다 :

강도 상황 explicit(명확) 화이트리스트에 있는 사람이 에이전트를 지목하거나, 이미 Ticket이 있는 Thread에서 후속한다. 진입표에서 명확한 요청으로 설정된 칸. inferred(추론) 화이트리스트에 없는 사람이 Ticket이 있는 Thread에서 후속한다. 진입표에서 추론 후보로 설정된 칸. 화이트리스트 봇의 메시지. 진입 불가 그 밖의 봇, 진입표가 무시하는 모든 것, 그리고 수주 모드가 off일 때의 모든 추론 상황.

수주 모드 는 정책의 일부다:

모드 효과 off 어떤 추론도 후보가 될 수 없다. observe (기본값) 추론 후보는 평가되고, 통과한 기록은 "원래라면 수주했을" 무시로 남으며, 수주하지 않는다 auto 추론 후보가 평가를 통과하면 수주한다.

명확한 요청은 모든 모드에서 유효하다. 먼저 observe로 돌리고, 기록된 결정을 검토한 뒤, auto로 전환하라 . 매 평가는 활성화된 모든 규칙에 대해 한 번씩 판단한다. 능동 수주는 최소한 하나의 규칙과 일치해야 한다.

규칙이 바뀌면 어떻게 되는지 도 설명되어 있다: Policy 변화는 실행 중인 Eval을 폐기하고 다시 대기열에 넣으며, 영향을 받는 활성 Ticket에 "정책이 변경됨" 입력을 보내, 매칭된 규칙이 바뀌었는지, 요청자가 더 이상 허용되지 않는지, 아니면 능동 작업이 더 이상 수용되지 않는지를 설명한다. 그러나 이미 존재하는 Ticket의 Mandate를 즉시 철회하지는 않는다. 종료된 Ticket을 복원하기 전에야 현재 정책에 따라 재검증한다:

- 명확한 후속 Mandate는 통과한다

- 추론된 Mandate는 auto 모드이고 매칭된 규칙이 여전히 활성화되어야 한다

- 진입표 칸에 의해 부여된 Mandate는 여전히 최소한 원래의 강도에 도달해야 한다. 발신자를 화이트리스트에서 제거하면 "화이트리스트 발신자" 칸을 통해 얻은 Mandate가 철회된다

- 봇의 Mandate는 해당 봇이 여전히 화이트리스트에 있어야 한다

검증에 실패하면 Ticket은 종료 상태를 유지하며, 그 안에서 대기 중인 모든 메시지는 "어떤 Ticket에도 도달하지 못한" 것으로 처리되고, 만약 다른 Ticket이 그것을 소유하지 않는다면 Eval로 보내진다.

디테일이 두 가지 더 있다:

- 사람이 Thread에서 "멈춰"라고 말하는 것은 그저 평범한 Trigger이며, 중지는 Eval이 결정한다. Executor는 스스로 "누군가 나에게 멈추라고 했다"고 주장할 수 없다

- 패널에서 "중지"를 클릭하는 것은 명령 이며, Ticket에 직접 작용하고, 수동 중지로 기록된다

구독과 "귀속": 후속 메시지는 누구의 것인가

이 부분이 가장 헷갈리기 쉽고, 동시에 설계 역량이 가장 잘 드러나는 곳이다.

한 사람이 특정 Ticket 자신의 Thread에서 메시지를 보내면, 이 Ticket의 Executor가 결정 하며, 더 이상 Eval을 거치지 않고 Decision도 생성하지 않는다. Executor는 Ticket 범위 내에서 처리하거나, 되돌려준다 (hand back): 요청이 범위를 벗어나거나 다른 Ticket에 속할 때이다.

어떤 Ticket도 더 이상 이 메시지를 갖고 있지 않을 때에만, 그 메시지는 새로운 Eval로 진입하며, 후보에는 각 Executor가 돌려준 이유가 함께 담긴다.

Ticket이 끝날 때는, 해당 Executor가 읽지 않았거나 처리하지 않은 후속 메시지를 해제한다. 확인되지 않았거나 답변되지 않았거나 반환되지 않은 것들은 각자 Eval로 간다.

능동과 수동도 구분된다. Executor는 관련 Thread(예를 들어 다른 Issue나 PR)를 仅上下文(컨텍스트 전용)으로 구독할 수 있으며, 그곳의 메시지는 Ticket에 도달할 수 있지만 권한을 부여하지 않고, 이미 끝난 Ticket을 깨우지도 않는다.

실행: 하나의 작업 티켓은 어떻게 살아 있는가

docs/003-execution.md는 열려 있는 Ticket을 서로 배타적인 몇 개의 단계로 나누고, 위에서 아래로 첫 번째로 일치하는 것을 취한다.

단계 条件 面板标签 person / delivery Executor로 입력 전달 실패 Input undelivered person / answer Attention(사람의 답변을 기다리는 질문)이 있음 Awaiting answer person / review 최근 보고서가 ready Awaiting review person / blocked, failed 최근 보고서가 blocked 또는 failed이고, 이후 아무도 답하지 않음 Blocked · Failed working / queued Assignment가 없거나, 대기 중 Queued idle 보고서가 waiting이거나, Assignment가 끝남 Waiting for a Trigger working 기타 Working

person 단계는 모두 "누군가 입력하지 않으면 진행할 수 없다"는 뜻이다. 새로운 사람의 메시지는 blocked 또는 failed 상태의 Ticket을 다시 Executor의 손으로 되돌린다.

Executor란 무엇인가: 각 Ticket은 worker-<ticket id>라는 이름의 Executor Session과 Ticket 짧은 이름으로 명명된 디렉터리를 하나씩 받는다. Session은 운영자의 운영체제 사용자 신원으로 승인 없이 명령을 실행한다. 포그라운드 shell 명령이 5초를 넘으면 백그라운드 작업으로 전환되어, worker가 긴 명령을 기다리는 대신 다음 단계에서 새 메시지를 받을 수 있다.

문서는 "백그라운드 작업"에 대해 아주 세밀하게 규정한다:

- 한 라운드가 끝날 때 아직 shell 작업이나 하위 에이전트가 돌고 있으면, Ticket은 자신의 worker 슬롯을 유지하고 working을 유지하며, waiting을 보고하지 않는다

- 매 라운드 이후, 백그라운드 작업은 최대 30분 안에 완료되어야 한다. 시간을 초과한 shell 작업은 종료되고, Ticket은 waiting을 보고하며, 어떤 작업이 종료되었고 어떤 하위 에이전트가 아직 남아 있는지 설명한다

- 사람에게 넘길 때는 즉시 슬롯을 해제한다. 하위 에이전트는 멈추고, "리뷰용 서비스" 같은 shell 작업은 Assignment가 끝날 때까지 계속될 수 있다

동시성: 설정된 동시성 상한은 worker 슬롯에 적용되며, 그와 별도로 "사람의 메시지 또는 상태 요청"을 위한 슬롯을 하나 더 남긴다. 즉, 새 작업이 사람이 기존 Ticket을 계속할 기회를 밀어내지 않는다.

디렉터리 준비: 첫 번째 Assignment 이전에 Ticket 디렉터리가 없으면, 실행 루트 디렉터리에서 sh로 준비 명령을 한 번 실행하며, 제한 시간은 10분이고, 전형적인 방법은 git worktree로 체크아웃을 만드는 것이다. 브랜치 이름의 마지막 부분이 Ticket 짧은 이름과 일치하면, 그 PR은 이 Ticket에 귀속된다.

실행 변수: 준비 명령과 Executor 모두 동일한 변수를 읽을 수 있다. 예를 들어 DSH_SUPERAGENT_DIR, DSH_SUPERAGENT_TICKET, DSH_SUPERAGENT_GITHUB_REPOSITORY, DSH_SUPERAGENT_GITHUB_ACCOUNT이며, 어떤 자격 증명도 포함하지 않는다.

병합: 호스트가 아니라 프롬프트가 관리한다

자동 병합은 "전달 요구 사항"이라는 프롬프트 단락이 제어하며, 호스트에는 병합 관련 의사 결정 로직이 전혀 없다.

기본적으로 Executor는 절대 에이전트 계정으로 자동 병합을 활성화하지 않는다. GitHub는 병합을 활성화한 사람에게 병합을 귀속시키기 때문이다. 전달 요구 사항에는 반드시 다른 계정의 CLI를 지정해 병합해야 하며, 그렇지 않으면 사람이 병합한다.

기본 지시는 다음 조건이 동시에 충족될 때만 자동 병합을 허용한다. 해당 PR이 이 Ticket을 위해 열렸고, 준비가 완료되었고, 필요한 승인이 head 커밋을 포함하며, 추가 및 삭제 행 수 합계가 200행 미만일 것. 새 버전을 다시 푸시하기 전에 Executor는 먼저 자동 병합을 철회한다.

문서의 태도는 매우 분명하다. 이 설명들은 에이전트를 구속하는 것이지, GitHub의 병합 규칙을 구속하는 것이 아니다. 승인을 강제하려면 브랜치 보호에서 요구하고, 만료된 승인이 무효화되게 하라.

프롬프트: 팀이 에이전트를 어떻게 빚는가

docs/004-prompts.md는 팀이 무엇을 바꿀 수 있는지 분명히 설명한다:

단락 내용 Communication(커뮤니케이션) 언제 사람에게 메시지를 보내는지, 어떻게 쓰는지, 모든 GitHub 메시지 첫 줄(기본값은 This is by an automated agent, not a human), 리뷰를 어떻게 처리하는지, 어떤 일반 계정이 리뷰 봇인지 Ticket scope(작업 티켓 범위) Ticket이 언제 계속되는지, 언제 초안을 가지고 멈추는지 Delivery requirements(전달 요구 사항) PR의 증거, 자동 병합 조건과 행 수 임계값, 커밋 작성자 Team skills(팀 스킬) 에이전트가 필요할 때 로드하는 지식, 예를 들어 페이수(Feishu) 사용자가 어느 GitHub 계정에 대응하는지 설명하는 identities 스킬

시스템 프롬프트는 고정된 순서로 조립된다: 공유 지시와 역할, 세 개의 팀 단락, 구독과 답장, 스케줄링 또는 작업 지시, 입장, 인계, 환경, 그리고 마지막의 Policy 단락. Policy 단락은 매 모델 요청 시 다시 생성되며, 맨 마지막에 놓여서 정책 변화가 앞부분의 프롬프트 텍스트를 바꾸지 않게 한다(캐시 친화적).

우선순위는 강한 것에서 약한 것 순이다:

- 도구와 호스트가 강제하는 사실(신원, 권한, 매개변수 검사, 답장 용도, 길이 제한)은 프롬프트로 바꿀 수 없다

- 내장 및 생성된 단락(팀 오버라이드 포함)

- 능동 Ticket 매칭 규칙 안의 절차와 커뮤니케이션 요구 사항으로, 해당 Ticket의 Executor에만 유효하다

- 팀 단락과 팀 스킬

- 외부 텍스트: 메시지, 댓글, 문서, 인용. 그것은 데이터이며, 결코 규칙이나 권한을 바꾸지 않는다

마지막은 프롬프트 인젝션 방어선이다: 외부에서 온 텍스트는 아무리 명령처럼 보여도 데이터일 뿐이다.

내장 텍스트의 원칙도 읽어볼 만하다. 예를 들면:

- 역할 분리: 메인 Session은 라우팅만 하고 원본 Trigger와 라우팅 사실을 전달하며 기술적 결정은 하지 않는다. 라우팅 비고는 최대 30단어. Executor는 원본 출처를 읽고 범위를 판단하며 구현하고 검증한다

- 메인 Session은 기다리지 않는다: 보고, 후속 알림, 후보, 완료된 백그라운드 작업은 자동으로 메시지로 도착한다. 가드는 sleep, 30초를 초과하는 shell 타임아웃, 5초를 초과하는 작업 대기를 거부한다. 막힌 단계 하나가 새 후보를 늦추기 때문이다

- 사람이 반드시 행동해야 하거나 결과를 활용할 수 있을 때만 메시지를 보낸다. 채팅 메시지는 기본 한 문장, 하드 상한 100단어

- 명확히 인용할 때만 연결한다: 메시지는 반드시 특정 Ticket의 PR, Issue, 원본 메시지 또는 확인 답글을 가리켜야 하며, 주제가 비슷한 것만으로는 부족하다

- 정직한 전달: PR을 열었다고 해서 준비된 것은 아니다. 초안은 미완료로 표시해야 한다. 실제 "이전" 스크린샷이 없는 UI 변경은 준비된 것으로 치지 않는다

- 중복 작업에 자리를 양보한다: 누군가의 브랜치나 PR에 이미 이 Ticket의 변경이 포함되어 있으면 Executor는 한 문장으로 자신의 PR을 닫고 상대를 가리킨다

- 리뷰는 결과로 처리한다: 고치고 검증한 코멘트는 조용히 해결한다. 거부한 것은 한 줄 이유를 준다. 각 자동 리뷰 로봇은 하나의 PR에서 최대 세 라운드

장애와 복구

실행 문서는 "문제가 생기면 어떻게 할 것인가"에 많은 분량을 할애한다:

- Executor가 막히거나 실패: Ticket은 더 이상 자동 입력을 받지 않는다. 일시적인 모델 제공자 또는 네트워크 장애(HTTP 408, 429, 5xx, 연결 거부, 재설정 또는 타임아웃)에 대해 백오프를 두고 자동으로 세 번 재시도한다. 실패 후 CI와 로봇 메시지는 기록만 하고 전달하지 않으며 Session을 깨우지도 않는다. 사람의 메시지, 이후의 non blocked / failed가 아닌 보고 또는 재시도가 차단을 해제한다

- 재시작: 실행 중인 Assignment는 "host restarted"로 종료되고, 새 Assignment가 복구 비고를 달고 시작되며, Executor가 모든 외부 동작을 반복하기 전에 자신의 디렉터리, git 이력, GitHub를 먼저 확인하도록 요구하고, 가장 오래된 Ticket을 우선한다

- "먼저 저장, 그다음 실행": dsh-superagent는 결정 후의 동작(후보 전달, Assignment 시작, 입력 전달)을 먼저 디스크에 기록하고 실행하며, 실패 시 2초부터 시작해 두 배씩 늘려 1분까지 재시도한다. 어떤 유형의 작업은 동일 항목이 연속 세 번 실패한 뒤에야 개요의 시스템 문제에 나타난다

- 채널 실패: 발송한 메시지도 저장된 작업으로 처리하며, 5초부터 시작해 두 배씩 늘려 300초까지 백오프한다. 같은 Ticket에서 같은 대화로 가는 메시지는 순서를 유지하고, 확인은 반드시 뒤따르는 답변보다 앞선다. Source가 더 이상 그 대화를 듣지 않거나, 그 대화가 영원히 답변을 받을 수 없다고 명확히 답한 경우에만 폐기하며, 폐기된 메시지는 기록을 남기므로 "확인"은 "발송됨"이 아니라 "폐기됨"으로 읽힌다

- 일시 정지 처리: 스케줄링, 새 Eval, Eval 타임아웃, 입력 전달, 응답을 중지한다. Source는 계속 Trigger를 기록하고, 실행 중인 Executor 라운드는 중단되지 않는다

패널: 세 가지 질문에만 답한다

docs/005-panel.md는 패널을 열면 순서대로 세 가지 질문에 답하도록 규정한다: 지금 내가 처리해야 할 것이 있는가? 시스템은 건강하고 옳은 일을 하고 있는가? 한 작업의 Trigger에서 Eval, Ticket까지의 이력은 무엇인가?

탭은 워크플로에 따라 배열된다: Overview, Source, Trigger, Eval, Execution, Settings. Overview는 처리해야 할 Ticket을 먼저 나열하고, 이어서 시스템 문제, 24시간 활동 카운트, Executor 부하를 보여준다.

코드 구조

src 아래의 대략적인 계층:

디렉터리 내용 src/core 도메인 코어: engine.ts, evals.ts, tickets.ts, assignments.ts, intake.ts, replies.ts, ports.ts 등 src/sources GitHub와 Feishu의 Source 구현: 읽기, 트리거, 채널, 폴링, 등록 src/executor DSH와의 연동(dsh.ts)과 백그라운드 작업 관리(background.ts) src/app 런타임, HTTP 인터페이스, 설정, 프롬프트 조립, 세션 관리, 마이그레이션, 도구 src/client 패널 프런트엔드(React / TSX) src/infra 명령, 환경, 헬스 체크, 경로 prompts/, skills/ 기본 프롬프트와 GitHub, Feishu 두 Skill tests/ 대량의 테스트, 가장 큰 몇 개 파일 runtime.spec.ts 약 142 KB, core-engine.spec.ts 약 107 KB

docs/007-architecture.md 약 70 KB는 아키텍처 문서이고, docs/008-cookbook.md 약 30 KB는 새로운 Source를 추가하는 방법을 다룬다. 이번에 나는 이 두 문서를 한 줄씩 읽지는 않았다.

적용 범위와 한계

- 공식 포지셔닝은 연구 프로토타입: DeepSeek의 정식 제품이 아니며 프로덕션 소프트웨어로 직접 쓰는 것은 권장되지 않는다. 사용 전에 검토하고 조정해야 한다

- 논문과 일치하지 않는다: 프로토타입은 내부 버전과도, 논문이 서술한 구현과도 완전히 같지 않으며, 논문의 일부 설계는 여전히 미래의 방향이다

- DeepSeek Harness에 의존: DSH의 플러그인 패키지이므로 버전 범위에 맞는 DSH와 설정된 모델 제공자가 필요하다

- Executor의 권한이 매우 크다: Session은 운영자의 OS 사용자 신원으로 승인 없이 명령을 실행한다. 문서는 래퍼 스크립트와 디렉터리는 기본값일 뿐 보안 경계가 아니라고 명시하며, worker는 여전히 절대 경로로 프로그램을 실행할 수 있다. 배포 전에 그것이 무엇을 건드릴 수 있는지 분명히 생각하라

- 사전 의존성이 많다: Node 22.19+, pnpm, git, tmux, Python, GitHub CLI, DSH, 그리고 전용 에이전트 GitHub 계정(문서는 자신의 계정을 쓰지 말 것을 권한다)

- 단일 GitHub 저장소만 대상으로 하며, Feishu는 선택 사항이다. 다른 코드 호스팅 플랫폼은 Source를 직접 작성해야 한다(docs/008-cookbook.md에 추가 방법이 있다)

- 기본적으로 사람의 확인이 필요하다: 자동 병합은 기본적으로 꺼져 있고, 능동적 수주는 기본적으로 기록만 한다

- 매우 어리다: 생성 3일 차로 현재 커밋이 한 번뿐이며, 릴리스 버전이 없고, 문서는 계속 발전할 것이다

- 문서는 영어로 되어 있다. 그 외에 소량의 중국어 인터페이스 문구가 있다(locale/zh.json)

프로젝트 주소와 리소스

공식 리소스

- 🌟 GitHub : github.com/deepseek-ai…

- 🌐 DeepSeek Harness : www.deepseek.com/en/harness/

- 📚 문서 : 저장소 내 docs/000-philosophy.md 부터 docs/008-cookbook.md 까지

- 🧭 설치 절차 : 저장소 내 SETUP.md

관련 리소스

- 논문: Exploring Super-agent Design: Towards a More Autonomous Agent System (README에서 인용, 이번에는 원문을 찾지 못해 읽지 않음)

- Cordis 논문: DSH 공식 홈페이지에 Cordis paper가 나열되어 있음

요약과 전망

핵심 요점 정리

- 주의력은 비용이다 : 모든 메시지, 설정, 패널 요소는 인간의 주의력을 점유할 가치가 있음을 스스로 입증해야 하며, 그렇지 않으면 삭제한다

- 능동적이되 절제한다 : 요청을 받거나 팀 규칙이 있을 때만 행동한다. 능동적으로 작업을 수임할 때는 기본적으로 기록만 하고 실행하지 않는다

- 권한 부여는 추적 가능하고 변조 불가 : Mandate는 불변이며, 작업 수임, 사람에 의한 중지, 재검증 실패만이 이를 변경할 수 있다. 외부 텍스트는 영원히 데이터일 뿐이다

- 누가 이 메시지를 소유하는가 : 구독과 "반납" 메커니즘이 모든 후속 메시지에 하나뿐인 귀속을 보장하여, 양쪽에서 동시에 처리되지 않고 방치되지도 않도록 한다

- 문서 자체가 제품이다 : 순서대로 읽고, 기각된 방안과 그 이유를 기록하는 것은 아주 좋은 설계 문서 견본이다

적용 대상

- 코딩 에이전트가 팀 저장소에서 비동기적이고 통제된 방식으로 작업하도록 만들고 싶은 엔지니어링 책임자

- "능동형 에이전트"의 권한 부여, 접근 승인, 구독, 노이즈 감소 메커니즘을 설계하고 있는 개발자

- Skill, 프롬프트 체계 또는 에이전트 문서를 작성 중인 사람. 이 저장소의 문서 구성 방식은 참고할 가치가 있다

- DeepSeek Harness 생태계에 관심이 있는 사람

사용 제안

먼저 설치하지 말 것. 먼저 docs/000-philosophy.md 부터 docs/003-execution.md 까지 순서대로 읽어보고, 네 편을 합쳐도 길지 않으니 그다음 자신의 저장소에서 실행할지 결정하라. 정말로 시험해보려면 전용 GitHub 계정을 사용하고, 화이트리스트에는 자신만 적고, 작업 수임 모드는 observe에 두어 당분간 먼저 "하고 싶어 하게" 만든 뒤 완화할지 결정하라.

PrimeSkills 탐색하기 — 엄선된 AI 에이전트와 스킬 도구로, 하나하나가 실제 워크플로로 검증되었다. 과장은 없고, 정말 쓸 만한 도구만 있다.

나의 개인 홈페이지를 방문하여 더 많은 인사이트와 흥미로운 제품을 확인하세요.

冬奇Lab

소프트웨어 아키텍처

556

글

392k

조회수

857

팬