Viết factory đầu tiên của bạn

Tự viết một factory you-agent-factory theo từng bước, bằng định dạng đồ thị khai báo hoặc định dạng bộ điều phối JavaScript.

Nó là gì

Một định nghĩa factory đặt tên cho ba thứ. Loại công việc là các nhóm công việc chảy qua nó, mỗi loại có một trạng thái khởi đầu, một trạng thái kết thúc và một trạng thái thất bại. Worker là runtime thực sự thực thi — một tác tử, một script, một lời gọi suy luận. Workstation là bước xử lý: nhận công việc ở một trạng thái, điều phối nó tới worker, rồi đẩy nó sang trạng thái kế tiếp. Mọi thứ còn lại — thử lại, vòng rà soát, guard, chạy song song, tài nguyên dùng chung — đều được thêm vào bộ khung đó về sau.

Khi nào dùng

Hãy tự viết khi một factory đóng gói làm gần đúng điều bạn muốn nhưng chưa đủ. Bắt đầu từ định nghĩa nhỏ nhất chạy được trọn vẹn, rồi mới mở rộng. Một factory không chạy chẳng dạy bạn điều gì; một factory chạy tệ lại cho biết chính xác cần sửa gì tiếp theo.

Chọn định dạng

Trường orchestrator quyết định engine nào chạy factory của bạn, và lựa chọn đó quyết định cách bạn viết nó. Factory đồ thị mô tả một cấu trúc liên kết và để engine đưa công việc chạy qua đó. Factory JavaScript mô tả một thủ tục và gọi thẳng runtime. Không cái nào là tập con của cái kia: dạng đồ thị cho bạn trạng thái bền vững theo từng hạng mục và tính đồng thời miễn phí, còn dạng JavaScript cho bạn luồng điều khiển thông thường.
Câu hỏiFactory đồ thịFactory JavaScript
Bạn viết cái gì?Loại công việc, worker và workstation bằng JSON hoặc YAML.Một hàm JavaScript cộng một khối orchestrator.
Luồng điều khiển đi thế nào?Công việc di chuyển giữa các trạng thái; workstation nào có công việc ở trạng thái đầu vào thì chạy.Từ trên xuống dưới, với await, vòng lặp và điều kiện thông thường.
Trạng thái nằm ở đâu?Ngay trong chính các hạng mục công việc, bền vững, mỗi hạng mục một bản.Trong biến của script, kèm checkpoint tường minh khi cần khôi phục.
Bạn phải khai báo gì?Mọi trạng thái mà một hạng mục công việc có thể ở.Một lược đồ tham số và một chính sách thực thi.
Bỏ trống khối orchestrator là hợp lệ và có nghĩa là đồ thị: các định nghĩa sẵn có nạp theo mặc định tương thích vào engine Petri. Dù vậy hãy khai báo tường minh — một factory JavaScript quên khai báo sẽ thất bại theo cách rất khó hiểu.

Bắt đầu từ một ví dụ chạy được

Khởi đầu nhanh và chắc nhất là một factory đóng gói bạn đã chạy. Cài nó vào một thư mục gốc cục bộ của dự án, bạn sẽ có một định nghĩa chắc chắn hợp lệ, chắc chắn chạy được, và đủ nhỏ để đọc hết trong một lần. @you/subagent là cái nhỏ nhất: một loại công việc, một worker, một workstation.
you init --package @you/subagent --dir ./factory --replace
Hãy đọc định nghĩa đã cài trước khi sửa. Đổi tên workstation, trỏ nó vào lời nhắc của riêng bạn, rồi chạy lại — đó là bước sửa đầu tiên nhỏ hơn nhiều so với viết tệp từ đầu, và giữ nguyên mọi trường đã làm nó hợp lệ.

Viết factory đồ thị

Dựng định nghĩa theo đúng thứ tự engine đọc: khai báo công việc trước người làm, và người làm trước các bước sử dụng họ. Mỗi bước dưới đây thêm một mảng cấp cao nhất vào tệp.

Bước 1 — đặt tên cho factory

Đặt tên cho factory. Đây là trường cấp cao nhất duy nhất bắt buộc, và cũng là thứ mà các lệnh factory có tên sẽ tham chiếu sau này.

Bước 2 — khai báo loại công việc và các trạng thái của nó

Khai báo một loại công việc với ba trạng thái: trạng thái INITIAL nơi công việc gửi vào cập bến, trạng thái TERMINAL nghĩa là đã xong, và trạng thái FAILED cho công việc mà đồ thị không hoàn tất được. Gắn handlingBehavior DEFAULT để một lần chạy di động biết đặt dữ liệu đầu vào của lời gọi vào đâu.

Bước 3 — khai báo một worker

