ai-agent-book 精选快照(<2MB 代码与文档,来自 github.com/bojieli/ai-agent-book)
Build latest book artifacts / build (push) Canceled after 0s
dependency resolution / resolve (3.11) (push) Canceled after 0s
dependency resolution / resolve (3.13) (push) Canceled after 0s
deploy-pages / build (push) Canceled after 0s
deploy-pages / deploy (push) Canceled after 0s
i18n consistency check / check (push) Canceled after 0s
provider adoption tests / test (chapter2/context-compression) (push) Canceled after 0s
provider adoption tests / test (chapter2/prompt-injection) (push) Canceled after 0s
provider adoption tests / test (chapter2/system-hint) (push) Canceled after 0s
provider adoption tests / test (chapter3/log-sanitization) (push) Canceled after 0s
web-search-agent tests / test (push) Canceled after 0s
web-search-agent tests / agentbook (push) Canceled after 0s
Build latest book artifacts / build (push) Canceled after 0s
dependency resolution / resolve (3.11) (push) Canceled after 0s
dependency resolution / resolve (3.13) (push) Canceled after 0s
deploy-pages / build (push) Canceled after 0s
deploy-pages / deploy (push) Canceled after 0s
i18n consistency check / check (push) Canceled after 0s
provider adoption tests / test (chapter2/context-compression) (push) Canceled after 0s
provider adoption tests / test (chapter2/prompt-injection) (push) Canceled after 0s
provider adoption tests / test (chapter2/system-hint) (push) Canceled after 0s
provider adoption tests / test (chapter3/log-sanitization) (push) Canceled after 0s
web-search-agent tests / test (push) Canceled after 0s
web-search-agent tests / agentbook (push) Canceled after 0s
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
# Live diagnosis experiment PRD
|
||||
|
||||
- R1 (P0): Every refund must call `verify_refund_eligibility` before
|
||||
`process_refund`; a refund without the check is a policy violation.
|
||||
- R2 (P1): `check_stock` must complete within 250 ms. On origin timeout the
|
||||
orchestrator must use the degraded cache route; it must not simply fail.
|
||||
- R3 (P1): Regression cases must cite the source trajectory ID and the exact
|
||||
observed turn where the violation is visible.
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
# Live diagnosis experiment architecture
|
||||
|
||||
The orchestrator calls a local HTTP order service. Refund flows MUST call
|
||||
`verify_refund_eligibility` before `process_refund`. Inventory origin calls
|
||||
have a 250 ms client deadline; on timeout the orchestrator MUST call the same
|
||||
`check_stock` operation through the degraded cache route and finish normally.
|
||||
Every trajectory turn records its measured HTTP latency and raw response.
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
"""Small real HTTP system used by the Experiment 5-8 campaign.
|
||||
|
||||
The service intentionally exposes ordinary order, refund, and inventory
|
||||
endpoints. The buggy/fixed distinction lives in the orchestrator under test:
|
||||
the buggy orchestrator skips a required endpoint and mishandles an inventory
|
||||
timeout, while the fixed orchestrator makes the required calls and degrades.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import time
|
||||
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
|
||||
from urllib.parse import parse_qs, urlparse
|
||||
|
||||
|
||||
class Handler(BaseHTTPRequestHandler):
|
||||
server_version = "Experiment58HTTP/1.0"
|
||||
|
||||
def log_message(self, fmt: str, *args: object) -> None:
|
||||
print(
|
||||
json.dumps(
|
||||
{
|
||||
"client": self.client_address[0],
|
||||
"message": fmt % args,
|
||||
"time": time.time(),
|
||||
},
|
||||
ensure_ascii=False,
|
||||
),
|
||||
flush=True,
|
||||
)
|
||||
|
||||
def _json(self, status: int, value: object) -> None:
|
||||
raw = json.dumps(value, ensure_ascii=False).encode("utf-8")
|
||||
self.send_response(status)
|
||||
self.send_header("content-type", "application/json; charset=utf-8")
|
||||
self.send_header("content-length", str(len(raw)))
|
||||
self.end_headers()
|
||||
try:
|
||||
self.wfile.write(raw)
|
||||
except BrokenPipeError:
|
||||
# A timed-out client is an expected part of the observed buggy run.
|
||||
pass
|
||||
|
||||
def _body(self) -> dict[str, object]:
|
||||
length = int(self.headers.get("content-length") or 0)
|
||||
if not length:
|
||||
return {}
|
||||
value = json.loads(self.rfile.read(length))
|
||||
return value if isinstance(value, dict) else {}
|
||||
|
||||
def do_GET(self) -> None: # noqa: N802 - BaseHTTPRequestHandler contract
|
||||
parsed = urlparse(self.path)
|
||||
if parsed.path == "/health":
|
||||
self._json(200, {"ok": True})
|
||||
return
|
||||
if parsed.path.startswith("/orders/"):
|
||||
order_id = parsed.path.rsplit("/", 1)[-1]
|
||||
self._json(200, {"order_id": order_id, "status": "paid", "sku": "SKU-42"})
|
||||
return
|
||||
if parsed.path.startswith("/inventory/"):
|
||||
sku = parsed.path.rsplit("/", 1)[-1]
|
||||
degraded = parse_qs(parsed.query).get("degraded", ["0"])[0] == "1"
|
||||
if degraded:
|
||||
self._json(200, {"sku": sku, "stock": 12, "source": "cache", "degraded": True})
|
||||
else:
|
||||
# Longer than the campaign's real client deadline.
|
||||
time.sleep(0.8)
|
||||
self._json(200, {"sku": sku, "stock": 12, "source": "origin", "degraded": False})
|
||||
return
|
||||
self._json(404, {"error": "not_found"})
|
||||
|
||||
def do_POST(self) -> None: # noqa: N802 - BaseHTTPRequestHandler contract
|
||||
body = self._body()
|
||||
if self.path == "/refund/eligibility":
|
||||
self._json(200, {"order_id": body.get("order_id"), "eligible": True})
|
||||
return
|
||||
if self.path == "/refund/process":
|
||||
self._json(200, {"order_id": body.get("order_id"), "refund_id": "RF-LIVE-1"})
|
||||
return
|
||||
if self.path == "/notifications":
|
||||
self._json(200, {"sent": True, "status": body.get("status")})
|
||||
return
|
||||
self._json(404, {"error": "not_found"})
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--port", type=int, required=True)
|
||||
args = parser.parse_args()
|
||||
server = ThreadingHTTPServer(("127.0.0.1", args.port), Handler)
|
||||
print(json.dumps({"listening": args.port}), flush=True)
|
||||
server.serve_forever()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
{"trajectory_id": "HTTP-RF-001::buggy", "source_trajectory_id": "HTTP-RF-001", "implementation": "buggy", "task_input": {"intent": "refund", "order_id": "ORD-58-A"}, "final_status": "success", "turns": [{"index": 0, "role": "user", "content": "{\"intent\": \"refund\", \"order_id\": \"ORD-58-A\"}"}, {"index": 1, "role": "tool", "module": "http_order_system", "tool": "query_order", "method": "GET", "path": "/orders/ORD-58-A", "request": null, "http_status": 200, "status": "success", "latency_ms": 0.451, "response": {"order_id": "ORD-58-A", "status": "paid", "sku": "SKU-42"}}, {"index": 2, "role": "tool", "module": "http_order_system", "tool": "process_refund", "method": "POST", "path": "/refund/process", "request": {"order_id": "ORD-58-A"}, "http_status": 200, "status": "success", "latency_ms": 0.431, "response": {"order_id": "ORD-58-A", "refund_id": "RF-LIVE-1"}}, {"index": 3, "role": "tool", "module": "http_order_system", "tool": "notify_user", "method": "POST", "path": "/notifications", "request": {"status": "success"}, "http_status": 200, "status": "success", "latency_ms": 0.423, "response": {"sent": true, "status": "success"}}]}
|
||||
{"trajectory_id": "HTTP-INV-001::buggy", "source_trajectory_id": "HTTP-INV-001", "implementation": "buggy", "task_input": {"intent": "order_status", "order_id": "ORD-58-B", "sku": "SKU-42"}, "final_status": "failed", "turns": [{"index": 0, "role": "user", "content": "{\"intent\": \"order_status\", \"order_id\": \"ORD-58-B\", \"sku\": \"SKU-42\"}"}, {"index": 1, "role": "tool", "module": "http_order_system", "tool": "query_order", "method": "GET", "path": "/orders/ORD-58-B", "request": null, "http_status": 200, "status": "success", "latency_ms": 0.378, "response": {"order_id": "ORD-58-B", "status": "paid", "sku": "SKU-42"}}, {"index": 2, "role": "tool", "module": "http_order_system", "tool": "check_stock", "method": "GET", "path": "/inventory/SKU-42", "request": null, "http_status": null, "status": "error", "latency_ms": 352.364, "error": "TimeoutError: timed out"}, {"index": 3, "role": "tool", "module": "http_order_system", "tool": "notify_user", "method": "POST", "path": "/notifications", "request": {"status": "failed"}, "http_status": 200, "status": "success", "latency_ms": 2.174, "response": {"sent": true, "status": "failed"}}]}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
{"listening": 56305}
|
||||
{"client": "127.0.0.1", "message": "\"GET /health HTTP/1.1\" 200 -", "time": 1785360656.4696589}
|
||||
{"client": "127.0.0.1", "message": "\"GET /orders/ORD-58-A HTTP/1.1\" 200 -", "time": 1785360656.470422}
|
||||
{"client": "127.0.0.1", "message": "\"POST /refund/process HTTP/1.1\" 200 -", "time": 1785360656.470944}
|
||||
{"client": "127.0.0.1", "message": "\"POST /notifications HTTP/1.1\" 200 -", "time": 1785360656.471394}
|
||||
{"client": "127.0.0.1", "message": "\"GET /orders/ORD-58-B HTTP/1.1\" 200 -", "time": 1785360656.4718232}
|
||||
{"client": "127.0.0.1", "message": "\"POST /notifications HTTP/1.1\" 200 -", "time": 1785360656.8262029}
|
||||
{"client": "127.0.0.1", "message": "\"GET /inventory/SKU-42 HTTP/1.1\" 200 -", "time": 1785360657.274664}
|
||||
Reference in New Issue
Block a user