Skip to content

Commit 59daf78

Browse files
Hk669sonichi
andauthored
Made the cost info easier to read (#2356)
* gather_usage_summary has been updated * updated cost info to 'usage_including_cached_inference' and 'usage_excluding_cached_inference' * fix: pre-commit formatting for cost_info * improved cost explanation and doc * improved cost info doc * include - exclude --------- Co-authored-by: Chi Wang <[email protected]>
1 parent 9088390 commit 59daf78

9 files changed

+57
-38
lines changed

autogen/agentchat/chat.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,12 @@ class ChatResult:
2525
"""The chat history."""
2626
summary: str = None
2727
"""A summary obtained from the chat."""
28-
cost: tuple = None # (dict, dict) - (total_cost, actual_cost_with_cache)
29-
"""The cost of the chat. a tuple of (total_cost, total_actual_cost), where total_cost is a
30-
dictionary of cost information, and total_actual_cost is a dictionary of information on
31-
the actual incurred cost with cache."""
28+
cost: Dict[str, dict] = None # keys: "usage_including_cached_inference", "usage_excluding_cached_inference"
29+
"""The cost of the chat.
30+
The value for each usage type is a dictionary containing cost information for that specific type.
31+
- "usage_including_cached_inference": Cost information on the total usage, including the tokens in cached inference.
32+
- "usage_excluding_cached_inference": Cost information on the usage of tokens, excluding the tokens in cache. No larger than "usage_including_cached_inference".
33+
"""
3234
human_input: List[str] = None
3335
"""A list of human input solicited during the chat."""
3436

autogen/agentchat/utils.py

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import re
2-
from typing import Any, Callable, Dict, List, Tuple, Union
2+
from typing import Any, Callable, Dict, List, Union
33

44
from .agent import Agent
55

@@ -26,33 +26,46 @@ def consolidate_chat_info(chat_info, uniform_sender=None) -> None:
2626
), "llm client must be set in either the recipient or sender when summary_method is reflection_with_llm."
2727

2828

29-
def gather_usage_summary(agents: List[Agent]) -> Tuple[Dict[str, any], Dict[str, any]]:
29+
def gather_usage_summary(agents: List[Agent]) -> Dict[Dict[str, Dict], Dict[str, Dict]]:
3030
r"""Gather usage summary from all agents.
3131
3232
Args:
3333
agents: (list): List of agents.
3434
3535
Returns:
36-
tuple: (total_usage_summary, actual_usage_summary)
36+
dictionary: A dictionary containing two keys:
37+
- "usage_including_cached_inference": Cost information on the total usage, including the tokens in cached inference.
38+
- "usage_excluding_cached_inference": Cost information on the usage of tokens, excluding the tokens in cache. No larger than "usage_including_cached_inference".
3739
3840
Example:
3941
4042
```python
41-
total_usage_summary = {
42-
"total_cost": 0.0006090000000000001,
43-
"gpt-35-turbo": {
44-
"cost": 0.0006090000000000001,
45-
"prompt_tokens": 242,
46-
"completion_tokens": 123,
47-
"total_tokens": 365
43+
{
44+
"usage_including_cached_inference" : {
45+
"total_cost": 0.0006090000000000001,
46+
"gpt-35-turbo": {
47+
"cost": 0.0006090000000000001,
48+
"prompt_tokens": 242,
49+
"completion_tokens": 123,
50+
"total_tokens": 365
51+
},
52+
},
53+
54+
"usage_excluding_cached_inference" : {
55+
"total_cost": 0.0006090000000000001,
56+
"gpt-35-turbo": {
57+
"cost": 0.0006090000000000001,
58+
"prompt_tokens": 242,
59+
"completion_tokens": 123,
60+
"total_tokens": 365
61+
},
4862
}
4963
}
5064
```
5165
5266
Note:
5367
54-
`actual_usage_summary` follows the same format.
55-
If none of the agents incurred any cost (not having a client), then the total_usage_summary and actual_usage_summary will be `{'total_cost': 0}`.
68+
If none of the agents incurred any cost (not having a client), then the usage_including_cached_inference and usage_excluding_cached_inference will be `{'total_cost': 0}`.
5669
"""
5770