Khai báo một worker. Trường type quyết định những trường nào hợp lệ với nó: AGENT_WORKER nhận công cụ tác tử và thiết lập quyền, SCRIPT_WORKER nhận lệnh và tham số, INFERENCE_WORKER nhận các thao tác và vị trí chạy mô hình. Để trống model và provider để kế thừa mặc định vận hành bạn đã cấu hình lúc cài.

Bước 4 — khai báo một workstation

Khai báo một workstation. inputs nêu loại công việc và trạng thái nó tiêu thụ, outputs nêu trạng thái nó phát ra khi thành công, còn onFailure nêu trạng thái phát ra khi worker thất bại. body chính là lời nhắc: nó có thể chèn tham số lời gọi và tham chiếu hạng mục công việc đang xử lý.

Bước 5 — khai báo chữ ký lời gọi

Khai báo chữ ký lời gọi để bên gọi biết phải truyền gì. Mỗi tham số có tên nội bộ, tên ngoài dùng trên dòng lệnh, và các cách liên kết nó chấp nhận — văn bản vị trí, stdin qua ống dẫn, hoặc một cờ có tên.

Toàn bộ tệp

{
  "name": "summarize",
  "description": "Summarize one submitted request in a single agent pass.",
  "workTypes": [
    {
      "name": "task",
      "handlingBehavior": ["DEFAULT"],
      "states": [
        { "name": "init", "type": "INITIAL" },
        { "name": "complete", "type": "TERMINAL" },
        { "name": "failed", "type": "FAILED" }
      ]
    }
  ],
  "workers": [
    {
      "name": "summarizer",
      "type": "AGENT_WORKER",
      "agentTools": { "policy": "READ_ONLY" },
      "skipPermissions": true
    }
  ],
  "workstations": [
    {
      "name": "summarize-request",
      "type": "AGENT_RUN",
      "worker": "summarizer",
      "inputs": [{ "workType": "task", "state": "init" }],
      "outputs": [{ "workType": "task", "state": "complete" }],
      "onFailure": [{ "workType": "task", "state": "failed" }],
      "body": "Read the request below in full and return a self-contained summary with the key claims, the evidence behind them, and anything you could not verify.\n\nRequest:\n${input}\n"
    }
  ],
  "invocationSignature": {
    "parameters": [
      {
        "name": "input",
        "externalName": "to",
        "description": "Text request to summarize.",
        "required": true,
        "bindings": [{ "kind": "POSITIONAL", "position": 1 }, { "kind": "STDIN" }, { "kind": "NAMED" }]
      }
    ]
  }
}
Tám loại workstation và sáu loại worker mỗi loại chấp nhận một tập trường khác nhau. Trang tham chiếu lược đồ liệt kê trường nào dùng chung, trường nào chỉ thuộc về một biến thể, và trường nào bị từ chối.

Viết factory JavaScript

Factory JavaScript thay đồ thị workstation bằng một script. Không có loại công việc, worker hay workstation nào phải khai báo — khối orchestrator mang mã nguồn, lược đồ tham số và chính sách an toàn, còn bản thân script gọi các tác tử theo thứ tự bạn viết.

Bước 1 — khai báo loại bộ điều phối

Đặt orchestrator.kind thành JAVASCRIPT. Không đặt thì định nghĩa sẽ nạp như một factory đồ thị theo mặc định tương thích, và engine sẽ đi tìm những workstation vốn không tồn tại.

Bước 2 — trỏ tới mã nguồn quy trình

Trỏ tới mã nguồn quy trình. Dùng sourceRef với đường dẫn tương đối theo factory khi script nằm cạnh định nghĩa, hoặc inlineSource khi bạn muốn định nghĩa mang thẳng nội dung script. Các factory JavaScript đóng gói dùng dạng nội tuyến để phát hành gọn trong một tệp.

Bước 3 — khai báo lược đồ tham số

Khai báo argsSchema như một đối tượng JSON Schema. Nó kiểm tra tham số trước khi script khởi chạy, và cũng là nguồn để điền giá trị cho liên kết args trong script.

Bước 4 — đặt chính sách mặc định

Đặt defaultPolicy. Nó giới hạn những gì quy trình được phép làm khi không có ghi đè từ runtime: tổng số lời gọi tác tử, số lời gọi chạy đồng thời, độ sâu lồng nhau của điều phối con, có cho phép truy cập mạng không, và những thư mục gốc nào ghi được. READ_ONLY cùng danh sách thư mục ghi được để trống là điểm khởi đầu an toàn.

Mã nguồn quy trình

