You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

test_chat_completion_cache.py 5.8 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. import copy
  2. from typing import List, Tuple, Union
  3. import pytest
  4. from autogen_core.models import (
  5. ChatCompletionClient,
  6. CreateResult,
  7. LLMMessage,
  8. SystemMessage,
  9. UserMessage,
  10. )
  11. from autogen_ext.models.cache import ChatCompletionCache
  12. from autogen_ext.models.replay import ReplayChatCompletionClient
  13. def get_test_data() -> Tuple[list[str], list[str], SystemMessage, ChatCompletionClient, ChatCompletionCache]:
  14. num_messages = 3
  15. responses = [f"This is dummy message number {i}" for i in range(num_messages)]
  16. prompts = [f"This is dummy prompt number {i}" for i in range(num_messages)]
  17. system_prompt = SystemMessage(content="This is a system prompt")
  18. replay_client = ReplayChatCompletionClient(responses)
  19. replay_client.set_cached_bool_value(False)
  20. cached_client = ChatCompletionCache(replay_client)
  21. return responses, prompts, system_prompt, replay_client, cached_client
  22. @pytest.mark.asyncio
  23. async def test_cache_basic_with_args() -> None:
  24. responses, prompts, system_prompt, _, cached_client = get_test_data()
  25. response0 = await cached_client.create([system_prompt, UserMessage(content=prompts[0], source="user")])
  26. assert isinstance(response0, CreateResult)
  27. assert not response0.cached
  28. assert response0.content == responses[0]
  29. response1 = await cached_client.create([system_prompt, UserMessage(content=prompts[1], source="user")])
  30. assert not response1.cached
  31. assert response1.content == responses[1]
  32. # Cached output.
  33. response0_cached = await cached_client.create([system_prompt, UserMessage(content=prompts[0], source="user")])
  34. assert isinstance(response0, CreateResult)
  35. assert response0_cached.cached
  36. assert response0_cached.content == responses[0]
  37. # Cache miss if args change.
  38. response2 = await cached_client.create(
  39. [system_prompt, UserMessage(content=prompts[0], source="user")], json_output=True
  40. )
  41. assert isinstance(response2, CreateResult)
  42. assert not response2.cached
  43. assert response2.content == responses[2]
  44. @pytest.mark.asyncio
  45. async def test_cache_model_and_count_api() -> None:
  46. _, prompts, system_prompt, replay_client, cached_client = get_test_data()
  47. assert replay_client.model_info == cached_client.model_info
  48. assert replay_client.capabilities == cached_client.capabilities
  49. messages: List[LLMMessage] = [system_prompt, UserMessage(content=prompts[0], source="user")]
  50. assert replay_client.count_tokens(messages) == cached_client.count_tokens(messages)
  51. assert replay_client.remaining_tokens(messages) == cached_client.remaining_tokens(messages)
  52. @pytest.mark.asyncio
  53. async def test_cache_token_usage() -> None:
  54. responses, prompts, system_prompt, replay_client, cached_client = get_test_data()
  55. response0 = await cached_client.create([system_prompt, UserMessage(content=prompts[0], source="user")])
  56. assert isinstance(response0, CreateResult)
  57. assert not response0.cached
  58. assert response0.content == responses[0]
  59. actual_usage0 = copy.copy(cached_client.actual_usage())
  60. total_usage0 = copy.copy(cached_client.total_usage())
  61. response1 = await cached_client.create([system_prompt, UserMessage(content=prompts[1], source="user")])
  62. assert not response1.cached
  63. assert response1.content == responses[1]
  64. actual_usage1 = copy.copy(cached_client.actual_usage())
  65. total_usage1 = copy.copy(cached_client.total_usage())
  66. assert total_usage1.prompt_tokens > total_usage0.prompt_tokens
  67. assert total_usage1.completion_tokens > total_usage0.completion_tokens
  68. assert actual_usage1.prompt_tokens == actual_usage0.prompt_tokens
  69. assert actual_usage1.completion_tokens == actual_usage0.completion_tokens
  70. # Cached output.
  71. response0_cached = await cached_client.create([system_prompt, UserMessage(content=prompts[0], source="user")])
  72. assert isinstance(response0, CreateResult)
  73. assert response0_cached.cached
  74. assert response0_cached.content == responses[0]
  75. total_usage2 = copy.copy(cached_client.total_usage())
  76. assert total_usage2.prompt_tokens == total_usage1.prompt_tokens
  77. assert total_usage2.completion_tokens == total_usage1.completion_tokens
  78. assert cached_client.actual_usage() == replay_client.actual_usage()
  79. assert cached_client.total_usage() == replay_client.total_usage()
  80. @pytest.mark.asyncio
  81. async def test_cache_create_stream() -> None:
  82. _, prompts, system_prompt, _, cached_client = get_test_data()
  83. original_streamed_results: List[Union[str, CreateResult]] = []
  84. async for completion in cached_client.create_stream(
  85. [system_prompt, UserMessage(content=prompts[0], source="user")]
  86. ):
  87. original_streamed_results.append(copy.copy(completion))
  88. total_usage0 = copy.copy(cached_client.total_usage())
  89. cached_completion_results: List[Union[str, CreateResult]] = []
  90. async for completion in cached_client.create_stream(
  91. [system_prompt, UserMessage(content=prompts[0], source="user")]
  92. ):
  93. cached_completion_results.append(copy.copy(completion))
  94. total_usage1 = copy.copy(cached_client.total_usage())
  95. assert total_usage1.prompt_tokens == total_usage0.prompt_tokens
  96. assert total_usage1.completion_tokens == total_usage0.completion_tokens
  97. for original, cached in zip(original_streamed_results, cached_completion_results, strict=False):
  98. if isinstance(original, str):
  99. assert original == cached
  100. elif isinstance(original, CreateResult) and isinstance(cached, CreateResult):
  101. assert original.content == cached.content
  102. assert cached.cached
  103. assert not original.cached
  104. else:
  105. raise ValueError(f"Unexpected types : {type(original)} and {type(cached)}")