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.

gpt5_basic_usage.py 18 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502
  1. #!/usr/bin/env python3
  2. """
  3. GPT-5 Basic Usage Examples for AutoGen
  4. This script demonstrates the key features and usage patterns of GPT-5
  5. with AutoGen, including:
  6. 1. Basic GPT-5 model usage with reasoning control
  7. 2. Custom tools with freeform text input
  8. 3. Grammar-constrained custom tools
  9. 4. Multi-turn conversations with chain-of-thought preservation
  10. 5. Tool restrictions with allowed_tools parameter
  11. 6. Responses API for optimized performance
  12. Run this script to see GPT-5 features in action.
  13. """
  14. import asyncio
  15. import os
  16. from typing import Literal
  17. from autogen_core import CancellationToken
  18. from autogen_core.models import UserMessage
  19. from autogen_core.tools import BaseCustomTool, CustomToolFormat
  20. from autogen_ext.models.openai import OpenAIChatCompletionClient, OpenAIResponsesAPIClient
  21. from pydantic import BaseModel
  22. import json
  23. class TextResult(BaseModel):
  24. text: str
  25. def _coerce_content_to_text(content: object) -> str:
  26. if isinstance(content, str):
  27. return content
  28. try:
  29. return json.dumps(content, ensure_ascii=False, default=str)
  30. except Exception:
  31. return str(content)
  32. ReasoningEffort = Literal["minimal", "low", "medium", "high"]
  33. class CodeExecutorTool(BaseCustomTool[TextResult]):
  34. """GPT-5 custom tool for executing Python code with freeform text input."""
  35. def __init__(self):
  36. super().__init__(
  37. return_type=TextResult,
  38. name="code_exec",
  39. description="Executes Python code and returns the output. Input should be valid Python code.",
  40. )
  41. async def run(self, input_text: str, cancellation_token: CancellationToken) -> TextResult:
  42. """Execute Python code safely (in a real implementation, use proper sandboxing)."""
  43. try:
  44. # In production, use proper sandboxing like RestrictedPython or containers
  45. # This is a simplified example
  46. import io
  47. from contextlib import redirect_stdout
  48. output = io.StringIO()
  49. with redirect_stdout(output):
  50. exec(
  51. input_text,
  52. {
  53. "__builtins__": {
  54. "print": print,
  55. "len": len,
  56. "str": str,
  57. "int": int,
  58. "float": float,
  59. }
  60. },
  61. )
  62. result = output.getvalue()
  63. text = (
  64. f"Code executed successfully:\n{result}" if result else "Code executed successfully (no output)"
  65. )
  66. return TextResult(text=text)
  67. except Exception as e: # noqa: BLE001
  68. return TextResult(text=f"Error executing code: {e}")
  69. class SQLQueryTool(BaseCustomTool[TextResult]):
  70. """GPT-5 custom tool with grammar constraints for SQL queries."""
  71. def __init__(self):
  72. # Define SQL grammar using Lark syntax
  73. sql_grammar = CustomToolFormat(
  74. type="grammar",
  75. syntax="lark",
  76. definition=r"""
  77. start: select_statement
  78. select_statement: "SELECT" column_list "FROM" table_name where_clause?
  79. column_list: column ("," column)*
  80. | "*"
  81. column: IDENTIFIER
  82. table_name: IDENTIFIER
  83. where_clause: "WHERE" condition
  84. condition: column operator value
  85. operator: "=" | ">" | "<" | ">=" | "<=" | "!="
  86. value: NUMBER | STRING
  87. IDENTIFIER: /[a-zA-Z_][a-zA-Z0-9_]*/
  88. NUMBER: /[0-9]+(\.[0-9]+)?/
  89. STRING: /"[^"]*"/
  90. %import common.WS
  91. %ignore WS
  92. """,
  93. )
  94. super().__init__(
  95. return_type=TextResult,
  96. name="sql_query",
  97. description="Execute SQL SELECT queries with grammar validation. Only SELECT statements are allowed.",
  98. format=sql_grammar,
  99. )
  100. async def run(self, input_text: str, cancellation_token: CancellationToken) -> TextResult:
  101. """Simulate SQL query execution."""
  102. # In a real implementation, this would connect to a database
  103. # This is a mock response for demonstration
  104. return TextResult(
  105. text=(
  106. f"SQL Query Results:\nExecuted: {input_text}\nResult: [Mock data returned - 3 rows affected]"
  107. )
  108. )
  109. class CalculatorTool(BaseCustomTool[TextResult]):
  110. """Simple calculator tool for safe mathematical operations."""
  111. def __init__(self):
  112. super().__init__(
  113. return_type=TextResult,
  114. name="calculator",
  115. description=(
  116. "Perform basic mathematical calculations safely. Input should be a mathematical expression."
  117. ),
  118. )
  119. async def run(self, input_text: str, cancellation_token: CancellationToken) -> TextResult:
  120. """Safely evaluate mathematical expressions."""
  121. try:
  122. import ast
  123. import operator
  124. allowed_ops: dict[type[ast.AST], object] = {
  125. ast.Add: operator.add,
  126. ast.Sub: operator.sub,
  127. ast.Mult: operator.mul,
  128. ast.Div: operator.truediv,
  129. ast.Mod: operator.mod,
  130. ast.Pow: operator.pow,
  131. ast.USub: operator.neg,
  132. }
  133. def safe_eval(node: ast.AST) -> float | int:
  134. if isinstance(node, ast.Expression):
  135. return safe_eval(node.body) # type: ignore[arg-type]
  136. if isinstance(node, ast.Constant):
  137. if isinstance(node.value, (int, float)):
  138. return node.value
  139. raise ValueError("Only numeric constants are allowed")
  140. if isinstance(node, ast.BinOp):
  141. left = safe_eval(node.left)
  142. right = safe_eval(node.right)
  143. op = allowed_ops.get(type(node.op))
  144. if op:
  145. return op(left, right) # type: ignore[call-arg]
  146. if isinstance(node, ast.UnaryOp):
  147. operand = safe_eval(node.operand)
  148. op = allowed_ops.get(type(node.op))
  149. if op:
  150. return op(operand) # type: ignore[call-arg]
  151. raise ValueError(f"Unsupported operation: {type(node)}")
  152. tree = ast.parse(input_text, mode="eval")
  153. result = safe_eval(tree)
  154. return TextResult(text=f"Calculation result: {result}")
  155. except Exception as e: # noqa: BLE001
  156. return TextResult(text=f"Error in calculation: {e}")
  157. async def demonstrate_gpt5_basic_usage():
  158. """Demonstrate basic GPT-5 usage with reasoning control."""
  159. print("🚀 GPT-5 Basic Usage Example")
  160. print("=" * 50)
  161. # Initialize GPT-5 client
  162. client = OpenAIChatCompletionClient(
  163. model="gpt-5",
  164. api_key=os.getenv("OPENAI_API_KEY", "your-api-key-here"),
  165. )
  166. # Example 1: Basic reasoning with different effort levels
  167. print("\n1. Reasoning Effort Control:")
  168. print("-" * 30)
  169. # High reasoning for complex problems
  170. response = await client.create(
  171. messages=[UserMessage(
  172. content="Explain the concept of quantum entanglement and its implications for quantum computing",
  173. source="user",
  174. )],
  175. reasoning_effort="high",
  176. verbosity="medium",
  177. preambles=True,
  178. )
  179. print(f"High reasoning response: {_coerce_content_to_text(response.content)}")
  180. if response.thought:
  181. print(f"Reasoning process: {response.thought}")
  182. # Minimal reasoning for simple tasks
  183. response = await client.create(
  184. messages=[UserMessage(
  185. content="What's 2 + 2?",
  186. source="user",
  187. )],
  188. reasoning_effort="minimal",
  189. verbosity="low",
  190. )
  191. print(f"Minimal reasoning response: {_coerce_content_to_text(response.content)}")
  192. await client.close()
  193. async def demonstrate_gpt5_custom_tools():
  194. """Demonstrate GPT-5 custom tools with freeform text input."""
  195. print("\n🛠️ GPT-5 Custom Tools Example")
  196. print("=" * 50)
  197. client = OpenAIChatCompletionClient(
  198. model="gpt-5",
  199. api_key=os.getenv("OPENAI_API_KEY", "your-api-key-here"),
  200. )
  201. # Initialize custom tools
  202. code_tool = CodeExecutorTool()
  203. sql_tool = SQLQueryTool()
  204. print("\n2. Custom Tool with Freeform Input:")
  205. print("-" * 40)
  206. # Code execution example
  207. response = await client.create(
  208. messages=[UserMessage(
  209. content="Calculate the factorial of 8 using Python code",
  210. source="user",
  211. )],
  212. tools=[code_tool],
  213. reasoning_effort="medium",
  214. verbosity="low",
  215. preambles=True, # Explain why tools are used
  216. )
  217. print(f"Tool response: {_coerce_content_to_text(response.content)}")
  218. if response.thought:
  219. print(f"Tool explanation: {response.thought}")
  220. print("\n3. Grammar-Constrained Custom Tool:")
  221. print("-" * 40)
  222. # SQL query with grammar constraints
  223. response = await client.create(
  224. messages=[UserMessage(
  225. content="Query all users from the users table where age is greater than 25",
  226. source="user",
  227. )],
  228. tools=[sql_tool],
  229. reasoning_effort="low",
  230. preambles=True,
  231. )
  232. print(f"SQL response: {_coerce_content_to_text(response.content)}")
  233. await client.close()
  234. async def demonstrate_allowed_tools():
  235. """Demonstrate allowed_tools parameter for restricting model behavior."""
  236. print("\n🔒 GPT-5 Allowed Tools Example")
  237. print("=" * 50)
  238. client = OpenAIChatCompletionClient(
  239. model="gpt-5",
  240. api_key=os.getenv("OPENAI_API_KEY", "your-api-key-here"),
  241. )
  242. # Create multiple tools
  243. code_tool = CodeExecutorTool()
  244. sql_tool = SQLQueryTool()
  245. calc_tool = CalculatorTool()
  246. all_tools = [code_tool, sql_tool, calc_tool]
  247. safe_tools = [calc_tool] # Only allow calculator for safety
  248. print("\n4. Restricted Tool Access:")
  249. print("-" * 30)
  250. response = await client.create(
  251. messages=[UserMessage(
  252. content="I need help with calculations, database queries, and code execution",
  253. source="user",
  254. )],
  255. tools=all_tools,
  256. allowed_tools=safe_tools, # Restrict to only calculator
  257. tool_choice="auto",
  258. reasoning_effort="medium",
  259. preambles=True,
  260. )
  261. print(f"Restricted response: {_coerce_content_to_text(response.content)}")
  262. if response.thought:
  263. print(f"Tool restriction explanation: {response.thought}")
  264. await client.close()
  265. async def demonstrate_responses_api():
  266. """Demonstrate GPT-5 Responses API for optimized multi-turn conversations."""
  267. print("\n💬 GPT-5 Responses API Example")
  268. print("=" * 50)
  269. # Use the Responses API for better performance in multi-turn conversations
  270. client = OpenAIResponsesAPIClient(
  271. model="gpt-5",
  272. api_key=os.getenv("OPENAI_API_KEY", "your-api-key-here"),
  273. )
  274. print("\n5. Multi-Turn Conversation with CoT Preservation:")
  275. print("-" * 50)
  276. # Turn 1: Initial complex question requiring high reasoning
  277. print("Turn 1: Complex initial question")
  278. response1 = await client.create(
  279. input="Design a distributed system architecture for a real-time chat application that can handle millions of users",
  280. reasoning_effort="high",
  281. verbosity="medium",
  282. preambles=True,
  283. )
  284. print(f"Response 1: {_coerce_content_to_text(response1.content)}")
  285. if response1.thought:
  286. print(f"Reasoning 1: {response1.thought[:200]}...")
  287. # Turn 2: Follow-up question with preserved context
  288. print("\nTurn 2: Follow-up with preserved reasoning context")
  289. response2 = await client.create(
  290. input="How would you handle data consistency in this distributed system?",
  291. previous_response_id=getattr(response1, 'response_id', None), # Preserve CoT context
  292. reasoning_effort="medium", # Can use lower effort due to context
  293. verbosity="medium",
  294. )
  295. print(f"Response 2: {_coerce_content_to_text(response2.content)}")
  296. # Turn 3: Implementation request with tools
  297. print("\nTurn 3: Implementation with custom tools")
  298. code_tool = CodeExecutorTool()
  299. response3 = await client.create(
  300. input="Show me a simple example of the message routing logic in Python",
  301. previous_response_id=getattr(response2, 'response_id', None),
  302. tools=[code_tool],
  303. reasoning_effort="low", # Minimal reasoning needed due to established context
  304. preambles=True,
  305. )
  306. print(f"Response 3: {_coerce_content_to_text(response3.content)}")
  307. if response3.thought:
  308. print(f"Implementation explanation: {response3.thought}")
  309. await client.close()
  310. async def demonstrate_model_variants():
  311. """Demonstrate different GPT-5 model variants."""
  312. print("\n🎯 GPT-5 Model Variants Example")
  313. print("=" * 50)
  314. print("\n6. Model Variant Comparison:")
  315. print("-" * 30)
  316. # GPT-5 (full model)
  317. gpt5_client = OpenAIChatCompletionClient(
  318. model="gpt-5",
  319. api_key=os.getenv("OPENAI_API_KEY", "your-api-key-here"),
  320. )
  321. # GPT-5 Mini (cost-optimized)
  322. gpt5_mini_client = OpenAIChatCompletionClient(
  323. model="gpt-5-mini",
  324. api_key=os.getenv("OPENAI_API_KEY", "your-api-key-here"),
  325. )
  326. # GPT-5 Nano (high-throughput)
  327. gpt5_nano_client = OpenAIChatCompletionClient(
  328. model="gpt-5-nano",
  329. api_key=os.getenv("OPENAI_API_KEY", "your-api-key-here"),
  330. )
  331. question = "Briefly explain machine learning"
  332. # Compare responses from different variants
  333. print("GPT-5 (full model):")
  334. response = await gpt5_client.create(
  335. messages=[UserMessage(content=question, source="user")],
  336. reasoning_effort="medium",
  337. verbosity="medium",
  338. )
  339. print(f" {_coerce_content_to_text(response.content)[:100]}...")
  340. print(f" Token usage: {response.usage.prompt_tokens + response.usage.completion_tokens}")
  341. print("\nGPT-5 Mini (cost-optimized):")
  342. response = await gpt5_mini_client.create(
  343. messages=[UserMessage(content=question, source="user")],
  344. reasoning_effort="medium",
  345. verbosity="medium",
  346. )
  347. print(f" {_coerce_content_to_text(response.content)[:100]}...")
  348. print(f" Token usage: {response.usage.prompt_tokens + response.usage.completion_tokens}")
  349. print("\nGPT-5 Nano (high-throughput):")
  350. response = await gpt5_nano_client.create(
  351. messages=[UserMessage(content=question, source="user")],
  352. reasoning_effort="minimal",
  353. verbosity="low",
  354. )
  355. print(f" {_coerce_content_to_text(response.content)[:100]}...")
  356. print(f" Token usage: {response.usage.prompt_tokens + response.usage.completion_tokens}")
  357. await gpt5_client.close()
  358. await gpt5_mini_client.close()
  359. await gpt5_nano_client.close()
  360. async def main():
  361. """Run all GPT-5 examples."""
  362. print("🎉 Welcome to GPT-5 Features Demo with AutoGen!")
  363. print("=" * 60)
  364. print("This demo showcases the key GPT-5 features and capabilities.")
  365. print("Make sure to set your OPENAI_API_KEY environment variable.")
  366. print("")
  367. try:
  368. # Run all examples
  369. await demonstrate_gpt5_basic_usage()
  370. await demonstrate_gpt5_custom_tools()
  371. await demonstrate_allowed_tools()
  372. await demonstrate_responses_api()
  373. await demonstrate_model_variants()
  374. print("\n🎊 All GPT-5 examples completed successfully!")
  375. print("=" * 60)
  376. print("Key takeaways:")
  377. print("• GPT-5 offers fine-grained reasoning and verbosity control")
  378. print("• Custom tools accept freeform text input with optional grammar constraints")
  379. print("• Allowed tools parameter provides safety through tool restrictions")
  380. print("• Responses API optimizes multi-turn conversations with CoT preservation")
  381. print("• Different model variants (gpt-5, gpt-5-mini, gpt-5-nano) balance performance and cost")
  382. except Exception as e: # noqa: BLE001
  383. print(f"\n❌ Error running examples: {e}")
  384. print("Make sure you have:")
  385. print("1. Set OPENAI_API_KEY environment variable")
  386. print("2. Installed required dependencies: pip install autogen-ext[openai]")
  387. print("3. Have access to GPT-5 models in your OpenAI account")
  388. if __name__ == "__main__":
  389. # Set up example API key if not in environment
  390. if not os.getenv("OPENAI_API_KEY"):
  391. print("⚠️ Warning: OPENAI_API_KEY environment variable not found.")
  392. print("Please set it with: export OPENAI_API_KEY='your-api-key-here'")
  393. print("Or uncomment the line below to set it in code (not recommended for production)")
  394. # os.environ["OPENAI_API_KEY"] = "your-api-key-here"
  395. asyncio.run(main())