DeepSeek Harness roles de capacidad: Definition / Provider / Consumer
En la documentación oficial aparecen con frecuencia los tres términos Service Definition, Service Provider y Consumer; juntos forman el seam de una capacidad, es decir, la interfaz de capacidad reemplazable.
Este capítulo explicará claramente qué es cada uno de los tres y por qué se divide una capacidad en tres roles.
La capacidad completa constituye su seam; ningún rol individual por sí solo es el seam.
¿Qué es cada uno de los tres roles?
Cuando una capacidad es lo suficientemente genérica y necesita admitir proveedores reemplazables (por ejemplo, la ejecución de Bash), el harness divide la capacidad en tres roles.
| Rol | ¿De qué se encarga? | Con Bash como ejemplo |
|---|---|---|
| Service Definition Interfaz + tipos | Define el servicio Cordis, así como los tipos de la solicitud Request y del resultado Result | dsh-shell (registrado como ctx.shell) |
| Service Provider Implementación | Implementa realmente la capacidad, normalmente para un entorno de ejecución específico | dsh-bash-local (ejecución local) |
| Consumer Herramienta orientada al modelo | Expone la capacidad como una herramienta que el modelo puede invocar | dsh-tool-bash (herramienta bash) |
Service Definition solo declara "qué capacidad hay y cómo es", sin preocuparse de cómo se implementa.
Service Provider hereda la clase abstracta de Definition y añade el comportamiento concreto.
Consumer está orientado al modelo; envuelve la capacidad en un schema de herramienta para que el modelo pueda invocarla.
Los tres roles pueden estar en el mismo paquete o en paquetes distintos.
Solo hay un criterio: si estos roles necesitan evolucionar o reemplazarse de forma independiente.
Entiende los tres roles de seam con una imagen
Los tres roles dependen de Definition, mientras que Provider y Consumer no dependen entre sí.
El recuadro de líneas discontinuas en la imagen es la capacidad completa, es decir, el seam.
Definition está en el centro; tanto Provider como Consumer dependen únicamente de él.
Provider hereda e implementa Definition; Consumer, a través deinject: ['shell']depende de él.
No existe ninguna dependencia entre Provider y Consumer.
Por lo tanto, al cambiar de Provider, no es necesario modificar ni una sola línea de Definition ni de Consumer.
Con Bash como ejemplo: los tres roles de ctx.shell
La ejecución de Bash es el seam más típico de dsh; cada uno de los tres roles tiene su propio paquete.
Service Definition es el paquete dsh-shell, registrado como el servicio ctx.shell.
Define el tipo de solicitud de BashShellExecRequesty el tipo de resultadoShellRunResult。
Service Provider es dsh-bash-local, que ejecuta comandos en la computadora local.
La misma Definition tiene otros Provider, por ejemplo dsh-bash-sandbox que ejecuta en un sandbox, y dsh-pwsh-local que ejecuta PowerShell.
Consumer es dsh-tool-bash, que envuelve la capacidad como una herramienta bash invocable por el modelo.
tool-bash declara su dependencia de ctx.shell mediante inject y luego llama a ctx.shell.run(...) en execute.
El documento de referencia oficial "Capability Seam and Core Services" mantiene la asignación de los tres roles de ctx.shell en una tabla.
| Clave ctx | Rol | Paquete al que pertenece (Definition) | Implementación (Provider) | Consumidor directo (Consumer) |
|---|---|---|---|---|
| ctx.shell | seam | shell | bash-local / bash-sandbox / pwsh-local | tool-bash / tool-pwsh / hooks-claude-code / hooks-codex |
Los consumidores también incluyen los dos plugins puente de hooks: hooks-claude-code y hooks-codex.
Al igual que tool-bash, solo reconocen la interfaz ctx.shell y no les importa qué ejecutor hay detrás.
En el seam de Bash, la solicitud orientada al modelo ShellExecRequest (workdir, timeoutMs opcionales) se separa de la especificación completamente resuelta ShellExecSpec (campos obligatorios) que usa realmente el ejecutor.
La capa de herramienta llama a ctx.shell.resolve(request) entre ambos; esto es "lo explícito es mejor que lo implícito en los límites del paquete".
¿Por qué dividirlo en tres roles?
El primer beneficio de la división es que el proveedor es reemplazable.
La misma Service Definition puede tener múltiples proveedores, seleccionados mediante cordis.yml.
Ejemplo
# Ejecución local
- name: '@deepseek-ai/dsh-bash-local'
# Cuando quieras cambiar de proveedor, solo reemplaza la línea de arriba.
# Cambia a la línea de abajo para usar el ejecutor de sandbox:
# - name: '@deepseek-ai/dsh-bash-sandbox'
Al cambiar de proveedor, tanto Service Definition como Consumer permanecen sin cambios.
El segundo beneficio de la división es que los tres roles pueden evolucionar de forma independiente.
| Rol | Libertad de evolución independiente |
|---|---|
| Service Definition | Una vez que los invocadores empiezan a depender de sus convenciones, rara vez cambia |
| Service Provider | Puede optimizar el rendimiento y la seguridad de forma independiente |
| Consumer | Puede ajustar la forma en que la capacidad se presenta al modelo |
El tercer beneficio de la división es el desacoplamiento de dependencias.
Service Provider depende de Service Definition.
Consumer depende de Service Definition.
Service Provider y ConsumerNo dependen entre sí。
| Relación de dependencia | ¿Se cumple? |
|---|---|
| Provider → Definition | Sí |
| Consumer → Definition | Sí |
| Provider → Consumer | no |
| Consumer → Provider | no |
Ponlo en práctica: encuentra los tres roles del seam que estás usando
El documento de referencia oficial "Capability Seam and Core Services" mantiene una lista completa de servicios.
Elige un seam que conozcas, como ctx.fs o ctx.llm, y analízalo en tres pasos.
Primer paso: encuentra su paquete Definition, es decir, la columna "Paquete al que pertenece" en la tabla.
Segundo paso: encuentra su paquete Provider, es decir, la columna "Implementación" en la tabla.
Tercer paso: encuentra su Consumer, es decir, la columna "Consumidor directo" en la tabla.
Por ejemplo, para ctx.llm, la Definition es el paquete llm, las implementaciones son llm-deepseek y llm-pi-ai, y los consumidores directos son agent-loop y compaction-basic.
Otro ejemplo: para ctx.fs, la Definition es el paquete fs, las implementaciones son fs-local, fs-sandbox y fs-e2b, y el consumidor directo es tool-fs.
Una vez que te acostumbres a esta forma de pensar, podrás identificar de un vistazo a qué rol pertenece cualquier servicio integrado.
Resumen y autoevaluación
Resumen en una frase: la capacidad se divide en tres roles: Definition (interfaz y tipos), Provider (implementación) y Consumer (herramienta orientada al modelo); solo los tres juntos forman el seam.
Autoevaluación 1: ¿Qué paquete corresponde respectivamente a Definition, Provider y Consumer de la capacidad Bash?
Autoevaluación 2: Al cambiar el Provider de Bash, ¿qué paquetes pueden permanecer sin cambios?
Autoevaluación 3: ¿Por qué se dice que "ningún rol individual por sí solo es el seam"?
Otras extensiones