Replies: 2 comments 1 reply
|
Thanks for writing this up. The Retry scope and compatibility. §3.2 says existing retry names are retained for compatibility, but the proposed scope appears to move from MCP Server identity. §4.5 adds Latency aggregation. §3.1 says consumers can aggregate across the Action scope to view resource-wide health. That works for counters, but latency histograms/percentiles generally do not compose across per-Action series. Is Gauge recovery semantics. §6 says Gauges may be reconstructed from restored runtime state when the state identifies pending or active work. Could we spell out which gauges are actually reconstructable after failover? Tool success/failure parity. §5.4 says a Tool error response is counted as a failed Tool execution, and §7 makes Java/Python outcome alignment part of the contract. Could we define whether Tool success/failure is a framework-level contract or a best-effort interpretation of the Tool return value? Java has |
|
Thanks for raising these points. I agree that these contracts should be made more explicit. Retry scope and compatibility. The move from MCP Server identity. The Part 1 prototype already propagates this identity in both Java and Python. When an MCP Server declared in the AgentPlan is expanded into Tool resources, each discovered MCP Tool retains the declared server resource name. At execution time, the Tool exposes that name through the common Tool execution metadata contract, and the metrics recorder uses it as the Latency aggregation. Agreed. The current latency histograms are scoped to an Action and resource, so their exported percentiles should not be treated as generally composable across Actions. The resource-wide aggregation statement applies to counters such as call successes and failures, not to latency percentiles. The proposal now clarifies that Gauge recovery semantics. In the prototype, all four proposed Gauges are reconstructed from restored runtime state. Active input runs come from the restored processing-key state, pending input Events from the pending-Event state, pending Action tasks from the restored ActionTask queues, and active Action executions from restored tasks whose execution-start marker is set. These Gauges are reconstructed from checkpointed state rather than reset or treated as best-effort after failover. The proposal now spells out these state sources. Tool success/failure parity. Tool outcome is a framework-level contract rather than an interpretation of arbitrary return payloads. A normal return is successful; an exception or a framework-recognized error result is failed. Java |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
This proposal is the second in a two-part Flink Agents observability series:
Part 1 defines the per-run recording needed to reconstruct an Agent Trace. This proposal defines bounded-cardinality metrics for observing aggregate health and behavior across runs.
The two capabilities share runtime observation boundaries but produce independent outputs:
1. Context and Relationship to Part 1
Flink already provides job, operator, checkpoint, backpressure, and resource metrics. These metrics describe the Flink execution layer, but they do not directly answer Agent-specific operational questions:
Part 1 proposes two runtime Event categories for per-run observation:
Those Events also provide natural boundaries for aggregate metrics. Trace logging and metric aggregation can consume the same Execution Events independently, so Action, LLM, and Tool metrics follow the lifecycle semantics recorded in each trace.
Execution Events cover only work represented as executions. Queue depth,
ActionTaskscheduling, token usage, and retry statistics instead arise from runtime state or call results and are recorded at their own boundaries. The complete signal model is therefore:flowchart LR BE["Business Event"] --> TRACE["Event Log<br/>per-run Agent Trace"] BE --> EVENT_METRICS["Event-driven metrics<br/>Business Event / Action / LLM / Tool"] EE["Execution Event"] --> TRACE EE --> EVENT_METRICS RUN_STATE["Run and queue state"] --> RUN_METRICS["Input Run and scheduling metrics"] MODEL_RESULT["Model call result"] --> MODEL_METRICS["Token usage and retry metrics"]This model aligns Agent Trace and execution metrics on lifecycle, entity, outcome, and metadata semantics while keeping the two outputs independent.
2. Goals and Non-goals
Goals
Non-goals
3. Metric Model
3.1 Scope Hierarchy
The Agent name identifies the Flink operator that runs the Agent. Agent-specific dimensions are registered as key-value
MetricGroupscopes. Metric reporters that support dimensions, such as Prometheus, can expose these scopes as labels; other reporters may encode them in the metric identifier.load_skillTool callmodel_resourceandmodelbelong to independent branches:When one resource is shared by multiple Actions, each Action produces a separate raw metric series. Consumers can retain the Action scope to locate the caller. Counters such as call successes and failures can also be summed across Actions to view resource-wide outcomes. Latency Histograms remain per-Action distributions; their exported percentiles are not generally composable across Action series, so this proposal does not define a resource-wide latency percentile.
3.2 Metric Types and Naming
The proposal uses standard Flink metric types:
Metric names follow the existing Flink Agents style:
numOf.......PerSec....LatencyMs.modelscope tomodel_resource. This is a breaking scope change; compatibility is limited to the metric names.model_resourceandmcp_server.3.3 Cardinality
Operational metrics intentionally exclude per-run and per-execution identifiers. Fields such as
input_run_id,execution_id,business_key, andevent_idare useful for Agent Trace queries but would create unbounded metric cardinality.Metric scopes are limited to reusable Agent entities and resources: Action, Model Resource, model name, Tool, Skill, and MCP Server. Metrics identify where aggregate behavior is concentrated; Agent Trace remains the per-run diagnostic surface.
4. Built-in Metrics
The existing Event throughput, Action throughput, and token metrics remain part of the built-in metric surface. This proposal adds Input Run, Action scheduling, and execution-entity health metrics while preserving existing names and semantics.
4.1 Existing Baseline
numOfEventProcessednumOfEventProcessedPerSecnumOfActionsExecutednumOfActionsExecutedPerSecnumOfActionsExecutednumOfActionsExecutedPerSeceventLogTruncatedEventspromptTokenscompletionTokenstotalTokens4.2 Input Run
An Input Run is one attempt to process an input for a business key. Metric tracking begins when the runtime receives the Input Event. The run's processing phase begins later, when that Event leaves the pending queue. Tracking ends when all associated Actions complete or an unhandled exception terminates the run.
numOfInputRunsSucceedednumOfInputRunsFailedinputRunLatencyMsinputRunQueueLatencyMsinputRunProcessingLatencyMsnumOfPendingInputEventsnumOfActiveInputRunsThe latency boundaries are:
Here, processing starts when the Input Event leaves the pending queue and enters Event routing. It does not imply that the first Action has already begun executing.
A child execution failure does not by itself make the Input Run fail. If the Agent handles the failure and reaches its normal completion boundary, the run is successful.
4.3 Action
Action metrics distinguish between a physical
ActionTaskand a logical Action execution. One logical execution may suspend while waiting for asynchronous work and later resume through anotherActionTask.actionSchedulingLatencyMsActionTaskenqueue to its first executionactionExecutionLatencyMsstartedtofinishedorfailed, including asynchronous waitingnumOfPendingActionTasksActionTaskinstances waiting for execution, including continuationsnumOfActiveActionExecutionsOnly the initial
ActionTaskcontributes a scheduling-latency sample. A continuation updates the pending-task Gauge but does not create another scheduling sample.4.4 LLM and Token Usage
LLM health and framework retry metrics use the configured ChatModel setup resource scope. The
model_resourcevalue is the AgentPlan resource name used to resolve aCHAT_MODELresource; it is not the underlying ChatModel connection name or the model name returned by the provider. Each LLM health sample represents one framework-observed model invocation. A framework retry that calls the model again produces another sample; provider-internal attempts remain outside this metric boundary.numOfLlmCallsSucceedednumOfLlmCallsFailedllmCallLatencyMsretryCountretryWaitSecpromptTokenscompletionTokenstotalTokensThe underlying connection or provider SDK may perform its own transport retries. Those attempts are a separate connection-level signal and are not included in
retryCountorretryWaitSec.Structured-output parsing is a separate execution in Agent Trace. If a model invocation succeeds but parsing fails, that LLM execution remains successful and the Parser execution fails. If framework retry logic calls the model again, the new invocation contributes another LLM outcome and latency sample, while
retryCountandretryWaitSecdescribe the retry behavior around those invocations.4.5 Tool, Skill, and MCP Server
Each Tool call is one Tool execution. Skill and MCP Server metrics are additional aggregate projections derived from explicit Tool execution metadata; they do not introduce separate execution levels.
The
mcp_serverscope uses the MCP Server resource name declared in the AgentPlan. When the plan expands an MCP Server into Tool resources, it attaches that name to each discovered MCP Tool. At execution time, the Tool exposes the name through the shared Tool execution metadata contract, and both Java and Python use the same metadata key. The runtime emits MCP Server metrics only when this declared identity is present; it does not infer the identity from an endpoint.numOfToolCallsSucceedednumOfToolCallsFailedtoolCallLatencyMsnumOfSkillLoadsload_skillcalls that reached a terminal stateskillLoadLatencyMsload_skillcall latencynumOfMcpToolCallsSucceedednumOfMcpToolCallsFailedmcpToolCallLatencyMsEvery named Tool execution contributes to Tool metrics. Only an explicit
load_skillTool execution contributes to Skill metrics. The runtime does not infer that subsequent Tool calls belong to the loaded Skill. A Tool execution carrying MCP Server metadata contributes to both its Tool and MCP Server scopes.5. Recording Semantics
5.1 Event-Driven Metrics
Metrics derived from Business Events and Execution Events use the same semantic boundaries as Agent Trace:
execution_idmay be used internally to pairstartedand terminal Events, but it is never exposed as a metric scope or label.Metric aggregation consumes these in-process Events directly rather than reading them back from the Event Log.
5.2 Runtime State Metrics
Input Run and scheduling metrics require state transitions that are not fully represented by Execution Events:
ActionTaskenqueue and dequeue define scheduling latency and pending-task counts.These observations extend the metric model without turning queue operations into public Event types.
5.3 Model Call Metrics
Token usage and retry information are available only at the model-call boundary:
These values complement the LLM Execution Event without expanding its lifecycle schema with provider-specific payloads.
5.4 Outcome Boundaries
Tool outcome is a framework-level contract rather than an interpretation of arbitrary return payloads. A normal return is successful. An exception or a framework-recognized error result is failed. Java and Python normalize their language-specific Tool results to these outcomes before recording the Tool Execution Event; the runtime does not inspect an arbitrary raw value to guess whether it represents an error.
6. Task Attempt and Recovery Semantics
Flink metrics are scoped to the current task attempt. Counter, Meter, and Histogram values are not restored from checkpoints and do not provide exactly-once values across failures.
The prototype reconstructs all four current-value Gauges from checkpointed operator state before processing resumes:
numOfActiveInputRunsnumOfPendingInputEventsnumOfPendingActionTasksnumOfActiveActionExecutionsThese Gauges are rebuilt rather than reset or approximated after failover. They represent the restored checkpoint state and then change as replayed or newly received work is processed. Historical start timestamps cannot be reconstructed:
Consumers must aggregate Gauge values across subtasks for a job-level view. Histograms include only samples observed by the current task attempts.
7. Cross-Language and Reporter Semantics
Java and Python use the same logical execution entity types, lifecycle outcomes, metadata keys, metric names, and scope hierarchy. This alignment is part of the metric contract, even though the two runtimes observe LLM and Tool calls at different language-specific boundaries.
MetricGroupscopes are the framework-level representation of dimensions. A reporter may expose them as labels or encode them in a metric identifier, but this does not change their logical meaning. Dashboards and queries must preserve or deliberately aggregate scopes rather than assume identical physical names across reporters.8. Prototype Status
The metric model has been prototyped in both the Java and Python runtime paths. The prototype covers:
The purpose of this discussion is to review the metric contracts and their relationship to Agent Trace before submitting the implementation upstream.
9. Summary
Agent Trace and operational metrics answer different questions but share the same runtime semantics. Business Events and Execution Events provide stable observation boundaries for Event throughput and execution health. Run state, queue state, and model-call results provide the additional signals required by metrics.
This proposal adds:
The result is a bounded-cardinality operational metric surface that complements per-run Agent Trace without depending on Event Log storage or introducing per-run identifiers into metrics.
All reactions