5871
def aggregate_summary(usage_summary: Dict[str, Any], agent_summary: Dict[str, Any]) -> None:
@@ -69,15 +82,18 @@ def aggregate_summary(usage_summary: Dict[str, Any], agent_summary: Dict[str, An
6982
usage_summary[model]["completion_tokens"] += data.get("completion_tokens", 0)
7083
usage_summary[model]["total_tokens"] += data.get("total_tokens", 0)
7184

72-
total_usage_summary = {"total_cost": 0}
73-
actual_usage_summary = {"total_cost": 0}
85+
usage_including_cached_inference = {"total_cost": 0}
86+
usage_excluding_cached_inference = {"total_cost": 0}
7487

7588
for agent in agents:
7689
if getattr(agent, "client", None):
77-
aggregate_summary(total_usage_summary, agent.client.total_usage_summary)
78-
aggregate_summary(actual_usage_summary, agent.client.actual_usage_summary)
90+
aggregate_summary(usage_including_cached_inference, agent.client.total_usage_summary)
91+
aggregate_summary(usage_excluding_cached_inference, agent.client.actual_usage_summary)
7992

80-
return total_usage_summary, actual_usage_summary
93+
return {
94+
"usage_including_cached_inference": usage_including_cached_inference,
95+
"usage_excluding_cached_inference": usage_excluding_cached_inference,
96+
}
8197

8298

8399
def parse_tags_from_content(tag: str, content: Union[str, List[Dict[str, Any]]]) -> List[Dict[str, Dict[str, str]]]:

autogen/code_utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141

4242

4343
def content_str(content: Union[str, List[Union[UserMessageTextContentPart, UserMessageImageContentPart]], None]) -> str:
44-
"""Converts the `content` field of an OpenAI merssage into a string format.
44+
"""Converts the `content` field of an OpenAI message into a string format.
4545
4646
This function processes content that may be a string, a list of mixed text and image URLs, or None,
4747
and converts it into a string. Text is directly appended to the result string, while image URLs are

notebook/agentchat_agentoptimizer.ipynb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -459,7 +459,7 @@
459459
"name": "python",
460460
"nbconvert_exporter": "python",
461461
"pygments_lexer": "ipython3",
462-
"version": "3.9.18"
462+
"version": "3.9.13"
463463
}
464464
},
465465
"nbformat": 4,

notebook/agentchat_auto_feedback_from_code_execution.ipynb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -692,6 +692,7 @@
692692
" file_content = \"No data found.\"\n",
693693
" return \"Analyze the data and write a brief but engaging blog post. \\n Data: \\n\" + file_content\n",
694694
"\n",
695+
"\n",
695696
"# followup of the previous question\n",
696697
"chat_res = user_proxy.initiate_chat(\n",
697698
" recipient=assistant,\n",

notebook/agentchat_cost_token_tracking.ipynb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -494,8 +494,8 @@
494494
}
495495
],
496496
"source": [
497-
"total_usage_summary, actual_usage_summary = gather_usage_summary([assistant, ai_user_proxy, user_proxy])\n",
498-
"total_usage_summary"
497+
"usage_summary = gather_usage_summary([assistant, ai_user_proxy, user_proxy])\n",
498+
"usage_summary[\"usage_including_cached_inference\"]"
499499
]
500500
}
501501
],

notebook/agentchat_groupchat_stateflow.ipynb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,6 @@
112112
")\n",
113113
"\n",
114114
"\n",
115-
"\n",
116115
"coder = autogen.AssistantAgent(\n",
117116
" name=\"Retrieve_Action_1\",\n",
118117
" llm_config=gpt4_config,\n",

notebook/agentchat_image_generation_capability.ipynb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@
135135
" return content[\"text\"].rstrip().endswith(\"TERMINATE\")\n",
136136
" return False\n",
137137
"\n",
138+
"\n",
138139
"def critic_agent() -> autogen.ConversableAgent:\n",
139140
" return autogen.ConversableAgent(\n",
140141
" name=\"critic\",\n",

test/agentchat/test_agent_usage.py

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,18 @@
11
#!/usr/bin/env python3 -m pytest
22

33
import io
4+
import os
5+
import sys
46
from contextlib import redirect_stdout
57

68
import pytest
7-
from conftest import skip_openai
89
from test_assistant_agent import KEY_LOC, OAI_CONFIG_LIST
910

1011
import autogen
1112
from autogen import AssistantAgent, UserProxyAgent, gather_usage_summary
1213

13-
try:
14-
import openai
15-
except ImportError:
16-
skip = True
17-
else:
18-
skip = False or skip_openai
14+
sys.path.append(os.path.join(os.path.dirname(__file__), ".."))
15+
from conftest import skip_openai as skip # noqa: E402
1916

2017

2118
@pytest.mark.skipif(skip, reason="openai not installed OR requested to skip")
@@ -62,11 +59,11 @@ def test_gathering():
6259
"gpt-4": {"cost": 0.3, "prompt_tokens": 100, "completion_tokens": 200, "total_tokens": 300},
6360
}
6461

65-
total_usage, _ = gather_usage_summary([assistant1, assistant2, assistant3])
62+
total_usage = gather_usage_summary([assistant1, assistant2, assistant3])
6663

67-
assert round(total_usage["total_cost"], 8) == 0.6
68-
assert round(total_usage["gpt-35-turbo"]["cost"], 8) == 0.3
69-
assert round(total_usage["gpt-4"]["cost"], 8) == 0.3
64+
assert round(total_usage["usage_including_cached_inference"]["total_cost"], 8) == 0.6
65+
assert round(total_usage["usage_including_cached_inference"]["gpt-35-turbo"]["cost"], 8) == 0.3
66+
assert round(total_usage["usage_including_cached_inference"]["gpt-4"]["cost"], 8) == 0.3
7067

7168
# test when agent doesn't have client
7269
user_proxy = UserProxyAgent(
@@ -77,7 +74,10 @@ def test_gathering():
7774
default_auto_reply="That's all. Thank you.",
7875
)
7976

80-
total_usage, acutal_usage = gather_usage_summary([user_proxy])
77+
total_usage = gather_usage_summary([user_proxy])
78+
total_usage_summary = total_usage["usage_including_cached_inference"]
79+
80+
print("Total usage summary:", total_usage_summary)
8181

8282

8383
@pytest.mark.skipif(skip, reason="openai not installed OR requested to skip")

0 commit comments

Comments
 (0)