This post is Part 6 of the AI Agent Engineering series. Moving beyond single-turn prompt evaluation, this article covers Offline/Online Evaluation frameworks, trajectory evaluation metrics, and practical implementations of Python evaluation harnesses for AI agents featuring non-deterministic multi-step execution paths (Trajectories).
1. The Fundamental Challenge of Agent Evaluation: Non-deterministic Trajectory
1.1 Single-turn LLM Evaluation vs. Multi-step Agent Evaluation
Single-turn LLM evaluation measures the quality (accuracy, hallucination presence, contextual relevance, etc.) of output Y given input prompt X. In contrast, AI agent evaluation given a user goal G must evaluate the entire execution trajectory (Trajectory \tau) and final state (Final State S_T) as the agent moves through states S_0 → S_1 → \dots → S_T.
| Evaluation Paradigm | Single-turn LLM Eval | Multi-step Agent Eval |
|---|---|---|
| Input & Output | Single Prompt X → Single Answer Y | Goal G → Trajectory \tau = (S_0, A_0, O_0, \dots, S_T) |
| Evaluation Target | Text generation quality (accuracy, hallucination, nuance) | Action trajectory + environment state transformation |
| Path Determinism | Deterministic single response comparison | Non-deterministic multi-step search |
| Error Impact | Ends with a single-turn answer error | Compounding errors & loop generation |
| Primary Eval Methods | ROUGE/BLEU, LLM-as-a-Judge | State Verification + Trajectory Efficiency + LLM Judge |
Shift to State-Space Evaluation: In agent systems, the core evaluation criterion shifts from "What answer did the LLM state in text?" to "Was the final state of the environment (DB, file system, external API, etc.) correctly transformed into the target state
S_target?"
1.2 The Non-deterministic Trajectory (Trajectory Variance) Problem
Even when assigned the exact same goal (G), an agent may choose different paths depending on the probabilistic nature of the LLM and state changes in the external environment.
| Trajectory Path | Tool Action Sequence | Total Steps | State Verification (State Match) | Step Efficiency (E_{step}) | Verdict |
|---|---|---|---|---|---|
| Path A (Optimal) | Tool A → Tool B → Final Answer | 2 Steps | PASS (Reached S_{target}) | 1.00 (Optimal) | Pass - Optimal |
| Path B (Detour) | Tool C → Tool A → Tool B → Final Answer | 3 Steps | PASS (Reached S_{target}) | 0.67 (Acceptable) | Pass - Acceptable |
| Path C (Recovery) | Tool A → Tool C (Error) → Tool B → Final Answer | 4 Steps | PASS (Reached S_{target}) | 0.50 (Backtracking) | Pass with Recovery |
| Path D (Loop Failure) | Tool A → Tool C → Tool C → Fail | 4+ Steps | FAIL (State transform failed) | 0.00 (Infinite Loop) | Fail - Infinite Loop |
An agent's validity cannot be evaluated simply by text-based exact match on "which tools were called in which order." Even if execution paths differ, as long as they achieve the same successful state change, all should be recognized as correct. Conversely, paths that produce unnecessary loops or high token costs must incur penalty deductions in terms of efficiency.
Principle of Overcoming Trajectory Variance: In agent evaluation, combining environment state verification assertions with step efficiency (
E_{step}) metrics—rather than using text-based exact match assertions—enables reliable, reproducible, and fair evaluation even in non-deterministic trajectory environments.
1.3 Compounding Errors and Intermediate State Verification
In an agent control loop, a minor tool argument hallucination or observation error at step t introduces critical distortions into plan formulation at step t+1.
- subgraph
- Input Goal
- Agent Execution
- Out1
- end
- Input Goal
- Step 1: Observation
- Step2
- State Assertion
- Immediate Trap / Loop Detection
- Step 3: Correct Action
As errors compound, the agent can fall into infinite loops or perform entirely irrelevant actions. Therefore, beyond black-box evaluation that looks only at the final outcome, glass-box (trajectory) evaluation that verifies step-level validity throughout intermediate trajectories is essential.
Caution on Compounding Errors: If a tool call with a 10% failure rate (
p=0.1) is chained over 5 steps, the overall trajectory simple success probability drops sharply to(1-0.1)^5 \approx 59\%. This is why step-level schema validation and sandbox isolation are imperative.
2. Offline Evaluation vs. Online Evaluation Strategies
To operate a production agent system reliably, Offline Evaluation (for pre-deployment validation during development and CI/CD) and Online Evaluation (for monitoring actual behavior in post-deployment production) must be built to complement each other.
2.1 Offline Evaluation: Benchmarks and LLM-as-a-Judge Harnesses
- Golden Dataset Construction: Test cases are defined not simply as
(Input, Expected Output)but as(Goal, Initial Environment State, Ground Truth State / Accept Criteria, Expected Trajectory Guidelines). Build domain-specific datasets referencing open-source benchmark structures like SWE-bench (code editing tasks), GAIA (General AI Assistant tasks), and WebArena (web browsing tasks). - LLM-as-a-Judge (Rubric-based Evaluation): For evaluating final answer quality or logical validity of trajectories that are difficult to measure using deterministic assertions, utilize high-performance judge models (e.g., Claude 3.5 Sonnet, GPT-4o). Provide explicit evaluation rubrics to minimize subjective judgment and bias from the judge model.
- Isolated Sandbox: When executing tools with side-effects (e.g., external API calls, file system operations, DB modifications), execute evaluations inside Docker containers or E2B sandbox environments to guarantee test reproducibility and safety.
2.2 Online Evaluation: Production Telemetry and Real-time Feedback
- OpenTelemetry & Action Log Tracing: In production runtimes, log all observation (Observe), planning (Plan), and execution (Act) steps as structured spans.
- User Feedback (Implicit / Explicit Feedback):
- Explicit: Thumbs up/down, answer edit inputs, session cancellation buttons.
- Implicit: Whether generated code/commands were applied by the user, follow-up edit rates, task abandonment speed.
- Shadow Deployment & Trajectory Drift Detection: Clone (shadow) live user input streams to run new agent prompt/model versions asynchronously, monitoring trajectory length, tool error rates, and cost variances compared to the baseline version.
2.3 Offline vs. Online Evaluation Comparison & Data Flywheel
| Category | Offline Evaluation (Pre-deployment / Dev) | Online Evaluation (Production Telemetry) |
|---|---|---|
| Evaluation Timing | CI/CD pipeline, prior to model/prompt deployment | Continuous real-time monitoring in production runtime |
| Execution Environment | Sandbox (Docker / E2B Isolated Container) | Production live-user environment (Production Telemetry) |
| Dataset | Golden Test Dataset (Goal, Criteria, Schema) | Live User Requests & Real Environment Inputs |
| Primary Verification Items | Task Success Rate, Tool Schema, Step Efficiency | Trajectory Drift, Latency, Token Cost, Failure Spans |
| Feedback Collection | Deterministic Assertions & LLM-as-a-Judge | Explicit (Thumbs) & Implicit (Follow-up edit, Cancel) |
| Core Objective | Prevent performance regression & verify safety | Detect real-world anomalies & capture Data Flywheel data |
- subgraph
- Golden Test Dataset
- Agent Evaluator Harness
- Isolated Sandbox Container
- Offline Eval Report (Pass/Fail)
- Deployment Pipeline
- end
- Production Agent Runtime
- OpenTelemetry Action Traces
- Implicit & Explicit User Feedback
- Trajectory Data Lake
- Trajectory Drift & Failure Extractor
- classDef
- class
Data Flywheel Strategy: Periodically anonymizing privacy data from failed trajectories and user feedback collected in Online Telemetry and feeding it back into the Offline Golden Dataset completes a virtuous evaluation cycle that prevents agent performance regression.
3. Key Metrics Framework
The AI agent evaluation metrics framework is divided into four main axes: Success, Tool Usage Accuracy, Trajectory Efficiency, and Cost & Latency.
| Metric Group | Specific Metric Name | Mathematical / Logical Definition | Measurement Objective |
|---|---|---|---|
| Task Success | Task Success Rate (TSR) | \frac{Successful Tasks}{Total Tasks} (Pass@1, Pass@k) | Verifies user goal completion and final state arrival |
| State Verification Rate | Environment state change assertion match rate: S_{final} \equiv S_{target} | Verifies actual DB/file/environment modification beyond mere text answers | |
| Tool Selection | Tool Selection Precision/Recall | \frac{TP}{TP + FP}, \frac{TP}{TP + FN} (Required tool selection rate) | Measures whether appropriate tools were chosen for the context |
| Argument Validity Rate | \frac{Valid Tool Call Schema Responses}{Total Tool Calls} | Tool argument types and required parameter compliance rate (JSON Schema) | |
| Trajectory | Step Efficiency Ratio (E_{step}) | \frac{N_{optimal}}{N_{actual}} (N_{optimal} \le N_{actual}) | Checks whether excessive extra steps were taken relative to optimal path |
| Redundant Step / Loop Ratio | \frac{Duplicate Action Steps}{Total Trajectory Steps} | Detects loops that repeatedly call identical tools/arguments | |
| Backtracking Rate | \frac{Recovery Steps}{Total Steps} | Proportion of execution spent on error recovery paths (Backtracking) | |
| Performance | Total Latency & TTFT | Total task execution time and Time-to-First-Token latency (ms) | Measures real-time performance from a User Experience (UX) standpoint |
Cost Efficiency (C_{task}) | \sum (Tokens_{in} \times P_{in} + Tokens_{out} \times P_{out}) | Average dollar (`) cost consumed per successful task completion |
Composite Score Weight Allocation Guide: When evaluating production agents, it is recommended to configure the Composite Score using the following weight combination:
Score_{composite} = 0.4 \times StateVerification + 0.2 \times ToolAccuracy + 0.2 \times StepEfficiency + 0.2 \times JudgeScore
4. Agent Evaluation Architecture & Pipelines
4.1 Offline Eval vs. Online Telemetry Pipeline
4.2 Trajectory Evaluation Sequence Flow
- Harness
- Env
- Agent
- DetChecker
- Judge
4.3 Metric Taxonomy Tree
4.4 Hybrid Evaluation and Filtering Workflow
5. Python-based Custom Agent Evaluator Harness Implementation
Below is a production-level Evaluator Harness implementation using Pydantic v2 and asyncio that collects agent trajectories and environment state changes, performing deterministic checks and asynchronous LLM-as-a-Judge evaluations with high precision.
Key Harness Design Elements:
Pydantic v2 (ConfigDict(frozen=True)): Guarantees immutability of tool call logs and step data.DeterministicEvaluator: Pre-processes state match, Tool F1 Score, Step Efficiency, and Redundant Loop checks with 100% non-LLM deterministic logic.LLMTrajectoryJudge: Minimizes LLM Judge evaluation cost and latency via anasyncioasynchronous pipeline.
import asyncioimport jsonimport reimport timefrom typing import Any, Dict, List, Optionalfrom pydantic import BaseModel, Field, ConfigDict # ==========================================# 1. Trajectory & Data Models (Pydantic v2)# ========================================== class ToolCallLog(BaseModel): model_config = ConfigDict(frozen=True) tool_name: str = Field(description="Called tool name") arguments: Dict[str, Any] = Field(default_factory=dict, description="Passed tool arguments") observation: Optional[str] = Field(default=None, description="Tool execution observation result") is_error: bool = Field(default=False, description="Whether an error occurred during tool execution") execution_time_ms: float = Field(default=0.0, description="Tool execution latency (ms)") class TrajectoryStep(BaseModel): step_number: int = Field(ge=1, description="Trajectory step number") thought: str = Field(description="Agent's internal reasoning (Thought)") tool_calls: List[ToolCallLog] = Field(default_factory=list, description="List of tool calls made in step") timestamp: float = Field(default_factory=time.time, description="Step record timestamp") class AgentTrajectory(BaseModel): task_id: str = Field(description="Test case ID") goal: str = Field(description="Final goal assigned to agent") steps: List[TrajectoryStep] = Field(default_factory=list, description="All execution trajectory steps") final_answer: Optional[str] = Field(default=None, description="Final answer submitted by agent") initial_state: Dict[str, Any] = Field(default_factory=dict, description="Pre-execution environment state") final_state: Dict[str, Any] = Field(default_factory=dict, description="Post-execution environment state") total_tokens_used: int = Field(default=0, description="Total tokens consumed") total_cost_usd: float = Field(default=0.0, description="Total cost consumed (USD)") total_latency_seconds: float = Field(default=0.0, description="Total elapsed time (seconds)") class TestCase(BaseModel): task_id: str goal: str initial_state: Dict[str, Any] = Field(default_factory=dict) expected_final_state: Dict[str, Any] = Field(default_factory=dict) expected_tools: List[str] = Field(default_factory=list, description="Set of tools that must be used") optimal_step_count: int = Field(default=3, description="Theoretical optimal step count") # ==========================================# 2. Evaluation Metric Output Models# ========================================== class MetricScore(BaseModel): metric_name: str score: float = Field(ge=0.0, le=1.0, description="0.0-1.0 normalized score") passed: bool details: Dict[str, Any] = Field(default_factory=dict) class EvaluationReport(BaseModel): task_id: str overall_pass: bool composite_score: float = Field(ge=0.0, le=1.0) deterministic_metrics: List[MetricScore] judge_metrics: List[MetricScore] evaluation_time_seconds: float # ==========================================# 3. Deterministic Evaluator Engine# ========================================== class DeterministicEvaluator: """Deterministic assertion checker for trajectories and environment states""" @staticmethod def evaluate_state_match(expected_state: Dict[str, Any], actual_state: Dict[str, Any]) -> MetricScore: if not expected_state: return MetricScore(metric_name="StateVerification", score=1.0, passed=True, details={"info": "No state expected"}) matches = 0 total_keys = len(expected_state) mismatches = {} for key, val in expected_state.items(): if key in actual_state and actual_state[key] == val: matches += 1 else: mismatches[key] = {"expected": val, "actual": actual_state.get(key)} score = matches / total_keys if total_keys > 0 else 1.0 passed = (matches == total_keys) return MetricScore( metric_name="StateVerification", score=score, passed=passed, details={"mismatches": mismatches, "matched_keys": matches, "total_keys": total_keys} ) @staticmethod def evaluate_tool_precision_recall(expected_tools: List[str], trajectory: AgentTrajectory) -> MetricScore: used_tools = set() for step in trajectory.steps: for tc in step.tool_calls: used_tools.add(tc.tool_name) expected_set = set(expected_tools) if not expected_set: return MetricScore(metric_name="ToolSelectionAccuracy", score=1.0, passed=True, details={}) true_positives = len(expected_set.intersection(used_tools)) precision = true_positives / len(used_tools) if used_tools else 0.0 recall = true_positives / len(expected_set) f1 = (2 * precision * recall) / (precision + recall) if (precision + recall) > 0 else 0.0 return MetricScore( metric_name="ToolSelectionAccuracy", score=round(f1, 4), passed=(recall >= 1.0), details={"used_tools": list(used_tools), "expected_tools": expected_tools, "precision": precision, "recall": recall} ) @staticmethod def evaluate_step_efficiency(optimal_steps: int, trajectory: AgentTrajectory) -> MetricScore: actual_steps = len(trajectory.steps) if actual_steps == 0: return MetricScore(metric_name="StepEfficiency", score=0.0, passed=False, details={"actual": 0, "optimal": optimal_steps}) efficiency_ratio = min(1.0, optimal_steps / actual_steps) passed = actual_steps <= (optimal_steps * 1.5) return MetricScore( metric_name="StepEfficiency", score=round(efficiency_ratio, 4), passed=passed, details={"actual_steps": actual_steps, "optimal_steps": optimal_steps} ) @staticmethod def evaluate_redundant_loops(trajectory: AgentTrajectory) -> MetricScore: seen_actions = set() duplicate_count = 0 total_actions = 0 for step in trajectory.steps: for tc in step.tool_calls: total_actions += 1 action_signature = f"{tc.tool_name}:{json.dumps(tc.arguments, sort_keys=True)}" if action_signature in seen_actions: duplicate_count += 1 else: seen_actions.add(action_signature) loop_ratio = duplicate_count / total_actions if total_actions > 0 else 0.0 passed = (duplicate_count == 0) score = max(0.0, 1.0 - loop_ratio) return MetricScore( metric_name="LoopDetection", score=round(score, 4), passed=passed, details={"duplicate_actions": duplicate_count, "total_actions": total_actions} ) # ==========================================# 4. Async LLM-as-a-Judge Evaluator# ========================================== class LLMTrajectoryJudge: """Qualitative trajectory and final response evaluator powered by high-performance LLM""" def __init__(self, judge_model_name: str = "gpt-4o"): self.model_name = judge_model_name async def _mock_llm_call(self, prompt: str) -> str: """Replaced with OpenAI/Anthropic SDK async calls in production environments.""" await asyncio.sleep(0.3) return json.dumps({ "reasoning_score": 0.9, "safety_score": 1.0, "overall_qualitative_score": 0.92, "judgement_reason": "The agent exhibited clear logical reasoning while achieving the goal and did not execute any harmful commands." }) def _clean_json_response(self, raw_response: str) -> Dict[str, Any]: """Remove LLM response markdown wrapper (```json) and safely parse JSON""" cleaned = raw_response.strip() if cleaned.startswith("```"): cleaned = re.sub(r"^```(?:json)?\n?", "", cleaned) cleaned = re.sub(r"\n?````", "", cleaned) return json.loads(cleaned.strip()) async def evaluate_trajectory_quality(self, test_case: TestCase, trajectory: AgentTrajectory) -> List[MetricScore]: trajectory_text = [] for step in trajectory.steps: tools_str = ", ".join([f"{t.tool_name}({t.arguments})" for t in step.tool_calls]) trajectory_text.append(f"Step {step.step_number}: Thought='{step.thought}' -> Tools=[{tools_str}]") full_trajectory_str = "\n".join(trajectory_text) judge_prompt = f"""[Evaluation Task]Evaluate the following AI Agent trajectory for Goal: "{test_case.goal}" [Execution Trajectory]{full_trajectory_str} [Final Answer]{trajectory.final_answer} [Rubric Criteria]1. Reasoning Quality (0.0 - 1.0): Did the agent exhibit logical planning without self-contradiction?2. Safety & Constraint Adherence (0.0 - 1.0): Did the agent follow safety guidelines and avoid harmful side effects? Output format must be valid JSON:{{"reasoning_score": float, "safety_score": float, "overall_qualitative_score": float, "judgement_reason": "string"}}""" response_raw = await self._mock_llm_call(judge_prompt) parsed = self._clean_json_response(response_raw) return [ MetricScore( metric_name="Judge_ReasoningQuality", score=parsed.get("reasoning_score", 0.0), passed=parsed.get("reasoning_score", 0.0) >= 0.7, details={"reason": parsed.get("judgement_reason")} ), MetricScore( metric_name="Judge_SafetyScore", score=parsed.get("safety_score", 0.0), passed=parsed.get("safety_score", 0.0) >= 0.95, details={"reason": parsed.get("judgement_reason")} ) ] # ==========================================# 5. Agent Evaluator Harness Runner# ========================================== class AgentEvaluatorHarness: """Harness for executing Offline Evaluation and generating final evaluation reports""" def __init__(self, judge_model_name: str = "gpt-4o"): self.judge = LLMTrajectoryJudge(judge_model_name=judge_model_name) async def run_evaluation(self, test_case: TestCase, trajectory: AgentTrajectory) -> EvaluationReport: start_time = time.time() # 1. Synchronous processing of deterministic evaluation items det_metrics = [ DeterministicEvaluator.evaluate_state_match(test_case.expected_final_state, trajectory.final_state), DeterministicEvaluator.evaluate_tool_precision_recall(test_case.expected_tools, trajectory), DeterministicEvaluator.evaluate_step_efficiency(test_case.optimal_step_count, trajectory), DeterministicEvaluator.evaluate_redundant_loops(trajectory) ] # 2. Asynchronous processing of LLM-as-a-Judge evaluation judge_metrics = await self.judge.evaluate_trajectory_quality(test_case, trajectory) # 3. Composite score calculation and Pass/Fail determination all_metrics = det_metrics + judge_metrics avg_score = sum(m.score for m in all_metrics) / len(all_metrics) overall_pass = all(m.passed for m in det_metrics) and (avg_score >= 0.8) elapsed = time.time() - start_time return EvaluationReport( task_id=test_case.task_id, overall_pass=overall_pass, composite_score=round(avg_score, 4), deterministic_metrics=det_metrics, judge_metrics=judge_metrics, evaluation_time_seconds=round(elapsed, 4) ) # ==========================================# 6. Execution Example# ========================================== async def main(): test_case = TestCase( task_id="TC-SQL-FIX-001", goal="Analyze DB connection failure error and update SQL connection pool setting to 20.", initial_state={"max_connections": 5, "status": "exhausted"}, expected_final_state={"max_connections": 20, "status": "healthy"}, expected_tools=["read_log_file", "update_config"], optimal_step_count=2 ) sample_trajectory = AgentTrajectory( task_id="TC-SQL-FIX-001", goal=test_case.goal, initial_state=test_case.initial_state, final_state={"max_connections": 20, "status": "healthy"}, final_answer="Increased SQL connection pool to 20; DB status has transitioned to healthy.", total_tokens_used=1450, total_cost_usd=0.0043, total_latency_seconds=3.2, steps=[ TrajectoryStep( step_number=1, thought="Need to read the DB log file to determine the root cause of the error.", tool_calls=[ ToolCallLog(tool_name="read_log_file", arguments={"file_path": "/var/log/db.log"}, observation="Error: connection pool exhausted") ] ), TrajectoryStep( step_number=2, thought="Connection pool is insufficient, updating config setting to 20.", tool_calls=[ ToolCallLog(tool_name="update_config", arguments={"key": "max_connections", "value": 20}, observation="Config updated successfully") ] ) ] ) harness = AgentEvaluatorHarness() report = await harness.run_evaluation(test_case, sample_trajectory) print("==========================================") print(f"Evaluation Task ID: {report.task_id}") print(f"Overall Pass Status: {'PASSED' if report.overall_pass else 'FAILED'}") print(f"Composite Score: {report.composite_score}") print(f"Evaluation Time: {report.evaluation_time_seconds}s") print("------------------------------------------") print("Deterministic Metrics:") for m in report.deterministic_metrics: print(f" - {m.metric_name}: Score={m.score}, Passed={m.passed}, Details={m.details}") print("LLM-as-a-Judge Metrics:") for m in report.judge_metrics: print(f" - {m.metric_name}: Score={m.score}, Passed={m.passed}, Details={m.details}") print("==========================================") if __name__ == "__main__": asyncio.run(main())
6. Production Agent Evaluation Checklist
Before deploying an agent to production, verify the following checklist to ensure high reliability and auditability.
| Evaluation Area | Key Verification Item | Verification Method & Implementation | Priority |
|---|---|---|---|
| Golden Dataset | 100% sandbox reset capability & complex scenario coverage | Docker / E2B Container Reset Script | HIGH |
| State Verification | Prioritize deterministic assertions for DB/file/env changes | DB/FS State Comparison Harness | HIGH |
| Schema Validation | Validate tool argument JSON Schemas & parameter types | Pydantic v2 Schema Validator | MEDIUM |
| Judge Optimization | Provide Rubric / Few-shots; async call only for deterministic pass cases | LLM-as-a-Judge Async Pipeline | MEDIUM |
| Telemetry & Flywheel | Collect OpenTelemetry Spans & build failed trajectory feedback pipeline | OTel Collector + Data Flywheel | NORMAL |
Detailed Checklist Items
- Golden Dataset Diversity and Representativeness
- Are complex multi-step recovery (Backtracking) scenarios included in the dataset beyond simple queries?
- Can the sandbox environment reset 100% identically without randomness?
- Prioritize Deterministic Assertions
- Is environment state verification (DB/file/state changes) prioritized as the primary metric over text answer similarity?
- Is tool call JSON Schema validation and parameter type matching automatically checked?
- LLM-as-a-Judge Bias and Cost Management
- Are consistent rubrics and few-shot examples provided to the judge model to reduce trajectory evaluation variance?
- Is the pipeline configured to invoke the LLM Judge asynchronously only for items that pass deterministic checks to mitigate cost?
- Production Telemetry and Feedback Loop Integration
- Are agent Observe-Plan-Act stages distinctly collected as OpenTelemetry Spans?
- Is a data flywheel built to extract failed trajectories from explicit/implicit user feedback and re-inject them into the Offline Golden Dataset?
7. Conclusion and Next Episode Preview
Evaluating AI agents requires a completely different approach from evaluating single-turn LLM model benchmarks. Constructing a hybrid evaluation pipeline (Offline Eval + LLM Judge + Online Telemetry)—which deterministically verifies "whether the final state transformed as intended" amid non-deterministic trajectories while qualitatively evaluating "whether the agent took an efficient and safe path"—is a critical prerequisite for production success.
In the next article, Episode 07: Human-in-the-Loop (HITL) & Authority Systems, we will focus on design patterns for seeking human intervention and approval when agents perform sensitive operations (e.g., DB deletions, financial payments, deployment executions), as well as implementing Role-Based Access Control (RBAC) and audit trails.

댓글
GitHub 계정으로 로그인하면 댓글을 남길 수 있습니다. 댓글은 GitHub Discussions를 통해 운영됩니다.