跳到正文
DEV Community· Jeff·· 4 小時前AI 評分55

批量端點已存在,Agent 卻仍採用逐項循環

The Agent Reached for a Per-Item Loop When the Bulk Endpoint Already Existed

AI 導讀

Agent 為逐一更新客戶記錄而寫出逐項請求循環;在 staging 處理 400 條記錄時,工作因請求遭限流而中途受阻,但 API 其實已有一次提交陣列的批量更新端點。文章建議先查閲資源的操作清單,確認批量回應格式、冪等性及非同步處理方式,並在測試中驗證請求次數和部分失敗分支。

正文

The task read like a simple mapping: reconcile a list of customer records against the current system and update each one. The agent produced a clean for-each loop: fetch the record, compare, patch, move to the next. The unit test used three fixture rows, ran in milliseconds, and reported green. Staging used four hundred records, and the job became four hundred sequential requests that throttled halfway through.

The API already had a bulk update endpoint that accepted an array in one call and returned a per-item result envelope. The agent never looked for it. It reasoned from the single-item sample call it had in context and treated looping over an array as the universal shape.

Why the loop felt like the obvious answer

An agent that sees one GET and one PATCH for a single record has no signal that a batch path exists. A loop over an array is the most general program it can write from that evidence, and it reads as correct: each element gets the same treatment, errors can be caught per row, and the code is easy to read back. None of that checks whether the server already solved the N-requests problem.

Bulk endpoints differ in ways a per-item loop does not model: the request body is an array rather than a single object, the response carries a partial-failure list instead of one status, and large jobs often run as an accepted async task rather than completing inline. A loop hides all of that behind repeated single calls.

Dimension Per-item loop Existing bulk endpoint
Requests for N records N calls 1 call
Failure model One error stops or skips a row Per-item success/failure envelope
Rate limit exposure N chances to be throttled One request under the limit
Partial completion Handed by the caller Reported by the server
Consistency Rows drift between calls Server applies the batch atomically or per row

The three-row fixture makes both shapes indistinguishable in a test. Speed, correctness, and green status all hold at that size; the difference only appears when N grows and the throttle or the connection pool starts counting.

Check for a batch path before writing the loop

Before an agent commits to a loop over a resource, the cheap gate is a question: does this API expose a bulk or batch operation for the same write? That requires reading the operation list for the resource, not replaying the one sample call.

Practical checks that catch this early:

  • Estimate N from the real input size, not the fixture. A loop over three rows and a loop over four hundred rows are different programs.
  • Look for operations named bulk, batch, update-many, or a body that accepts an array of records. Do not assume the single-item path is the only write.
  • Read the bulk response shape. A batch endpoint usually returns which items succeeded, which failed, and why; design the caller around that envelope instead of inventing your own retry per row.
  • Confirm idempotency on the bulk path. Reconciliation jobs get re-run, and a batch that applies twice needs a key or a stable record reference the same way a single call does.
  • Watch for async acceptance. A bulk job may return 202 with a job id rather than the final result; the caller then polls, which the per-item loop never anticipated.

Keeping the operation list readable locally makes this scan possible without reconstructing the API from one captured call. In Powerduck the spec stays the source of truth on disk, so a bulk operation shows up in the operation list rather than having to be rediscovered from a sample exchange.

Prove the call count in the test

A test that asserts the updated value on three rows will not expose N requests. Add a recorder that counts outbound calls for a representative batch size and assert the expected shape: one bulk request carrying the array, or an explicit decision that the per-item loop is justified because no batch path exists.

Also assert the partial-failure branch. A bulk response that returns twenty successes and five failures should leave the caller able to report and retry the five, not treat the whole call as a generic error. That branch rarely appears when the agent wrote a loop it assumed would always succeed row by row.

The honest fallback is still a loop when no batch endpoint exists, but it should be a deliberate choice after checking, not the default assumption. The expensive version is the loop written because the agent never looked past the single sample call.

Where does your reconciliation code fall today: one deliberate per-item path, or a loop written before anyone checked whether the resource already offered a batch?

來源:DEV Community · dev.to