Harness Academy
Tài liệu gốc 16 9 phútTiếng Việt + English
docs/planning.mdXem bản gốc
Ngôn ngữ bài đọc
Bản dịch tiếng Việt

Bản dịch đầy đủ theo đúng cấu trúc tài liệu; code, liên kết và định danh kỹ thuật được giữ nguyên.

quy hoạch

Planning cung cấp cho mô hình một danh sách nhiệm vụ có cấu trúc, tự cập nhật thông qua một bộ công cụ nhỏ -- và hiển thị kế hoạch hiện tại trở lại mô hình mỗi lượt mà không làm mất hiệu lực bộ nhớ đệm nhắc nhở. Nó có thể ở trong bộ nhớ trong một lần chạy hoặc duy trì với SQLite/Postgres, chia các bước thành các nhiệm vụ phụ có phần phụ thuộc và phát ra các sự kiện từ các thay đổi chi tiết.

Nguồn

Khả năng này kết hợp các tính năng danh sách nhiệm vụ của pydantic-ai-todo -- các cửa hàng liên tục, nhiệm vụ con, phần phụ thuộc và sự kiện -- mà nó thay thế. Nếu bạn đang di chuyển từ pydantic-ai-todo, các công cụ được đổi tên:

pydantic-ai-todoPlanning
write_todoswrite_plan
read_todosread_plan
add_todoadd_task
update_todo_status / update_todo_statusesupdate_task_status / update_task_statuses
remove_todoremove_task
add_subtask, set_dependency, get_available_taskskhông thay đổi

Hai điểm khác biệt cần lập kế hoạch: không có sự tiện lợi của chuỗi kết nối (create_storage(backend=...) và bạn bè đã biến mất -- bạn xây dựng nhóm asyncpg hoặc ứng dụng khách Redis của riêng mình, điều này giúp cho harness không có trình điều khiển) và PlanEvent mang theo không timestamp, do đó, người tiêu dùng đã đặt hàng hoặc đăng nhập sẽ cung cấp đồng hồ của riêng mình.

Mặc dù Pydantic AI Harness có trên các bản phát hành 0.x nhưng API có thể thay đổi giữa các bản phát hành nhỏ; khi đó, cảnh báo ngừng sử dụng và hướng dẫn di chuyển ghi chú phát hành sẽ cho bạn (hoặc người đại diện của bạn) biết chính xác cách nâng cấp. Xem chính sách phiên bản.

vấn đề

Các hoạt động tác động kéo dài bị trôi dạt: mô hình mất dấu vết về những gì nó đặt ra và những gì còn lại. Cách khắc phục thông thường - giữ lại kế hoạch đang chạy và đưa lại kế hoạch đó vào lời nhắc hệ thống mỗi lượt - làm mất hiệu lực bộ nhớ đệm lời nhắc. Lời nhắc của hệ thống nằm ở phía trước yêu cầu, do đó, mỗi lần chỉnh sửa gói sẽ thay đổi tiền tố được lưu trong bộ nhớ đệm và buộc toàn bộ cuộc trò chuyện phải được xử lý lại ở mức giá đầy đủ của token.

Giải pháp

model sở hữu kế hoạch thông qua planning bộ công cụ. Kế hoạch hiện tại được hiển thị trở lại dưới dạng lời nhắc tạm thời được thêm vào cuối mỗi yêu cầu, với điểm dừng bộ đệm sau thẻ mở ổn định của nó:

  • Lời nhắc được thêm vào sau khi lịch sử lâu dài được duy trì, vì vậy nó đến được mô hình nhưng không bao giờ được ghi vào message_history. Không có lời nhắc nào được tích lũy qua các lượt.
  • A CachePoint đi theo sự ổn định <plan-reminder> thẻ mở, do đó, tiền tố được lưu trong bộ nhớ cache (công cụ + hệ thống + cuộc hội thoại thực + thẻ đó) vẫn giữ nguyên lượt chuyển đổi giống hệt byte. Chỉ nội dung nhắc nhở có thể thay đổi mới nằm ngoài bộ đệm.

Cách sử dụng

Xây dựng một Agent với Planning() trong nó capabilities. Các công cụ được đăng ký tự động và hướng dẫn sử dụng tĩnh được thêm vào lời nhắc hệ thống:

from pydantic_ai import Agent
from pydantic_ai_harness import Planning

agent = Agent('anthropic:claude-sonnet-4-6', capabilities=[Planning()])

result = agent.run_sync('Refactor the auth module and add tests.')
print(result.output)

Các công cụ

