HINDI TUMITIGIL ANG MUNDO.RSS
BIG CHANGE.
Isang tap lang, BIG CHANGE na
Isang tap lang, BIG CHANGE na

Bigyang-puwang ang malawak na pananaw.

Idagdag ang BIG CHANGE sa home screen o desktop mo. Bumubukas ito sa sarili nitong window, na may mga pinakabagong kuwento kapag online ka.

iPhone at iPad
Buksan ang bigchange.ai sa Safari. I-tap ang Share, pagkatapos ay Add to Home Screen. I-on ang Open as Web App kung ipinapakita, pagkatapos ay i-tap ang Add.
Android
Buksan ang bigchange.ai sa Chrome. Sa menu ng browser, piliin ang Install app o Add to Home screen.
Desktop
Sa Chrome o Edge, gamitin ang icon sa pag-install sa address bar o ang app menu ng browser. Sa Safari sa Mac, piliin ang File → Add to Dock.

Markdown edition

AI-translated from English; not yet reviewed by a fluent editor.

# Gawing nasuring talaan ng mga aksyon ang output ng agent

> Gumawa ng resultang may tiyak na uri gamit ang OpenAI Agents SDK mula sa sarili mong mga tala, suriin ang ebidensya at kahulugan, saka ipasa ang tinanggap na resulta sa lokal na Markdown na talaan ng aksyon na may muling pagbasa at pagsusuri ng hash.

By BIG CHANGE Editorial

Published: 2026-10-20T12:52:38.610Z
Updated: 2026-10-20T12:52:38.610Z
Canonical: https://bigchange.ai/blog/agents-sdk-reviewed-action-register-guide

