11# agentchat_behavioral_monitor
22
3- Detect vocabulary and topic drift in long AutoGen conversations .
3+ Detect vocabulary drift across repeated AgentChat runs .
44
5- When an AutoGen conversation runs long enough to trigger history summarization
6- or truncation, earlier task context can vanish without any visible signal. The
7- agent keeps responding, but its answers may silently ignore facts it established
8- in earlier turns — different tool choices, forgotten constraints, missing domain
9- vocabulary.
5+ When a long-running agent shifts away from earlier task vocabulary, the failure
6+ often shows up first as a change in outputs rather than an explicit error. This
7+ sample shows how to watch for that drift on the public AgentChat surface.
108
11- This sample shows how to detect that drift using ** Ghost Consistency Score
12- (CCS)** : the fraction of vocabulary from the earliest turns still present in
13- the most recent turns. A score below 0.40 indicates likely behavioral drift.
9+ The demo is deterministic: it uses ` ReplayChatCompletionClient ` together with a
10+ real ` AssistantAgent ` , then monitors the resulting ` TaskResult.messages `
11+ history. In production, replace the replay model with a real model client and
12+ keep the same monitor.
13+
14+ This sample detects drift using ** Ghost Consistency Score (CCS)** : the fraction
15+ of vocabulary from the earliest runs still present in the most recent runs. A
16+ score below 0.40 indicates likely behavioral drift.
1417
1518## How it works
1619
@@ -20,7 +23,8 @@ Current window = last 25% of conversation turns
2023CCS = |vocab(baseline) ∩ vocab(current)| / |vocab(baseline)|
2124```
2225
23- A "ghost term" is a task-relevant word (jwt, bcrypt, foreign_key, redis, etc.)
26+ A "ghost term" is a task-relevant word (` jwt ` , ` bcrypt ` , ` foreign_key ` ,
27+ ` redis ` , etc.)
2428that appeared in the baseline window but has disappeared from the current
2529window. Ghost terms are the most direct signal of forgotten context.
2630
@@ -33,38 +37,49 @@ python main.py
3337Expected output:
3438
3539```
36- === AutoGen Behavioral Monitor demo ===
37- Turn : 8
38- CCS : 0.333 (1.0 = no drift, <0.4 = significant drift)
39- Ghost terms : ['bcrypt', 'foreign_key', 'redis', 'jwt']
40- Unretrieved : True
41- Drift detected: True
40+ === AutoGen AgentChat behavioral monitor demo ===
41+
42+ Turn 1
43+ CCS: 1.0
44+ Ghost terms: []
45+ Drift detected: False
4246
43- Interpretation: the agent has drifted from its early task vocabulary.
44- If ghost terms include task-critical facts, consider re-injecting context
45- or prompting the agent to recall those items from its memory store.
47+ Turn 3
48+ CCS: 0.25
49+ Ghost terms: ['bcrypt', 'foreign_key', 'jwt', 'redis']
50+ Drift detected: True
4651```
4752
4853## Integrating into your agent loop
4954
5055``` python
56+ from autogen_agentchat.agents import AssistantAgent
57+ from autogen_ext.models.replay import ReplayChatCompletionClient
5158from main import BehavioralMonitor
5259
5360monitor = BehavioralMonitor(
5461 ccs_threshold = 0.40 ,
55- min_messages = 6 ,
62+ min_messages = 3 ,
5663)
5764
5865history = []
66+ agent = AssistantAgent(
67+ " assistant" ,
68+ model_client = ReplayChatCompletionClient([
69+ " Use jwt and bcrypt for auth." ,
70+ " Keep jwt auth intact for the profile endpoint." ,
71+ " Add endpoint rate limiting." ,
72+ ]),
73+ )
5974
6075# Check after each public AgentChat run
61- task_result = await assistant_agent .run(task = " Use jwt and bcrypt for auth" )
76+ task_result = await agent .run(task = " Use jwt and bcrypt for auth" , output_task_messages = False )
6277result = monitor.observe_result(history, task_result)
6378if result[" drift_detected" ]:
6479 print (" Drift at turn" , result[" turn" ], " ghost:" , result[" ghost_terms" ])
6580
6681# Later runs keep extending the same external history
67- task_result = await assistant_agent .run(task = " Now add a profile endpoint" )
82+ task_result = await agent .run(task = " Now add a profile endpoint" , output_task_messages = False )
6883result = monitor.observe_result(history, task_result)
6984```
7085
@@ -73,15 +88,15 @@ result = monitor.observe_result(history, task_result)
7388| Parameter | Default | Description |
7489| ---| ---| ---|
7590| ` ccs_threshold ` | 0.40 | Flag drift when CCS drops below this value |
76- | ` min_messages ` | 6 | Minimum conversation length before checks run |
91+ | ` min_messages ` | 3 | Minimum number of tracked AgentChat results before checks run |
7792| ` ghost_lexicon ` | built-in list | Domain terms to watch for disappearance |
7893
7994## Connection to AutoGen issue #7265
8095
8196This sample addresses the production reliability pattern discussed in
8297https://github.com/microsoft/autogen/issues/7265 — specifically the
83- ghost-lexicon + behavioral footprint pattern for detecting when long-running
84- agents silently lose task context to compression .
98+ ghost-lexicon pattern for detecting when long-running agent outputs silently
99+ drift away from earlier task vocabulary .
85100
86101## Related
87102
0 commit comments