Công cụMục đích
write_plan(items)Tạo hoặc thay thế gói đầy đủ (thay thế toàn bộ danh sách).
read_plan()Đọc kế hoạch hiện tại với id bước và tóm tắt tiến độ.
add_task(content, active_form)Nối thêm một đơn pending bước.
update_task_status(task_id, status)Di chuyển một bước giữa các trạng thái theo id.
update_task_statuses(updates)Áp dụng một số thay đổi trạng thái trong một cuộc gọi, được xác thực tất cả hoặc không có gì.
remove_task(task_id)Xóa từng bước theo id.

Mỗi bước là một content chuỗi, một tùy chọn hiện tại-tiếp diễn active_form nhãn và một status (pending, in_progress, completed, cancelled). Quy ước -- được nêu trong hướng dẫn và câu trả lời của công cụ -- là giữ đúng một bước in_progress.

Tất cả sáu đều được đăng ký theo mặc định. tools= thu hẹp danh sách đó vào danh sách cho phép và hướng dẫn tích hợp tuân theo danh sách đó:

from pydantic_ai_harness import Planning

planning = Planning(tools=['write_plan'])  # whole-plan replacement only -- one tool, no step ids to track

Đặt tên cho một công cụ chế độ hiện tại không đăng ký tăng ValueError, cũng như một khóa không xác định trong descriptions.

Nhiệm vụ phụ và phụ thuộc

Vượt qua enable_subtasks=True để thêm ba công cụ nữa, blocked trạng thái và một hierarchical xem trong read_plan:

Công cụMục đích
add_subtask(parent_id, content, active_form)Thêm một bước con dưới bước cha.
set_dependency(task_id, depends_on_id)Bước này chờ bước khác; bước phụ thuộc là tự độngblocked cho đến khi điều kiện tiên quyết của nó được giải quyết (hoàn thành hoặc hủy bỏ). Sự tự phụ thuộc, chu kỳ và bản sao đều bị từ chối.
get_available_tasks()Liệt kê các bước không có sự phụ thuộc đầy đủ -- những bước có thể bắt đầu ngay bây giờ.

parent_id, depends_on, và blocked trạng thái bị từ chối bởi write_plan trừ khi enable_subtasks được đặt: nếu không có các công cụ nhiệm vụ con thì không có gì điều hòa được sự phụ thuộc và không có chế độ xem nào hiển thị thứ bậc, vì vậy việc lưu trữ chúng sẽ là một thao tác ghi mà kế hoạch không phản ánh.

Kiên trì

Theo mặc định, gói này là một gói mới, riêng biệt trong bộ nhớ cho mỗi lần chạy. Vượt qua một store để duy trì nó:

from pydantic_ai_harness import Planning
from pydantic_ai_harness.planning import SqlitePlanStore

planning = Planning(store=SqlitePlanStore('plan.db', session='user-123'))

Các cửa hàng tích hợp là InMemoryPlanStore, SqlitePlanStore, PostgresPlanStore (trên nhóm asyncpg do người gọi sở hữu) và RedisPlanStore (trên một người gọi thuộc sở hữu redis.asyncio client) -- vì vậy khai thác không cần trình điều khiển cơ sở dữ liệu. bất kỳ PlanStore công tác triển khai và store_resolver chọn một mỗi lần chạy. SqlitePlanStore yêu cầu cơ sở dữ liệu được hỗ trợ bằng tệp; sử dụng InMemoryPlanStore cho những kế hoạch phù du hơn là ':memory:'.

Lời nhắc ở đuôi sẽ đọc cửa hàng theo mọi yêu cầu của mô hình, do đó, cửa hàng tăng giá sẽ không chạy được thay vì xuống cấp -- lời nhắc không phải là nỗ lực tốt nhất. Đó là sự cố ý: một kế hoạch mà mô hình không còn nhìn thấy nữa không phải là trạng thái để tiếp tục thực hiện trong im lặng. Chính sách thử lại và dự phòng thuộc về cửa hàng, không thuộc về Planningvà PlanStore là một giao thức chính xác để bạn có thể gói một giao thức:

class BestEffort:
    """Serve the last known plan when the backing store is unreachable."""

    def __init__(self, inner: PlanStore) -> None:
        self._inner, self._last = inner, []

    async def get_items(self) -> list[PlanItem]:
        try:
            self._last = await self._inner.get_items()
        except ConnectionError:
            pass
        return self._last

    # ... delegate the other five methods to `self._inner`

Lập kế hoạch và thực hiện trong các hoạt động riêng biệt

