DeepSeek Harness: Một Framework Agent Mã Nguồn Mở, nơi Thực Sự Mọi Thứ Đều Là Plugin
Một Ngăn Xếp Agent Hoàn Chỉnh, Được Đăng Tải Lên GitHub
DeepSeek đã phát hành bản xem trước dành cho nhà phát triển của DeepSeek Harness (dsh) vào ngày 13 tháng 8 năm 2026. Kho lưu trú nằm tại deepseek-ai/deepseek-harness. Đến cuối ngày, nó đã có 1.6k sao, 12.293 commit và 19 người đóng góp — những con số này cho thấy đây không phải là một dự án cuối tuần. Cơ sở mã là 97.1% TypeScript, 1.6% CSS và 0.7% Python. Phiên bản gói khi phát hành: 0.1.0-rc.5.
Trang đích tại deepseek.com/harness và tài liệu dành cho nhà phát triển tại deepseek-harness.github.io/deepseek-harness.
Được cấp phép theo MIT.
Câu Giới Thiệu Một Dòng
Từ README: “Agent = Model + Harness.”
Mô hình là linh hồn. Một harness giúp agent hiểu môi trường của mình, sử dụng công cụ và tiếp tục làm việc trong các bối cảnh thực tế. Quan điểm của DeepSeek: mọi khả năng — mô hình, công cụ, kỹ năng, phiên, hộp cát, lưu trữ, vòng lặp, lên lịch và UI — đều là một plugin có thể hoán đổi.
Đây không phải là một khẩu hiệu. Nó được kiến trúc thực thi.
Cordis: Hạt Nhân Dưới Mọi Thứ
DeepSeek Harness được xây dựng trên nền Cordis, một framework plugin được vendored. Thiết kế của Cordis được mô tả trong một bài báo có tên A Programming Paradigm for Spatiotemporal Composability.
Toàn bộ framework rút gọn thành năm ý tưởng:
- Một plugin là một đối tượng thực thi Service. Nó có thể là một hàm với
injectvàapply(ctx), hoặc một lớp conService. - Một ngữ cảnh là kho lưu trữ các dịch vụ. Một plugin chiếm một khóa ổn định như
ctx.tools,ctx.llmhoặcctx.sessions. Các plugin khác tìm kiếm dịch vụ theo khóa thay vì nhập các triển khai cụ thể. - Khai báo phụ thuộc dịch vụ thông qua
inject. Một plugin đặt tên các dịch vụ yêu cầu sẽ đợi cho đến khi các dịch vụ đó tồn tại. Không cần trình tự khởi động thủ công. - Sự kiện được gõ cho giao tiếp. Bốn chế độ gửi:
emit(bắn và quên),waterfall(kiểu middleware vớinext()),parallel(tất cả trình nghe chạy đồng thời), vàserial(trình nghe chạy theo thứ tự với giá trị trả về). - Các đăng ký là hiệu ứng có thể đảo ngược. Các phần prompt, schema công cụ, bộ chuyển đổi, trình nghe — mọi thứ được cài đặt thông qua
ctx.effect()để tải lại và dọn dẹp có thể gỡ bỏ chúng một cách có thể dự đoán.
Mô hình waterfall của Cordis là một around middleware. Một trình nghe nhận (...args, next). Gọi next() để ủy thác cho dịch vụ tiếp theo; trả về mà không gọi next() để ngắn mạch. Đối với các sự kiện quyết định đơn lẻ, việc ngắn mạch là thiết kế — một trình nghe chính sách có thể sở hữu hoàn toàn một quyết định.
Mọi Thứ Đều Là Plugin (Thật Đấy)
Danh sách plugin trên deepseek.com/harness nêu rõ toàn bộ bề mặt khả năng:
- Models — các backend LLM (DeepSeek, OpenAI, Anthropic, Bedrock, Vertex, Azure, Codex, cộng thêm bất kỳ endpoint tương thích OpenAI nào)
- Tools — những gì mô hình có thể gọi
- Skills — các gói prompt và công cụ có thể tái sử dụng
- Sessions — quản lý trạng thái hội thoại
- Sandboxes — nơi mã chạy (PTY bash, backend cục bộ
danger-full-access, hộp cát bản địa dựa trên landlock) - Storage — tính bền vững của phiên
- Loops — logic lượt của agent
- Scheduling — phân công subagent và nhiệm vụ
- UI — Web UI được phục vụ tại cổng 3080 theo mặc định
Một nhà phát triển có thể chọn, hoán đổi hoặc mở rộng bất kỳ thứ nào trong số này thông qua cấu hình — không cần thay đổi mã nguồn của chính DeepSeek Harness. Danh Mục Cấu Hình Plugin được tự động tạo từ mã nguồn (scripts/gen-config-catalog.ts) và được CI xác minh luôn mới, vì vậy mọi trường trong khối config: của cordis.yml đều khớp chính xác với loại cấu hình đã khai báo của một plugin.
Bốn Chế Độ Runtime
Tài liệu đi kèm bốn cài đặt sẵn. Mỗi cái nhắm đến một trường hợp sử dụng khác nhau.
Standard Mode — Agent mã hóa đầy đủ: chỉnh sửa tệp, shell, tìm kiếm tệp và web, kỹ năng, lập kế hoạch, mục tiêu, subagent và quy trình làm việc. Đây là trải nghiệm Web UI mặc định.
Code Mode — Mọi thứ trong Standard, nhưng các công cụ được hiển thị thông qua Code Mode SDK để mô hình có thể kết hợp các thao tác nhiều bước trong một chương trình TypeScript. Một chương trình do mô hình tạo ra thay thế nhiều vòng gọi công cụ.
Minimal Mode — Chỉ hai công cụ: một shell bash liên tục và str_replace_editor. Đây là để so sánh mô hình trong một môi trường được rút gọn. Không có kỹ năng, không có lập kế hoạch, không có subagent — khả năng mô hình thuần túy đối mặt với một cơ sở mã thực.
Creator Mode — Được xây dựng để viết các cài đặt sẵn agent tùy chỉnh. Bao gồm tất cả các khả năng của chế độ Standard cộng thêm kiểm tra runtime, thử nghiệm plugin Cordis trong bộ nhớ và hướng dẫn viết cài đặt sẵn. Đây là cách bạn xây dựng chế độ thứ năm, thứ sáu, thứ bảy.
Mỗi Chạy Đều Có Thể Theo Dõi
Đây là nơi Harness khác biệt với hầu hết các công cụ agent. Mọi thứ mô hình thấy đều được ghi lại trong nhật ký phiên chỉ ghi thêm:
- Prompt hệ thống
- Đầu ra suy luận
- Lời gọi công cụ và kết quả của chúng
- Quyết định lên lịch subagent
- Mỗi lần tiêm ngữ cảnh
Web UI có một chế độ xem Trajectory nơi bạn kiểm tra các bản ghi này được lọc theo nguồn. Tiếp tục, phân nhánh, tìm kiếm và phát lại — cả bốn hoạt động đều hoạt động trên cùng một luồng sự kiện. Không có cơ sở dữ liệu theo dõi riêng biệt, không có bước xuất. JSONL của phiên chính là nguồn sự thật.
Đối với Python SDK, thư mục phiên lưu trữ JSONL không nén chứa các yêu cầu mô hình đã lắp ráp và các lời gọi công cụ. Ví dụ tại examples/jsonrpc-agent/minimal.py cho thấy điều này từ đầu đến cuối.
Cấu Hình Mô Hình: DeepSeek + Bất Cứ Thứ Gì
Trang cấu hình mô hình (Cấu hình mô hình) có ba lớp.
DeepSeek Chính thức. Mở Cài đặt → Mô hình, dán khóa API DeepSeek, lưu. Khóa là chỉ ghi. Sau khi lưu, UI nhận một mô tả đã được che giấu, không bao giờ là văn bản thô. Các khóa nằm trong \$DSH_HOME/.credentials.yaml; trang cài đặt chỉ giữ một tham chiếu thông tin xác thực.
Nhà cung cấp danh mục. Nhấp “Thêm nhà cung cấp”, chọn Anthropic hoặc OpenAI, dán khóa. Các nhà cung cấp sử dụng xác thực gốc (Bedrock thông qua creds AWS + vùng, Vertex thông qua dự án ADC, Azure thông qua api-version, Codex thông qua OAuth) không hoạt động chỉ với một trường khóa API — mỗi cái cần đường dẫn xác thực riêng.
Nhà cung cấp tùy chỉnh. Dành cho cổng công ty, máy chủ tự lưu trữ hoặc bất kỳ nhà cung cấp nào không có trong danh mục. Đặt một ID Nhà cung cấp chữ thường (vĩnh viễn — yêu cầu, phiên đã lưu, mặc định mô hình và tham chiếu thông tin xác thực đều sử dụng nó), URL cơ sở, giao thức API, thông tin xác thực và ít nhất một mô hình.
Các mô hình hình ảnh cần một bước bổ sung. Vì một endpoint tùy chỉnh không có cách nào để quảng bá các phương thức hỗ trợ của mình, biểu mẫu không thể tự động phát hiện hỗ trợ thị giác. Thêm input: [text, image] vào mô hình trong \$DSH_HOME/settings.yaml. Nếu tất cả các mô hình tùy chỉnh của bạn chấp nhận hình ảnh, hãy đặt defaultInput: [text, image] một lần ở cấp nhà cung cấp thay vì mỗi mô hình. Trường input là một khẳng định, không phải kiểm tra — nếu bạn tuyên bố một mô hình làm thị giác nhưng endpoint thực sự không làm, nhà cung cấp sẽ từ chối yêu cầu thay vì Harness.
Khắc phục sự cố được viết trực tiếp trong tài liệu:
MISSING_CREDENTIAL→ lưu khóa nhà cung cấp thông qua trang Mô hình hoặc export biến môi trường được tham chiếuUNKNOWN_MODEL→ chọn một mô hình đã cấu hình, hoặc thêm mô hình còn thiếu vào nhà cung cấp tùy chỉnh- “Lấy mô hình khả dụng trả về 401” → kiểm tra khóa. Khám phá mô hình gọi endpoint tương thích OpenAI
GET /models. Nếu dịch vụ của bạn không hiển thị điều đó, hãy nhập mô hình thủ công. - “Hình ảnh bị từ chối trước khi gửi” → mô hình không khai báo phương thức
image. Thêminput: [text, image]. - “Nhà cung cấp từ chối một yêu cầu có hình ảnh” → mô hình đã tuyên bố một khả năng thị giác mà endpoint của nó thực sự không có. Xóa
imagekhỏi danh sách và bắt đầu một phiên mới (hình ảnh cũ vẫn nằm trong nhật ký phiên và tiếp tục lặp lại cùng một yêu cầu).
Bắt Đầu: Ba Con Đường
Con Đường 1: npx @deepseek-ai/dsh web
Cài đặt Node.js, chạy một lệnh. Web UI khởi động tại http://127.0.0.1:3080. Xong. Không cần clone, không cần build, không cần pnpm.
npx @deepseek-ai/dsh webSau đó: Cài đặt → Mô hình → dán khóa API DeepSeek. Chọn không gian làm việc (thư mục nơi dsh được gọi cũng được). Bắt đầu một phiên:
Tóm tắt kho lưu trữ này và xác định các gói chính của nó.
Agent đọc và chỉnh sửa các tệp không gian làm việc, chạy lệnh, ủy thác công việc và duy trì một kế hoạch. Bất kỳ hoạt động nào cần phê duyệt theo chính sách quyền đang hoạt động sẽ mở một hộp thoại trong Web UI trước khi thực thi.
Con Đường 2: Clone và Build Từ Nguồn
git clone https://github.com/deepseek-ai/deepseek-harness.gitcd deepseek-harnesspnpm installpnpm run buildpnpm dsh webCon Đường 3: Python SDK
Yêu cầu: Python 3.10+, Linux x64 / Linux arm64 / macOS 14+ trên arm64, một endpoint tương thích DeepSeek.
git clone https://github.com/deepseek-ai/deepseek-harness.gitcd deepseek-harnesspython -m venv .venv. .venv/bin/activatepython -m pip install deepseek-harness-sdkĐặt thông tin xác thực:
export DEEPSEEK_API_KEY=sk-your-key-here# Tùy chọn:# export DSH_MODEL=deepseek-v4-flash# export DSH_SYSTEM_PROMPT='You are a helpful software engineer assistant.'Chạy một nhiệm vụ đối với một không gian làm việc được cô lập:
python examples/jsonrpc-agent/minimal.py \ --workspace /absolute/path/to/workspace \ --session-root /absolute/path/to/sessions \ --session-id example-001 \ "Inspect the repository and fix the failing tests."Đối với mã của riêng bạn, điểm vào SDK là DeepSeekHarness như một trình quản lý ngữ cảnh:
from pathlib import Pathfrom deepseek_harness import DeepSeekHarness
config = Path("examples/jsonrpc-agent/minimal.cordis.yml").resolve()workspace = Path("/absolute/path/to/workspace").resolve()sessions = Path("/absolute/path/to/sessions").resolve()
with DeepSeekHarness( provider="deepseek-official", model="deepseek-v4-flash", max_tokens=49_152, cwd=str(workspace), session_root=str(sessions), cordis=str(config),) as harness: result = harness.run( "Inspect the repository and fix the failing tests.", session_id="example-001", ) print(result.final_response)DeepSeekHarness khởi động runtime được đóng gói một cách lười biếng và sử dụng lại cho đến khi khối with thoát. Sử dụng lại cùng một ID phiên để bảo toàn quy trình Bash (thư mục làm việc, biến env, hàm shell). Sử dụng ID phiên mới cho một nhiệm vụ độc lập.
Sự kết hợp tối giản jsonrpc-agent là cố tình thưa thớt: chỉ bash liên tục và str_replace_editor làm công cụ đối mặt với mô hình. Thời gian chờ Bash 300 giây. Giới hạn đầu ra trình chỉnh sửa 16.000 ký tự. Nén ngữ cảnh bị tắt. Hệ thống tệp sử dụng backend cục bộ trần — các đường dẫn trình chỉnh sửa có thể địa chỉ bất kỳ thứ mà quy trình runtime có thể thấy. Tài liệu cảnh báo rõ ràng: “Chỉ chạy bên trong một checkout dùng một lần hoặc container.” Backend PTY liên tục cũng cần một nền tảng thiết bị đầu cuối POSIX — không hỗ trợ Windows cho sự kết hợp này.
Viết Plugin Đầu Tiên Của Bạn
Hướng dẫn: Plugin đầu tiên của bạn. Một plugin là một mô-đun TypeScript xuất một hàm apply:
import type { Context } from '@deepseek-ai/cordis'
export const name = 'hello-plugin'
export function apply(ctx: Context) { console.log('[hello-plugin] plugin loaded!')}Đăng ký nó trong một vá cordis.yml:
- insert: - id: hello name: '/absolute/path/to/deepseek-harness/scratch-plugin/src/my-plugin.ts'Khởi động với lớp phủ:
pnpm dsh web --patch ./scratch-plugin/cordis.ymlDọn dẹp tự động là tính năng gây ấn tượng. Bất kỳ thứ nào được đăng ký thông qua ctx — trình nghe sự kiện, công cụ, bộ định thời — đều được dọn dẹp khi plugin được tải xuống. Không cần removeListener hoặc clearInterval thủ công. Đối với dọn dẹp tường minh (kết nối mạng), trả về một disposer từ ctx.effect().
Các phụ thuộc được khai báo bằng inject:
export const name = 'my-tool-plugin'export const inject = ['tools']
export function apply(ctx: Context) { // ctx.tools is ready here}Cordis đợi mọi dịch vụ yêu cầu sẵn sàng trước khi tải plugin.
Ba dạng plugin tồn tại: hàm (ở trên), đối tượng có apply, và lớp mở rộng Service. Sử dụng dạng lớp khi chính plugin cung cấp một dịch vụ cho các plugin khác tiêu thụ.
Viết Công Cụ Đầu Tiên Của Bạn
Hướng dẫn: Xây dựng một công cụ. Sử dụng defineTool từ @deepseek-ai/dsh-tools:
import type { Context } from '@deepseek-ai/cordis'import { defineTool } from '@deepseek-ai/dsh-tools'
export const name = 'greet-tool'export const inject = ['tools']
export function apply(ctx: Context) { ctx.tools.register(defineTool({ name: 'greet', description: 'Greet someone by name.', parameters: { name: { type: 'string', required: true, description: 'The name to greet', }, }, output: { schema: { type: 'string' }, render: (_args, value) => [{ type: 'text', text: value }], }, async execute(args) { return `Hello, ${args.name}!` }, }))}defineTool suy luận và xác thực args từ parameters. execute trả về giá trị chuẩn được khai báo bởi output.schema. output.render chuyển đổi giá trị chuẩn đó thành nội dung đối mặt với mô hình. Sau khi khởi động lại với vá, hỏi Web UI: “Sử dụng công cụ greet để chào Ada.” Mô hình gọi greet và nhận Hello, Ada!.
Các bước tiếp theo từ hướng dẫn là cấu hình plugin, tham khảo viết công cụ (schema lồng nhau, giá trị chuẩn, công việc nền, hook chính sách, Code Mode, thẻ UI) và phân lớp khả năng (Định nghĩa Dịch vụ → Nhà Cung Cấp Dịch vụ → tách gói người tiêu dùng).
Chế Độ Đầu Vào CLI
Lệnh @deepseek-ai/dsh là trình khởi chạy sản phẩm. Bốn điểm vào:
| Lệnh | Mục Đích |
|---|---|
dsh --profile <name> |
Khởi chạy cấu hình được đặt tên dưới \$DSH_HOME/profiles/<name> |
dsh --profile headless "job" |
Chạy một phiên liên tục mới, in câu trả lời cuối cùng, thoát |
dsh web |
Bí danh của --profile web |
dsh plugin --profile <name> <pnpm args> |
Quản lý plugin của một cấu hình bằng cách chuyển tiếp đến pnpm |
Thư mục được gọi là gốc không gian làm việc mặc định. Các cấu hình web và headless tự khởi tạo từ các mẫu được gửi đi khi sử dụng lần đầu. Bất kỳ cấu hình nào khác phải được tạo thông qua dsh plugin.
Các cờ trình khởi chạy đến trước. Token đầu tiên mà trình khởi chạy không nhận dạng trở thành đối số của ứng dụng. Ví dụ: dsh --profile web --port 8080 chuyển --port 8080 cho ứng dụng web, không phải trình khởi chạy.
Một thư mục cấu hình chứa một package.json (các phụ thuộc plugin ngoài cây, cộng với bản kê khai cấu hình dsh.profile với danh sách bundles đã sắp xếp của nó) và một cordis.patch.yml (lớp vá riêng của người dùng). Thứ tự kết hợp trên một gốc trống là: vá của mỗi gói theo thứ tự dsh.profile.bundles → cordis.patch.yml của cấu hình → \$DSH_HOME/cordis.patch.yml cấp nhà → lớp phủ --patch. Sử dụng --dump-default-config và --dump-config để kiểm tra cây đã kết hợp mà không cần khởi chạy nó.
Plugin Cộng Đồng và Hệ Sinh Thái
Gắn thẻ kho lưu trữ plugin của bạn bằng dsh-plugin trên GitHub để dễ khám phá. Trang chính thức liên kết trực tiếp đến trang chủ đề đó. Cũng có một cộng đồng Discord DeepSeek Harness để thảo luận.
Dự án sử dụng GitHub Discussions cho phản hồi và báo cáo lỗi. Tài liệu liên kết đến CONTRIBUTING.md cho quy trình phát triển, architecture.md cho thiết kế hệ thống và AGENTS.md cho các quy ước mã hóa cụ thể của agent.
Bản Xem Trước Cho Nhà Phát Triển — Vâng, Nó Sẽ Bị Hỏng
README đặt điều này dưới dạng IN HOA: “SẼ CÓ CÁC THAY ĐỔI LÀM HỖN LOẠN TƯƠNG THÍCH.”
Các plugin và API cốt lõi vẫn đang phát triển. Trang đích nói điều đó trực tiếp: “DeepSeek Harness vẫn còn trong bản xem trước cho nhà phát triển và vẫn đang được các nhà phát triển xây dựng các harness agent kiểm tra.”
Nếu bạn đang xây dựng trên nền của nó, hãy gắn một hàm băm commit, giữ các plugin của bạn mỏng so với danh mục cấu hình, và mong đợi sẽ kiểm tra lại trên mỗi lần tăng rc. Việc dọn dẹp tự động plugin và tiêm phụ thuộc làm cho việc kiểm tra lại ít đau đớn hơn so với các framework đơn khối, nhưng “bản xem trước cho nhà phát triển” có nghĩa chính xác như những gì nó nói.
Điều Gì Làm Nên Sự Khác Biệt
Hầu hết các framework agent ngày nay bắt đầu với một vòng lặp lượt và gắn khả năng mở rộng như một suy nghĩ sau. Harness lật ngược lại: khả năng mở rộng chính là framework, và vòng lặp lượt chỉ là một plugin khác. Kết quả có thể quan sát được là ba thứ bạn thường không nhận được trong một gói:
- Hoán đổi bất cứ thứ gì mà không cần fork. Không thích hệ thống công cụ tích hợp? Thay thế nó. Muốn một lớp định tuyến LLM khác? Đổi nhà cung cấp. Mọi thứ được giải quyết thông qua các khóa dịch vụ Cordis.
- Theo dõi theo mặc định. Nhật ký chỉ ghi thêm không phải là một tiện ích bổ sung quan sát. Nó là cách các phiên hoạt động. Tiếp tục, phân nhánh, tìm kiếm và phát lại đều sử dụng cùng một luồng.
- Cài đặt sẵn có thể kết hợp, không phải cờ tính năng. Bốn chế độ (Standard / Code / Minimal / Creator) chỉ là các lớp vá gói plugin đã sắp xếp. Bạn có thể xếp các cài đặt sẵn của riêng mình lên trên bằng YAML thay vì mã.
Cách tiếp cận này có thắng so với các SDK đơn khối hay không phụ thuộc vào việc hệ sinh thái plugin có sản xuất đủ công cụ và nhà cung cấp của bên thứ ba để làm cho câu chuyện hoán đổi/tái kết hợp trở thành sự thật hay không. Với 1.6k sao và 12k commit vào ngày đầu tiên, động lượng rõ ràng là có.
Tham Khảo
- Trang đích DeepSeek Harness
- deepseek-ai/deepseek-harness trên GitHub
- Quickstart tài liệu cho nhà phát triển
- Hướng dẫn cấu hình mô hình
- Hướng dẫn Python SDK
- Hướng dẫn Plugin đầu tiên của bạn
- Hướng dẫn Xây dựng một công cụ
- Cordis Primer
- Danh Mục Cấu Hình Plugin
- CLI README
- Cordis trên GitHub
- Bài báo Cordis: A Programming Paradigm for Spatiotemporal Composability
- Chủ đề dsh-plugin cộng đồng trên GitHub
- Discord DeepSeek Harness