![Conceptual charcoal illustration of one person holding a larger blank ruled source page and a smaller blank candidate page, with an orange reading strip across the source.](https://bigchange.ai/api/media/file/source-candidate-human-review-hero-v2.png)
AI-generated conceptual illustration by BIG CHANGE.

Maaaring tama ang JSON na anyo ng resulta ng agent ngunit mali ang pagbasa sa pinagmulan. Nagbibigay ang gabay sa Python developer ng buong landas mula sa isang pinapayagang file ng tala tungo sa lokal na talaan: resultang may tiyak na uri mula sa producer, pagsusuri ng pinagmulan at kahulugan, pag-apruba ng tao sa eksaktong mga hash, at consumer na nagsusulat at muling bumabasa ng nakagrupong Markdown report. Gumamit ng sarili mong tala na may tahasang pangako sa aksyon. Walang tunay na tala o resulta ng model ang ginamit sa paghahanda.

## Ang malaking pagbabago

- **Ano ang nagbago:** Tumatanggap ang OpenAI Agents SDK ng Pydantic `output_type`, kaya maaaring humiling ang application ng malinaw na tinukoy na resulta at suriin ito bago gamitin. Nagdadagdag ang halimbawa ng mga sipi sa pinagmulan at kontratang may bersyon sa resulta.
- **Bakit mahalaga:** Maaaring ihinto ng developer na nag-uugnay sa agent sa susunod na hakbang ang malformed, kulang o walang batayang output bago ito maging listahan ng aksyon. Kailangan pa ring pasyahan ng tagasuri kung sinusuportahan ng siniping tala ang bawat gawain, may-ari at petsa at kung may nakaligtaan ang model.
- **Ano ang dapat bantayan:** Ang punto ng pasya ay nasa hangganan ng consumer. Lokal na talaan para sa pag-uuri lamang ang ginagawa ng recipe matapos maaprubahan ang eksaktong run, pinagmulan at kandidato. Ang susunod na pag-import sa task system ay mangangailangan ng sarili nitong awtoridad, tuntunin sa pag-ulit at muling pagbasa sa destinasyon.

## Maghanda ng isang awtorisadong pinagmulan

Kailangan mo ng Python 3.12, OpenAI API account na awtorisado para sa mga tala, tagasuring makakabasa ng orihinal at model na nakumpirma mong kasalukuyang may JSON-schema structured-output support sa account. Suriin ang mga tuntunin sa data at kasalukuyang presyo bago patakbuhin ang producer. Huwag maglagay ng credential sa tala o pag-apruba. Ang tanging pagtawag sa model sa ibaba ay `produce`; lokal na pagproseso ang iba.

I-save ang orihinal mong tala bilang UTF-8 sa `notes.txt`. Dapat may aktuwal na tahasang pangako ng aksyon mula sa sarili mong trabaho. Magtalaga ng matatag na `source_id`, gaya ng sarili mong ID ng rekord, at huwag baguhin ang kahit isang byte hanggang sa pagsusuri at paggamit. Gumawa ng `candidate/` bago mag-produce; dapat bagong file ang kandidato. Maghanda ng hiwalay na output directory para sa lokal na report.

Itala ang hash ng mga byte ng pinagmulan bago patakbuhin:

```sh
python -c "from pathlib import Path; import hashlib; print(hashlib.sha256(Path('notes.txt').read_bytes()).hexdigest())"
```

Sa nakahiwalay na Python 3.12 environment, gumawa ng `recipe-requirements.txt` na may eksaktong mga linyang ito at i-install:

```text
openai-agents==0.24.0
pydantic==2.14.1
```

```sh
python -m pip install -r recipe-requirements.txt
mkdir candidate
```

Sabay na na-install ang mga bersyong ito sa lokal na Python 3.12.7 environment noong 20 Oktubre 2026. Kumpirmahin ang pagiging tugma at availability ng model kapag ginagamit mo ang gabay. I-save ang buong script sa ibaba bilang `action_register_recipe.py` sa parehong directory. May dalawa itong command: `produce` ay gumagawa ng kandidato at resibo ng run; `consume` ay bumubuo ng report matapos lamang ang validation at pag-apruba.

## Patakbuhin ang producer na may tiyak na uri

Ang kontratang `Extraction` ay nangangailangan ng bersyong `action-register/v1`, katayuang `ready`, `partial` o `blocked`, ID at SHA-256 ng eksaktong mga byte ng pinagmulan, mga aksyon at isang `gap_note`. Bawat aksyon ay nangangailangan ng teksto, eksaktong sipi at saklaw ng linya na nagsisimula sa 1, may-ari at petsang maaaring null, at `complete` o `needs_review` bilang katayuan ng ebidensya. Ang null na may-ari o petsa ay nangangahulugang hindi iyon sinabi sa tala. Inuutusan ang model na huwag hulaan ang alinman. Kailangan ang lahat ng patlang at tinatanggihan ang mga dagdag.

Tahasang piliin ang model na may structured output. Ilagay ang sarili mong pinapayagang path at ID:

```sh
python action_register_recipe.py produce --source-id OWNED-ID --source notes.txt --candidate candidate/actions.json --model YOUR-STRUCTURED-OUTPUT-MODEL
```

Basahin ang `candidate/actions.json` katabi ng `candidate/actions.run.json`. Itinatala ng huli ang UUID ng run, mga hash ng pinagmulan at kandidato, huling agent at hiniling na model. Sa kabiguan, gumagawa sa halip ng diagnostic record na `.failure.json` na may ID ng run sa hulihan. Ang pagkaantala, `None` o purong string na huling output, o di-inaasahang huling agent, ay hindi tagumpay. Hindi iniimbak ng command ang naipagpapatuloy na SDK state na `RunState`; hindi maipagpapatuloy ng resibo ng kabiguan ang run. Suriin ang request, kandidato at anumang kasunod na estado bago magpasya kung angkop ang bagong run.

## Suriin ang kahulugan at aprubahan ang eksaktong kandidato

Sinusuri ng application ang mahigpit na mga uri at kailangang patlang, identidad ng pinagmulan, ready na katayuan, kahit isang kumpletong aksyon, wastong saklaw ng linya, sipi sa nasabing saklaw, hindi blangkong gawain o may-ari at pamantayang mga petsang `YYYY-MM-DD`. Pinatutunayan nito ang istruktura at lokasyon ng sipi. Hindi nito napapatunayang totoong pangako ang pangungusap, tama ang kahulugan ng pangalan o petsa, o nahanap ang lahat ng pangako.

Basahin ang orihinal na tala at bawat mungkahing aksyon. Ihambing ang kahulugan, may-ari, petsa, sipi at pagkukulang. Lutasin ang kalabuan sa bagong nasuring run; huwag aprubahan ang walang batayan, kulang o blocked na kandidato. Matapos tiyaking tugma ang hindi nabagong file at kandidato sa `actions.run.json`, isulat ang `approval.json` na may eksaktong pitong key na ito. Kopyahin ang ID at mga hash mula sa sinuring resibo. Gamitin ang tunay na ID ng tagasuri at makabuluhang paglalarawan ng aktuwal na sinuri:

```json
{
  "approved": true,
  "run_id": "COPY-RUN-ID",
  "source_id": "OWNED-ID",
  "source_sha256": "COPY-SOURCE-SHA256",
  "payload_sha256": "COPY-PAYLOAD-SHA256",
  "reviewer": "YOUR-REVIEWER-ID",
  "review_note": "Describe the source, task, owner, date, quotation and omission checks actually performed."
}
```

`approved` ay dapat JSON boolean na `true`, hindi string o numero. String dapat ang ibang halaga; hindi maaaring blangko ang tagasuri at tala. Nabibigo ang dagdag na patlang. Isang kandidato at rebisyon ng pinagmulan ang saklaw ng pag-apruba, hindi anumang muling pagsulat.

## Gamitin at muling basahin ang report

```sh
python action_register_recipe.py consume --source-id OWNED-ID --source notes.txt --candidate candidate/actions.json --approval approval.json --out private-output
```

Iginugrupo ng consumer ang mga tinanggap na aksyon sa **Assigned with dates**, **Needs an owner** at **Needs a date**. Bawat entry ay may gawain, estado ng may-ari at petsa, sipi at mga linya ng pinagmulan. Isinusulat nito ang `action-register-<payload-hash-prefix>.md` at katabing `.receipt.json` na may mga hash ng run, pinagmulan, kandidato at report. Buksan pareho, ihambing ang siniping aksyon sa tala at suriin ang `report_sha256` laban sa mga byte ng Markdown file. Sinasabi lamang ng wastong resibo na nagawa at muling nabasa ang lokal na file; hindi nito pinapayagan ang pagsusulat sa panlabas na task system.

Ipinapakita ng consume command ang aktuwal na path ng report at resibo. Gamitin ang mga iyon sa pagsusuri ng byte:

```sh
python -c "from pathlib import Path; import hashlib,json,sys; report=Path(sys.argv[1]); receipt=json.loads(Path(sys.argv[2]).read_text(encoding='utf-8')); assert hashlib.sha256(report.read_bytes()).hexdigest()==receipt['report_sha256']; print('report hash matches receipt')" PATH-PRINTED-FOR-REPORT PATH-PRINTED-FOR-RECEIPT
```

Kapag may kandidato na, suriin ang pagtanggi gamit ang malinaw na sintetikong halimbawang istruktural. Kopyahin ang JSON sa ibang file, alisin ang alinmang kailangang patlang sa unang aksyon at tawagin ang `consume` gamit ang malformed file at bago at blangkong output directory. Dapat mabigo bago gumawa ng file. Huwag itong ituring na makatotohanang extraction o aprubahan. Halimbawa, inaalis ng sumusunod na lokal na pagsusuri ang `evidence_quote` mula sa kopya:

```sh
python -c "import json; from pathlib import Path; p=json.loads(Path('candidate/actions.json').read_text(encoding='utf-8')); p['actions'][0].pop('evidence_quote'); Path('candidate/SYNTHETIC-malformed.json').write_text(json.dumps(p), encoding='utf-8')"
python action_register_recipe.py consume --source-id OWNED-ID --source notes.txt --candidate candidate/SYNTHETIC-malformed.json --approval approval.json --out synthetic-rejection-output
```

Dapat mabigo ang ikalawang command at manatiling wala ang output directory. Huwag gamitin ang halimbawa kung walang unang aksyon ang totoong kandidato; kulang na iyon para sa consumer. Kung hindi tiyak ang pagsusulat, suriin ang deterministikong report at resibo bago ulitin. Maaaring gamitin muli ang kaparehong mga byte; ang magkaiba ay magpapatigil para sa pagkakasundo. Kailangan ng bagong pagsusuri ang binagong pinagmulan o bersyon ng schema. Huwag ulitin ang pagtawag sa model dahil lamang hindi malinaw ang lokal na tugon ng consumer.

## Buong Python recipe

Kopyahin ang script nang eksakto sa `action_register_recipe.py`:

```python
"""Private, bounded recipe. No model call occurs unless `produce` is explicitly run."""

import argparse
import hashlib
import json
import uuid
from datetime import date
from pathlib import Path
from typing import Literal

from pydantic import BaseModel, ConfigDict, StrictInt, StrictStr, ValidationError


class StrictModel(BaseModel):
    model_config = ConfigDict(extra="forbid", strict=True)


class Action(StrictModel):
    action_text: StrictStr
    evidence_quote: StrictStr
    line_start: StrictInt
    line_end: StrictInt
    owner: StrictStr | None
    due_date: StrictStr | None
    evidence_status: Literal["complete", "needs_review"]


class Extraction(StrictModel):
    schema_version: Literal["action-register/v1"]
    status: Literal["ready", "partial", "blocked"]
    source_id: StrictStr
    source_sha256: StrictStr
    actions: list[Action]
    gap_note: StrictStr | None


def digest(data: bytes) -> str:
    return hashlib.sha256(data).hexdigest()


def canonical(payload: Extraction) -> bytes:
    return json.dumps(payload.model_dump(mode="json"), sort_keys=True, ensure_ascii=False, separators=(",", ":")).encode("utf-8")


def check(payload: Extraction, source_id: str, source: bytes) -> None:
    if payload.source_id != source_id or payload.source_sha256 != digest(source):
        raise ValueError("source identity or revision mismatch")
    lines = source.decode("utf-8").splitlines()
    if payload.status == "ready" and (not payload.actions or payload.gap_note is not None):
        raise ValueError("ready requires actions and no gap")
    if payload.status != "ready":
        raise ValueError("partial or blocked result cannot reach consumer")
    for index, item in enumerate(payload.actions, 1):
        if item.evidence_status != "complete":
            raise ValueError(f"action {index}: evidence needs review")
        if not item.action_text.strip() or not item.evidence_quote.strip():
            raise ValueError(f"action {index}: empty task or evidence")
        if not 1 <= item.line_start <= item.line_end <= len(lines):
            raise ValueError(f"action {index}: invalid source line range")
        segment = "\n".join(lines[item.line_start - 1:item.line_end])
        if item.evidence_quote not in segment:
            raise ValueError(f"action {index}: quotation absent from source span")
        if item.owner is not None and not item.owner.strip():
            raise ValueError(f"action {index}: blank owner")
        if item.due_date is not None:
            try:
                if date.fromisoformat(item.due_date).isoformat() != item.due_date:
                    raise ValueError()
            except ValueError as exc:
                raise ValueError(f"action {index}: due date must be YYYY-MM-DD") from exc


def report(payload: Extraction) -> str:
    """Application consumer: a triage register grouped by missing ownership/date."""
    groups = [
        ("Assigned with dates", lambda x: x.owner is not None and x.due_date is not None),
        ("Needs an owner", lambda x: x.owner is None),
        ("Needs a date", lambda x: x.owner is not None and x.due_date is None),
    ]
    rows = ["# Action register for " + payload.source_id, "", "Review artifact; source meaning was approved separately.", ""]
    for heading, predicate in groups:
        rows += ["## " + heading, ""]
        matches = [(n, a) for n, a in enumerate(payload.actions, 1) if predicate(a)]
        for number, action in matches:
            rows += [f"{number}. {action.action_text}", f"   Owner: {action.owner or 'Unspecified'}; due: {action.due_date or 'Unspecified'}", f"   Source lines {action.line_start}-{action.line_end}: {action.evidence_quote}", ""]
        if not matches:
            rows += ["None.", ""]
    return "\n".join(rows)


def load_payload(path: Path) -> Extraction:
    return Extraction.model_validate_json(path.read_bytes(), strict=True)


def consume(source_id: str, source_path: Path, payload_path: Path, approval_path: Path, out_dir: Path) -> tuple[Path, Path]:
    source = source_path.read_bytes()
    payload = load_payload(payload_path)
    check(payload, source_id, source)
    run = json.loads(payload_path.with_suffix(".run.json").read_text(encoding="utf-8"))
    payload_hash = digest(canonical(payload))
    if run.get("source_id") != source_id or run.get("source_sha256") != digest(source) or run.get("payload_sha256") != payload_hash or run.get("last_agent") != "Owned-source action extractor" or not str(run.get("run_id", "")).strip():
        raise ValueError("producer receipt does not match accepted candidate")
    approval = json.loads(approval_path.read_text(encoding="utf-8"))
    if (type(approval) is not dict
            or set(approval) != {"approved", "run_id", "source_id", "source_sha256", "payload_sha256", "reviewer", "review_note"}
            or approval["approved"] is not True
            or any(type(approval[key]) is not str for key in ("run_id", "source_id", "source_sha256", "payload_sha256", "reviewer", "review_note"))
            or not approval["reviewer"].strip() or not approval["review_note"].strip()
            or approval["run_id"] != run["run_id"]
            or approval["source_id"] != source_id
            or approval["source_sha256"] != digest(source)
            or approval["payload_sha256"] != payload_hash):
        raise ValueError("human source/meaning approval must bind exact source and payload hashes")
    body = report(payload).encode("utf-8")
    stem = "action-register-" + payload_hash[:16]
    out_dir.mkdir(parents=True, exist_ok=True)
    target = out_dir / (stem + ".md")
    receipt = out_dir / (stem + ".receipt.json")
    record = {"run_id": run["run_id"], "source_id": source_id, "source_sha256": digest(source), "payload_sha256": payload_hash, "report_sha256": digest(body), "reviewer": approval["reviewer"], "operation": "local action-triage register"}
    encoded = (json.dumps(record, indent=2) + "\n").encode("utf-8")
    for path, data in [(target, body), (receipt, encoded)]:
        if path.exists():
            if path.read_bytes() != data:
                raise ValueError(f"uncertain prior output differs: {path}; inspect before retry")
        else:
            with path.open("xb") as handle:
                handle.write(data)
        if path.read_bytes() != data:
            raise IOError(f"readback failed: {path}")
    return target, receipt


def produce(source_id: str, source_path: Path, candidate_path: Path, model: str) -> None:
    from agents import Agent, Runner

    source = source_path.read_bytes()
    source_text = source.decode("utf-8")
    if not source_text.strip() or candidate_path.exists() or not candidate_path.parent.is_dir():
        raise ValueError("source must contain text; candidate must be new and its parent directory must already exist")
    run_id = str(uuid.uuid4())
    agent = Agent(
        name="Owned-source action extractor",
        model=model,
        instructions=("Extract only explicit action commitments from the supplied numbered source. "
                      "Return action-register/v1. Copy an exact quote with matching 1-based line span. "
                      "Use null for an unstated owner or due date; never infer them. "
                      "Use partial and needs_review for ambiguous evidence; blocked for unusable input. "
                      "Do not use tools or hand off."),
        output_type=Extraction,
    )
    numbered = "\n".join(f"{n}: {line}" for n, line in enumerate(source_text.splitlines(), 1))
    try:
        result = Runner.run_sync(agent, f"Source ID: {source_id}\nSHA-256: {digest(source)}\nNumbered source:\n{numbered}")
        if result.interruptions or result.last_agent is not agent or not isinstance(result.final_output, Extraction):
            raise ValueError("run interrupted, unfinished, or finished by unexpected agent; this CLI does not persist resumable RunState, so do not resume from its failure receipt")
        output = result.final_output
        if output.source_id != source_id or output.source_sha256 != digest(source):
            raise ValueError("producer returned wrong source identity")
        candidate = canonical(output)
        with candidate_path.open("xb") as handle:
            handle.write(candidate)  # Candidate only; consumer still requires review.
        receipt = {"run_id": run_id, "source_id": source_id, "source_sha256": digest(source), "payload_sha256": digest(candidate), "last_agent": result.last_agent.name, "model": model}
        with candidate_path.with_suffix(".run.json").open("x", encoding="utf-8") as handle:
            handle.write(json.dumps(receipt, indent=2) + "\n")
    except Exception as exc:
        failure = {"run_id": run_id, "source_id": source_id, "source_sha256": digest(source), "error_type": type(exc).__name__, "error": str(exc), "state": "unknown_or_blocked; inspect run and destination before retry"}
        with candidate_path.with_name(candidate_path.stem + "." + run_id + ".failure.json").open("x", encoding="utf-8") as handle:
            handle.write(json.dumps(failure, indent=2) + "\n")
        raise


def main() -> None:
    parser = argparse.ArgumentParser()
    sub = parser.add_subparsers(dest="command", required=True)
    for name in ("produce", "consume"):
        p = sub.add_parser(name)
        p.add_argument("--source-id", required=True)
        p.add_argument("--source", type=Path, required=True)
        if name == "produce":
            p.add_argument("--candidate", type=Path, required=True)
            p.add_argument("--model", required=True)
        else:
            p.add_argument("--candidate", type=Path, required=True)
            p.add_argument("--approval", type=Path, required=True)
            p.add_argument("--out", type=Path, required=True)
    args = parser.parse_args()
    if args.command == "produce":
        produce(args.source_id, args.source, args.candidate, args.model)
    else:
        print(*consume(args.source_id, args.source, args.candidate, args.approval, args.out), sep="\n")


if __name__ == "__main__":
    main()
```

## Mga limitasyon at sanggunian

Sinuri offline ang kontrata at lokal na consumer gamit ang limang test at pitong sintetikong kaso ng kunwaring producer o muling pagtatangka. Saklaw ang strict schema, pagtanggi bago gumawa ng file, paggrupo, hash at paghawak sa kabiguan. Walang schema na ipinadala sa provider, model na tinawag, tunay na talang kinuha, makatotohanang pag-apruba ng tao, report mula sa tunay na sanggunian o sinukat na bayarin o kalidad. Depende sa account ang bayad sa API; suriin ang kasalukuyang pagiging tugma, presyo at pahintulot sa data bago ipadala ang pinagmulan.

Para sa kaugnay na konteksto, ang [gabay ng BIG CHANGE sa pagpili ng AI task mula sa sariling trabaho](https://bigchange.ai/blog/map-work-choose-first-ai-task-guide) ay tumatalakay sa mas maagang pasya kung anong trabaho ang susubukan. Nagsisimula ito sa napili at pinapayagang extraction at dinadala ang resultang may tiyak na uri sa nasuring lokal na consumer.

### Mga sanggunian at karagdagang babasahin

- [OpenAI Agents SDK: Agents](https://openai.github.io/openai-agents-python/agents/) ay nagdodokumento ng Pydantic `output_type`. Hindi nito ibinibigay ang pag-apruba ng tao o lokal na consumer sa recipe.
- [OpenAI Agents SDK: Results](https://openai.github.io/openai-agents-python/results/) ay nagdodokumento ng `final_output`, `last_agent`, mga pagkaantala at `to_state()`. Hindi iniimbak ng CLI ang naipagpapatuloy na estado.
- [OpenAI Agents SDK: Quickstart](https://openai.github.io/openai-agents-python/quickstart/) ay tumatalakay sa pag-install at API key. Ilayo ang key sa pinagmulan at mga resibo.
- [OpenAI Structured Outputs](https://developers.openai.com/api/docs/guides/structured-outputs) ay nagpapaliwanag ng strict schema at suporta ng model. Kumpirmahin ang suporta ng napiling model.
- [Pydantic ConfigDict](https://docs.pydantic.dev/latest/api/config/) ay nagdodokumento ng mahigpit na validation at pagtanggi sa dagdag na patlang.
- [OpenAI Agents SDK 0.24.0](https://pypi.org/project/openai-agents/0.24.0/) at [Pydantic 2.14.1](https://pypi.org/project/pydantic/2.14.1/) ang eksaktong lokal na na-install na mga bersyon. Hindi nasubukan ang pagtanggap ng provider.

## Sources

- [OpenAI Agents SDK: Agents](https://openai.github.io/openai-agents-python/agents/) — Opisyal na manwal sa Pydantic output_type. Hindi nito ginagawa ang pag-apruba ng tao o lokal na consumer ng artikulo.
- [OpenAI Agents SDK: Results](https://openai.github.io/openai-agents-python/results/) — Opisyal na asal ng final_output, last_agent, pagkaantala at to_state. Hindi pinananatili ng recipe ang RunState o nag-aalok ng pagpapatuloy.
- [OpenAI Agents SDK: Quickstart](https://openai.github.io/openai-agents-python/quickstart/) — Opisyal na konteksto ng pag-install at API key; walang key o totoong tawag sa provider ang ginamit sa paghahanda.
- [OpenAI Agents SDK: sanggunian sa output schema](https://openai.github.io/openai-agents-python/ref/agent_output/) — Opisyal na sanggunian sa strict output-schema generation; hindi patunay ng pagtanggap ng provider ang lokal na pagsusuri.
- [OpenAI Structured Outputs](https://developers.openai.com/api/docs/guides/structured-outputs) — Mga tuntunin sa kailangang patlang at additionalProperties at pagiging tugma ng model; dapat kumpirmahin ng mambabasa ang model sa oras ng paggamit.
- [Pydantic ConfigDict](https://docs.pydantic.dev/latest/api/config/) — Nagpapaliwanag ng strict at extra-forbid; gawain pa rin ng tao ang pagsusuri ng kahulugan laban sa pinagmulan.
- [Release ng openai-agents 0.24.0](https://pypi.org/project/openai-agents/0.24.0/) — Eksaktong SDK version na na-install sa nakahiwalay na lokal na Python 3.12.7 offline check; walang tawag sa model o bayarin.
- [Release ng Pydantic 2.14.1](https://pypi.org/project/pydantic/2.14.1/) — Eksaktong bersyon ng validation library na lokal na na-install kasama ng SDK 0.24.0.
- [BIG CHANGE: Imapa ang sarili mong trabaho at pumili ng unang gawaing susubukan sa AI](https://bigchange.ai/blog/map-work-choose-first-ai-task-guide) — Kaugnay na gabay sa pagpili ng gawain bago ang integrasyong ito; hindi nito pinatutunayan ang kawastuhan ng recipe.