Cửa hàng dùng chung là toàn bộ cơ chế chuyển giao giữa hai lần chạy. Một agent viết kế hoạch, agent thứ hai thực hiện nó và kế hoạch là trạng thái duy nhất giao thoa giữa chúng:

store = SqlitePlanStore('plan.db', session='issue-403')

planner = Agent('anthropic:claude-opus-4-7', capabilities=[Planning(store=store)])
executor = Agent('anthropic:claude-sonnet-4-6', capabilities=[Planning(store=store)])

await planner.run('Investigate the issue and write a plan. Do not implement anything.')
await executor.run('Implement the plan.')

Người thi hành bắt đầu bằng không message_history, vì vậy nó không bao giờ trả tiền cho cuộc điều tra của người lập kế hoạch. Yêu cầu đầu tiên của nó chỉ mang theo lời nhắc mới cùng với lời nhắc kế hoạch mà khả năng này sẽ được xây dựng lại từ cửa hàng. Đó là lý do tại sao hai agent có thể chạy trên các mô hình khác nhau: một mô hình bối cảnh lớn có thể thực hiện việc đọc và suy luận, còn mô hình bối cảnh nhỏ hơn có thể thực thi dựa trên danh sách kiểm tra kết quả.

Nguyên tắc chỉ đọc của trình lập kế hoạch là thuộc tính về cách bạn định cấu hình agent đó (bộ công cụ nào nó nhận được và hướng dẫn của nó nói gì), chứ không phải thứ gì đó mà khả năng thực thi.

Sự kiện

Đính kèm một PlanEventEmitter đến một cửa hàng để phản ứng với những thay đổi:

from pydantic_ai_harness.planning import InMemoryPlanStore, PlanEventEmitter

emitter = PlanEventEmitter()

@emitter.on_completed
async def announce(event):
    print('done:', event.item.content)

store = InMemoryPlanStore(event_emitter=emitter)

Sự kiện đến từ các công cụ chi tiết (add_task, update_task_status, add_subtask, ...). write_plan là một sự thay thế toàn bộ kế hoạch và im lặng cho sự kiện, do đó, giao diện người dùng hoàn toàn do sự kiện điều khiển cũng nên đọc kế hoạch sau khi chạy hoặc hướng mô hình tới các công cụ chi tiết khi cần đưa tin về sự kiện trực tiếp.

Tại sao thay thế toàn bộ kế hoạch

Việc giải quyết các bước bằng chỉ số nguyên có thể thay đổi (chèn/xóa/sắp xếp lại) dễ xảy ra lỗi đối với cả mã và mô hình. write_plan restates the whole plan each call, so there are no indices to track. Chỉnh sửa chi tiết (add_task, update_task_status, remove_task) thay vào đó hãy tham chiếu ổn định id được hiển thị bởi read_plan.

Đảm bảo bộ nhớ đệm

Bản kế hoạch không bao giờ được chèn vào system prompt hoặc instructions. Hướng dẫn sử dụng tĩnh nằm ở đó (giữ bộ đệm ổn định); chỉ bản kế hoạch có thể thay đổi mới đi qua lời nhắc ở phần đuôi tạm thời, vốn chỉ tồn tại trong bản sao theo từng request và không bao giờ được lưu trữ. Đặt inject=False để vô hiệu hóa. Ánh xạ AI Pydantic CachePoint dành cho các model có profile hỗ trợ caching prompt; trên các model khác, ánh xạ này bị bỏ qua.

Cấu hình

from pydantic_ai_harness import Planning

Planning(
    guidance=None,           # static system-prompt guidance; None = default, '' = omit
    cache_ttl='5m',          # TTL for the cache breakpoint after the stable opening tag ('5m' | '1h')
    store=None,              # None = fresh in-memory plan per run; or a PlanStore to persist
    enable_subtasks=False,   # add subtask/dependency tools and the 'blocked' status
    inject=True,             # surface the current plan as a cache-safe tail reminder
    tools=None,              # None = every tool the mode registers; or an allowlist of names
    descriptions=None,       # optional per-tool description overrides, keyed by tool name
)

Thông số agent (YAML/JSON)

Planning hoạt động với thông số agent của Pydantic AI:

# agent.yaml
model: anthropic:claude-sonnet-4-6
capabilities:
  - Planning: {}
from pydantic_ai import Agent
from pydantic_ai_harness import Planning

agent = Agent.from_file('agent.yaml', custom_capability_types=[Planning])
result = agent.run_sync('...')
print(result.output)

Đọc thêm

Tham chiếu API

::: pydantic_ai_harness.planning.Planning

Mục lục nguồn