> For AI agents: the complete documentation index is available at https://open-spaced-repetition.github.io/ts-fsrs/zh-TW/llms.txt, the full documentation bundle is available at https://open-spaced-repetition.github.io/ts-fsrs/zh-TW/llms-full.txt.

# 排程器概覽

排程器是你的應用程式用來建立卡片、安排複習的物件。通常不必從頭建置：`defineScheduler({ model, chrono })` 把兩部分組合成可重用的定義，而 `DefaultScheduler` 是基於同一套機制做好的預設。各部分如何組裝見[整體架構](https://open-spaced-repetition.github.io/ts-fsrs/zh-TW/guide/architecture.md)；每個元件的詳細說明見[模型](https://open-spaced-repetition.github.io/ts-fsrs/zh-TW/guide/model.md)、[Chrono](https://open-spaced-repetition.github.io/ts-fsrs/zh-TW/guide/chrono.md) 與[中介軟體](https://open-spaced-repetition.github.io/ts-fsrs/zh-TW/guide/middleware.md)。


For your Agent

實作或說明一個排程器

複製提示詞

使用目前 ts-fsrs Scheduler 契約完成以下任務：[描述任務]。

1. 閱讀 https://open-spaced-repetition.github.io/ts-fsrs/zh-TW/guide/scheduler/index.md 與 https://open-spaced-repetition.github.io/ts-fsrs/zh-TW/guide/scheduler/default-scheduler.md，了解「定義與實例」模型及現成預設。
2. 用 defineScheduler({ model, chrono }) 組合排程器；用 .use(...) 加入中介軟體，用 .create({ config }) 建立實例。
3. 讓模型只負責記憶狀態更新與間隔計算、chrono 負責時間值與天數運算、中介軟體負責環繞核心的策略。
4. 把可重用定義保留在程式層級，用 .create({ config }) 驗證使用者的設定。
5. 當預設 FSRS 模型、dateChrono 與標準策略契合時，優先使用 DefaultScheduler。
6. 使用目前 public API，並為所實作的排程行為加入聚焦測試。

## 定義與實例

排程器存在於兩個階段：

| 階段 | 是什麼                                                  | 如何取得                                               |
| -- | ---------------------------------------------------- | -------------------------------------------------- |
| 定義 | 純 schema 描述：一個模型、一個 chrono，以及選用的中介軟體。不持有設定，也不持有卡片資料。 | `defineScheduler({ model, chrono })` 與 `.use(...)` |
| 實例 | 綁定到一份已驗證設定、可運作的排程器。                                  | `definition.create({ config })`                    |

`defineScheduler` 保留具體的模型與 chrono 型別，因此 schema 與處理函式在貫穿 `.use(...)` 時始終有型別檢查。`.use(middlewareA, middlewareB)` 回傳加入這些中介軟體（依序）的新定義；原定義不變，仍可重用。呼叫 `.create({ config })` 會依組合出的 schema 驗證該設定，並回傳狀態獨立、互不共享的排程器實例。

:::note 保留定義，按需建立實例
把包含所組合中介軟體的定義保留在程式層級。當某使用者或集合的設定就緒時再呼叫 `.create({ config })`。每次呼叫都會驗證設定並回傳獨立實例，因此兩次 `.create()` 不會共享排程狀態。
:::

## 重用同一份定義建立多個排程器

下面用一份定義建置兩個排程器，二者唯一的差別是目標保留率。由於 `schedulerDesiredRetentionMiddleware` 把 `desiredRetention` 併入設定 schema，`.create()` 可以在每個實例上接受並驗證它：

```ts twoslash file="../../../snippets/run-code/scheduler.ts" fold height=520
import { dateChrono, defineScheduler, Rating } from 'ts-fsrs'
import { schedulerDesiredRetentionMiddleware } from 'ts-fsrs/middlewares'
import { FSRS6_DEFAULT_WEIGHTS, FSRS6Model } from 'ts-fsrs/models/fsrs-6'

// Create a reusable definition once, at the program level.
const schedulerDefinition = defineScheduler({
  model: FSRS6Model,
  chrono: dateChrono,
}).use(schedulerDesiredRetentionMiddleware)

const now = new Date('2026-01-01T00:00:00.000Z')

// Each .create() validates its own config and returns an independent scheduler.
const library = schedulerDefinition.create({
  config: {
    weights: FSRS6_DEFAULT_WEIGHTS,
    enableShortTerm: true,
    numRelearningSteps: 1,
    desiredRetention: 0.9,
  },
})
const exam = schedulerDefinition.create({
  config: {
    weights: FSRS6_DEFAULT_WEIGHTS,
    enableShortTerm: true,
    numRelearningSteps: 1,
    desiredRetention: 0.8,
  },
})

function nextGoodDue(scheduler: typeof library) {
  const card = scheduler.newCard({ now })
  return scheduler
    .review({ card, grade: Rating.Good, now })
    .card.dueAt.toISOString()
}

console.log(
  JSON.stringify(
    {
      libraryRetention: 0.9,
      libraryDue: nextGoodDue(library),
      examRetention: 0.8,
      examDue: nextGoodDue(exam),
    },
    null,
    2
  )
)

```


▶ 執行程式碼

更低的目標保留率會讓間隔變大：exam 排程器首次 Good 複習在 1 月 9 日到期，而 library 排程器在 1 月 3 日到期。定義本身從未改變，兩個排程器只是透過各自驗證過的設定而不同。

## 現成預設

`DefaultScheduler` 是非同步工廠，用同樣的「定義與實例」機制組裝出預設 FSRS-7 模型、`dateChrono` 與標準排程策略的排程器，你只需傳入選項。選項與版本見[DefaultScheduler](https://open-spaced-repetition.github.io/ts-fsrs/zh-TW/guide/scheduler/default-scheduler.md)；想先跑起來見[快速開始](https://open-spaced-repetition.github.io/ts-fsrs/zh-TW/guide/quick-start.md)。