return (async function () {
  phase("draft");
  const draft = await agent.run({
    label: "drafter",
    prompt: "Write a first draft that answers the request in full.\n\nRequest:\n" + args.request,
  });
  if (draft.status !== "COMPLETED") {
    throw "drafting failed";
  }

  phase("review");
  const reviews = await parallel([
    {
      label: "review-accuracy",
      prompt: "Judge this draft for factual accuracy. List every unsupported claim.\n\n" + draft.output.text,
    },
    {
      label: "review-completeness",
      prompt: "Judge this draft for completeness. List every part of the request it does not answer.\n\nRequest:\n" +
        args.request + "\n\nDraft:\n" + draft.output.text,
    },
  ]);

  phase("revise");
  const final = await agent.run({
    label: "reviser",
    prompt: "Revise the draft so it survives both reviews. Return only the revised text.\n\nDraft:\n" +
      draft.output.text + "\n\nReviews:\n" + JSON.stringify(reviews.map((r) => r.output.text)),
  });
  if (final.status !== "COMPLETED") {
    throw "revision failed";
  }
  return final.output.text.trim();
})();

Định nghĩa nạp nó

{
  "name": "draft-review-revise",
  "description": "Drafts an answer, reviews it from two angles, and revises once.",
  "orchestrator": {
    "kind": "JAVASCRIPT",
    "javascript": {
      "sourceRef": "workflows/draft-review-revise.js",
      "argsSchema": {
        "type": "object",
        "required": ["request"],
        "additionalProperties": false,
        "properties": {
          "request": { "type": "string", "minLength": 1 }
        }
      },
      "defaultPolicy": {
        "mode": "READ_ONLY",
        "maxAgents": 8,
        "concurrency": 2,
        "maxDepth": 1,
        "maxRetries": 0,
        "allowNetwork": false,
        "writableRoots": []
      }
    }
  },
  "invocationSignature": {
    "parameters": [
      {
        "name": "request",
        "externalName": "to",
        "description": "Request to draft, review, and revise.",
        "required": true,
        "bindings": [{ "kind": "POSITIONAL", "position": 1 }, { "kind": "STDIN" }, { "kind": "NAMED" }]
      }
    ]
  }
}
Script chạy trên một tập liên kết runtime cố định: args và meta cho dữ liệu đầu vào của lời gọi, agent.run cho một lần điều phối con, parallel và pipeline để chạy song song, phase và log cho tiến độ, và không gian tên workflow cho ngân sách, checkpoint, hiện vật và kết quả cuối.

Kiểm tra rồi chạy

Kiểm tra là bước tách biệt với chạy, và đáng làm trước: nó đối chiếu tải trọng với cùng hợp đồng mà endpoint kiểm tra factory qua HTTP sử dụng, mà không khởi động runtime nào. Khi đã qua, hãy chạy thẳng tệp đó như một factory di động.

Kiểm tra trước khi chạy

you factory config validate ./factory/factory.json

Chạy nó như một factory di động

you run --factory ./factory/factory.json "Summarise this repository"
Một lần chạy di động cần biết loại công việc nào nhận dữ liệu đầu vào của lời gọi. Factory chạy bằng --factory phải khai báo handlingBehavior DEFAULT trên đúng một loại công việc — không hơn, không kém.

Hoặc cài nó dưới một cái tên và chạy từ bất cứ đâu

you factory create summarize --from ./factory/factory.json --set-current
you run --named summarize "Summarise this repository"

Mở rộng tệp

Một tệp duy nhất thôi hết dễ chịu vào khoảng workstation thứ ba. Bố cục tách rời ghi ra factory.json chuẩn cùng các thư mục workers và workstations, nhờ đó mỗi bước thành một tệp riêng và phần khác biệt vẫn dễ đọc.
you factory config expand ./factory/factory.json
Thao tác ngược lại ghi dạng một tệp chuẩn ra stdout, tiện khi cần so sánh bố cục tách rời với một định nghĩa ai đó gửi cho bạn.
you factory config flatten ./factory

Lỗi thường gặp

Ba sai lầm chiếm phần lớn thất bại của factory đầu tiên. Một workstation có trạng thái đầu vào mà chẳng công việc nào đến được, khiến lần chạy nằm không rồi thoát mà chưa làm gì. Một worker được tham chiếu bằng cái tên không khớp mục nào trong mảng workers. Và những trường mượn từ loại worker khác — công cụ tác tử gắn cho script worker, hay định tuyến mô hình gắn cho poller — bị lược đồ từ chối, vì mỗi loại worker chọn riêng tập trường của mình.

Để một factory viết hộ

Có factory đóng gói chuyên tạo ra factory. @you/factory-builder nhận một yêu cầu bằng ngôn ngữ thường, tạo ra một định nghĩa đã kiểm tra theo dạng bạn chọn, rồi cài nó dưới một cái tên bạn có thể chạy ngay.
you init --package @you/factory-builder
you run --named @you/factory-builder --factory-name release-note-review --orchestrator graph \
  --to "Review submitted release notes and return an approved summary."
Tham số orchestrator chọn dạng mà bộ tạo sẽ viết: graph cho cấu trúc YAML, javascript cho bộ điều phối JavaScript. Mặc định là graph.

Thẻ