Msingh openai reasoning param (#1665)

This commit is contained in:
Mandeep Singh 2025-02-04 10:00:34 -08:00 committed by GitHub
parent bb0dae2feb
commit f297551a6b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 137 additions and 97 deletions

View File

@ -341,7 +341,10 @@
"- Initialized with the developer prompt, model name, logger, and language model interface. These values can be overridden by the developer if needed. \n",
"- Has a setup_tools method that registers the PythonExecTool to the tool manager. \n",
"- Has a `task` method that calls the OpenAI API to perform the user's task, which in this case involves generating a Python script to answer the user's question and run it with Code Interpreter tool.\n",
"- `model_name='o3-mini'` that excels at STEM tasks such as code generation."
"- `model_name='o3-mini'` that excels at STEM tasks such as code generation.\n",
"- `reasoning_effort='high'` that allows for more complete reasoning given the complexity of the task at the cost of more tokens generated and slower responses. The default value is medium, which is a balance between speed and reasoning accuracy.\n",
"\n",
"You can learn more about the `reasoning_effort` parameter [here](https://platform.openai.com/docs/guides/reasoning)."
]
},
{
@ -363,8 +366,8 @@
"id": "866b7eb2",
"metadata": {
"ExecuteTime": {
"end_time": "2025-02-02T20:02:01.744619Z",
"start_time": "2025-02-02T20:00:26.688229Z"
"end_time": "2025-02-03T21:05:18.680311Z",
"start_time": "2025-02-03T21:03:52.169439Z"
}
},
"outputs": [
@ -395,9 +398,9 @@
"name": "stderr",
"output_type": "stream",
"text": [
"2025-02-02 12:00:27,749 - MyApp - INFO - Handling tool call: safe_file_access\n",
"2025-02-02 12:00:27,749 - MyApp - INFO - Tool arguments: {'filename': './resources/data/traffic_accidents.csv'}\n",
"2025-02-02 12:00:28,223 - MyApp - INFO - Tool 'safe_file_access' response: Copied ./resources/data/traffic_accidents.csv into sandbox:/home/sandboxuser/.\n",
"2025-02-03 13:03:54,066 - MyApp - INFO - Handling tool call: safe_file_access\n",
"2025-02-03 13:03:54,067 - MyApp - INFO - Tool arguments: {'filename': './resources/data/traffic_accidents.csv'}\n",
"2025-02-03 13:03:54,562 - MyApp - INFO - Tool 'safe_file_access' response: Copied ./resources/data/traffic_accidents.csv into sandbox:/home/sandboxuser/.\n",
"The file content for the first 15 rows is:\n",
" accidents traffic_fine_amount traffic_density traffic_lights pavement_quality urban_area average_speed rain_intensity vehicle_count time_of_day\n",
"0 20 4.3709 2.3049 753.000 0.7700 1 321.592 1.1944 290.8570 160.4320\n",
@ -430,9 +433,10 @@
"name": "stderr",
"output_type": "stream",
"text": [
"2025-02-02 12:00:46,338 - MyApp - INFO - Handling tool call: execute_python_code\n",
"2025-02-02 12:00:46,339 - MyApp - INFO - Tool arguments: {'python_code': \"import pandas as pd\\nimport numpy as np\\nimport matplotlib.pyplot as plt\\nimport seaborn as sns\\nfrom sklearn.ensemble import RandomForestRegressor\\nfrom sklearn.model_selection import train_test_split\\nfrom sklearn.metrics import mean_squared_error\\n\\n# Load the data\\nfile_path = '/home/sandboxuser/traffic_accidents.csv'\\ndf = pd.read_csv(file_path)\\n\\n# Display head (first few rows) and dataframe info for debugging\\nprint('Data Head:')\\nprint(df.head())\\nprint('\\\\nData Info:')\\nprint(df.info())\\n\\n# Check for duplicate columns in case of mislabel (the description had duplicate variable names)\\nprint('\\\\nColumns:', df.columns.tolist())\\n\\n# Define target and features. assuming 'accidents' is the response.\\n# We use all the other columns as predictors.\\n\\ntarget = 'accidents'\\nfeatures = [col for col in df.columns if col != target]\\n\\n# Exploratory analysis: Compute correlation between accidents and other features\\ncorr = df.corr()\\nprint('\\\\nCorrelation matrix:')\\nprint(corr[target].sort_values(ascending=False))\\n\\n# Plot correlation heatmap\\nplt.figure(figsize=(10,8))\\nsns.heatmap(corr, annot=True, cmap='coolwarm', fmt='.2f')\\nplt.title('Correlation Heatmap')\\nplt.tight_layout()\\nplt.savefig('correlation_heatmap.png')\\nplt.close()\\n\\n# Use a RandomForestRegressor to evaluate feature importances\\n# Prepare the data (if any missing values, fill with median for simplicity)\\ndf = df.fillna(df.median())\\n\\nX = df[features]\\ny = df[target]\\n\\n# Split the dataset into training and test set\\nX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)\\n\\n# Train the model\\nmodel = RandomForestRegressor(n_estimators=100, random_state=42)\\nmodel.fit(X_train, y_train)\\n\\n# Predict\\ny_pred = model.predict(X_test)\\nmse = mean_squared_error(y_test, y_pred)\\nprint('\\\\nRandom Forest Model Mean Squared Error:', mse)\\n\\n# Get feature importances\\nimportances = model.feature_importances_\\nfeat_importance = pd.Series(importances, index=features).sort_values(ascending=False)\\nprint('\\\\nFeature Importances from Random Forest:')\\nprint(feat_importance)\\n\\n# Plot feature importances\\nplt.figure(figsize=(10,6))\\nfeat_importance.plot(kind='bar')\\nplt.ylabel('Importance')\\nplt.title('Feature Importances for Accident Frequency Prediction')\\nplt.tight_layout()\\nplt.savefig('feature_importances.png')\\nplt.close()\\n\\nprint('\\\\nAnalysis Summary:')\\nprint('The correlation analysis and the random forest model indicate which factors are most associated with accident frequency. Factors with high correlation (absolute value) and high importance in the random forest model are likely significant contributors to accident frequency. Review the printed correlation values and the feature importance rankings to identify the key factors.')\\n\\n# The code also saved correlation heatmap and feature importance plots to PNG files.\\n\\n# For quick view, print both images paths:\\nprint('\\\\nCorrelation heatmap saved as correlation_heatmap.png')\\nprint('Feature importance plot saved as feature_importances.png')\\n\"}\n",
"2025-02-02 12:00:49,502 - MyApp - INFO - Tool 'execute_python_code' response: Data Head:\n",
"2025-02-03 13:04:39,427 - MyApp - INFO - Handling tool call: execute_python_code\n",
"2025-02-03 13:04:39,429 - MyApp - INFO - Tool arguments: {'python_code': \"import pandas as pd\\nimport numpy as np\\nfrom sklearn.linear_model import LinearRegression\\nfrom sklearn.preprocessing import StandardScaler\\nimport matplotlib.pyplot as plt\\nimport seaborn as sns\\n\\n# Load the dataset\\nfile_path = '/home/sandboxuser/traffic_accidents.csv'\\ndf = pd.read_csv(file_path)\\n\\n# Show basic information\\nprint('Dataset shape:', df.shape)\\nprint('First few rows:')\\nprint(df.head(), '\\\\n')\\nprint('Columns:', df.columns.tolist(), '\\\\n')\\n\\n# Correlation matrix analysis\\ncorr_matrix = df.corr()\\nprint('Correlation matrix:')\\nprint(corr_matrix, '\\\\n')\\n\\n# Correlation of each feature with accidents\\nacc_corr = corr_matrix['accidents'].drop('accidents').sort_values(key=lambda x: abs(x), ascending=False)\\nprint('Correlation of other variables with accidents (sorted by absolute correlation):')\\nprint(acc_corr, '\\\\n')\\n\\n# Visualize the correlation matrix\\nplt.figure(figsize=(10, 8))\\nsns.heatmap(corr_matrix, annot=True, cmap='coolwarm', fmt='.2f')\\nplt.title('Correlation Matrix')\\nplt.tight_layout()\\nplt.savefig('correlation_matrix.png')\\nplt.close()\\n\\n# Prepare data for regression analysis\\n# Exclude target variable 'accidents'\\nfeatures = [col for col in df.columns if col != 'accidents']\\nX = df[features]\\ny = df['accidents']\\n\\n# Standardize the features to compare the regression coefficients on the same scale\\nscaler = StandardScaler()\\nX_scaled = scaler.fit_transform(X)\\n\\n# Fit a linear regression model\\nmodel = LinearRegression()\\nmodel.fit(X_scaled, y)\\n\\n# Gather coefficients along with feature names\\ncoef = model.coef_\\ncoef_df = pd.DataFrame({'Feature': features, 'Coefficient': coef})\\ncoef_df['AbsCoefficient'] = coef_df['Coefficient'].abs()\\ncoef_df = coef_df.sort_values(by='AbsCoefficient', ascending=False)\\nprint('Linear Regression Coefficients (using standardized features):')\\nprint(coef_df[['Feature', 'Coefficient']], '\\\\n')\\n\\n# Additionally, compute feature importances using a Random Forest regressor\\nfrom sklearn.ensemble import RandomForestRegressor\\nrf = RandomForestRegressor(random_state=42)\\nrf.fit(X, y)\\nrf_importance = rf.feature_importances_\\nrf_df = pd.DataFrame({'Feature': features, 'Importance': rf_importance})\\nrf_df = rf_df.sort_values(by='Importance', ascending=False)\\nprint('Random Forest Feature Importances:')\\nprint(rf_df, '\\\\n')\\n\\n# The printed outputs will help in understanding which factors contribute most to accident frequency.\\n\\n# For clarity, save the coefficients and importances to CSV files (optional)\\ncoef_df.to_csv('linear_regression_coefficients.csv', index=False)\\nrf_df.to_csv('random_forest_importances.csv', index=False)\\n\\n# End of analysis\\n\"}\n",
"2025-02-03 13:04:43,123 - MyApp - INFO - Tool 'execute_python_code' response: Dataset shape: (8756, 10)\n",
"First few rows:\n",
" accidents traffic_fine_amount ... vehicle_count time_of_day\n",
"0 20 4.3709 ... 290.8570 160.4320\n",
"1 11 9.5564 ... 931.8120 8.9108\n",
@ -440,62 +444,61 @@
"3 23 6.3879 ... 813.1590 131.4520\n",
"4 23 2.4042 ... 1.4663 6.9610\n",
"\n",
"[5 rows x 10 columns]\n",
"[5 rows x 10 columns] \n",
"\n",
"Data Info:\n",
"<class 'pandas.core.frame.DataFrame'>\n",
"RangeIndex: 8756 entries, 0 to 8755\n",
"Data columns (total 10 columns):\n",
" # Column Non-Null Count Dtype \n",
"--- ------ -------------- ----- \n",
" 0 accidents 8756 non-null int64 \n",
" 1 traffic_fine_amount 8756 non-null float64\n",
" 2 traffic_density 8756 non-null float64\n",
" 3 traffic_lights 8756 non-null float64\n",
" 4 pavement_quality 8756 non-null float64\n",
" 5 urban_area 8756 non-null int64 \n",
" 6 average_speed 8756 non-null float64\n",
" 7 rain_intensity 8756 non-null float64\n",
" 8 vehicle_count 8756 non-null float64\n",
" 9 time_of_day 8756 non-null float64\n",
"dtypes: float64(8), int64(2)\n",
"memory usage: 684.2 KB\n",
"None\n",
"\n",
"Columns: ['accidents', 'traffic_fine_amount', 'traffic_density', 'traffic_lights', 'pavement_quality', 'urban_area', 'average_speed', 'rain_intensity', 'vehicle_count', 'time_of_day']\n",
"Columns: ['accidents', 'traffic_fine_amount', 'traffic_density', 'traffic_lights', 'pavement_quality', 'urban_area', 'average_speed', 'rain_intensity', 'vehicle_count', 'time_of_day'] \n",
"\n",
"Correlation matrix:\n",
"accidents 1.000000\n",
" accidents traffic_fine_amount ... vehicle_count time_of_day\n",
"accidents 1.000000 -0.745161 ... 0.068399 0.101995\n",
"traffic_fine_amount -0.745161 1.000000 ... -0.016610 -0.006236\n",
"traffic_density -0.059265 -0.004365 ... -0.014244 0.002806\n",
"traffic_lights -0.026642 0.009056 ... 0.001373 -0.001971\n",
"pavement_quality 0.064694 -0.021229 ... 0.007840 0.000055\n",
"urban_area 0.145092 -0.005136 ... -0.006053 -0.006320\n",
"average_speed 0.093923 0.009151 ... 0.000777 -0.005338\n",
"rain_intensity -0.091673 -0.015302 ... -0.025933 -0.013446\n",
"vehicle_count 0.068399 -0.016610 ... 1.000000 -0.009303\n",
"time_of_day 0.101995 -0.006236 ... -0.009303 1.000000\n",
"\n",
"[10 rows x 10 columns] \n",
"\n",
"Correlation of other variables with accidents (sorted by absolute correlation):\n",
"traffic_fine_amount -0.745161\n",
"urban_area 0.145092\n",
"time_of_day 0.101995\n",
"average_speed 0.093923\n",
"rain_intensity -0.091673\n",
"vehicle_count 0.068399\n",
"pavement_quality 0.064694\n",
"traffic_lights -0.026642\n",
"traffic_density -0.059265\n",
"rain_intensity -0.091673\n",
"traffic_fine_amount -0.745161\n",
"Name: accidents, dtype: float64\n",
"traffic_lights -0.026642\n",
"Name: accidents, dtype: float64 \n",
"\n",
"Random Forest Model Mean Squared Error: 5.559347659817352\n",
"Linear Regression Coefficients (using standardized features):\n",
" Feature Coefficient\n",
"0 traffic_fine_amount -3.891935\n",
"4 urban_area 0.739618\n",
"5 average_speed 0.533698\n",
"6 rain_intensity -0.532251\n",
"8 time_of_day 0.512661\n",
"1 traffic_density -0.331997\n",
"7 vehicle_count 0.281283\n",
"3 pavement_quality 0.264987\n",
"2 traffic_lights -0.092800 \n",
"\n",
"Feature Importances from Random Forest:\n",
"traffic_fine_amount 0.580211\n",
"traffic_density 0.169094\n",
"rain_intensity 0.095742\n",
"time_of_day 0.036433\n",
"average_speed 0.033714\n",
"pavement_quality 0.030789\n",
"traffic_lights 0.023037\n",
"vehicle_count 0.021283\n",
"urban_area 0.009697\n",
"dtype: float64\n",
"Random Forest Feature Importances:\n",
" Feature Importance\n",
"0 traffic_fine_amount 0.580838\n",
"1 traffic_density 0.165201\n",
"6 rain_intensity 0.095124\n",
"8 time_of_day 0.035814\n",
"5 average_speed 0.035590\n",
"3 pavement_quality 0.032177\n",
"2 traffic_lights 0.022613\n",
"7 vehicle_count 0.021006\n",
"4 urban_area 0.011637 \n",
"\n",
"Analysis Summary:\n",
"The correlation analysis and the random forest model indicate which factors are most associated with accident frequency. Factors with high correlation (absolute value) and high importance in the random forest model are likely significant contributors to accident frequency. Review the printed correlation values and the feature importance rankings to identify the key factors.\n",
"\n",
"Correlation heatmap saved as correlation_heatmap.png\n",
"Feature importance plot saved as feature_importances.png\n",
"\n"
]
},
@ -504,17 +507,17 @@
"output_type": "stream",
"text": [
"Output...\n",
"The analysis (both the correlation study and the random forest feature importance) indicates that the traffic fine amount is the single most influential factor related to accident frequency. Heres a summary of the key results:\n",
"The analysis shows that one variable stands out by far:\n",
"\n",
"1. The Pearson correlation between accidents and traffic fine amount is about 0.75 (a strong negative relationship), which implies that as fine amount increases, accident frequency tends to decrease.\n",
"Both the simple correlation analysis and regression results indicate that traffic_fine_amount is the dominant factor—its correlation with accidents is strong (about 0.75), and in the standardized linear regression its coefficient is the largest in magnitude (around 3.89). The negative sign suggests that, in this data, higher fine amounts are associated with fewer accidents (which might reflect more stringent enforcement or deterrence).\n",
"\n",
"2. In the random forest model, the traffic fine amount had the highest feature importance (approximately 58% importance), followed by traffic density (about 17%) and rain intensity (around 10%). These three predictors drive most of the models ability to predict accident frequency.\n",
"Other findings include:\n",
"\n",
"3. Other factors such as average speed, pavement quality, traffic lights, vehicle count, urban area, and time of day contribute less significantly according to both the correlation and feature importance analysis.\n",
"The Random Forest model also ranks traffic_fine_amount as most important (importance ≈ 0.58), with the next most influential factor being traffic_density (importance ≈ 0.17). Although its simple correlation with accidents is lower, traffic_density may contribute nonlinearly.\n",
"\n",
"This suggests that factors impacting or reflecting traffic fine regimes (and, by extension, traffic law enforcement or penalties) are critically related to accident frequency, with additional contributions from aspects representing the local traffic conditions (density) and environmental factors (rain intensity).\n",
"Additional factors like urban_area, average_speed, rain_intensity, and time_of_day have moderate associations (with linear model coefficients ranging between about ±0.5 to +0.74). These suggest that accidents tend to be somewhat higher in urban areas and vary with time of day and weather conditions, but their overall impact is much less than that of traffic fine amounts.\n",
"\n",
"The code below was used to load the CSV data, perform the analysis, generate correlation heatmaps, and compute the random forests feature importances for accident frequency prediction.\n",
"In summary, the data analysis indicates that traffic_fine_amount contributes the most to accident frequency—with higher fines linked to fewer recorded accidents—while factors such as traffic density, urban area status, vehicle speed, rain intensity, and time of day also play secondary roles.\n",
"Type your question related to the data in the file. Type 'exit' to exit.\n",
"Exiting the application.\n"
]
@ -554,8 +557,8 @@
"# This agent use gpt-4o by default\n",
"file_ingestion_agent = FileAccessAgent()\n",
"\n",
"# This agent uses o3-mini model by default\n",
"data_analysis_agent = PythonExecAgent(model_name='o3-mini')\n",
"# Let's make sure agent uses o3-mini model and set the reasoning_effort to high\n",
"data_analysis_agent = PythonExecAgent(model_name='o3-mini', reasoning_effort='high')\n",
"\n",
"print(\"Understanding the contents of the file...\")\n",
"# Give a task to the file ingestion agent to read the file and provide the context to the data analysis agent \n",
@ -590,7 +593,9 @@
"id": "29f96b97",
"metadata": {},
"source": [
"In this example, the **o3-mini** dynamically generated a tool (Python script) based on user's question to analyze the data. Note that **o3-mini** examined the problem using multiple approaches such as Pearson correlation and random forest models. This approach showcases the following:\n",
"In this example, the **o3-mini** dynamically generated a tool (Python script) based on user's question to analyze the data. Note that **o3-mini** examined the problem using multiple approaches such as correlation analysis, linear regression and random forest models. This approach highlights the following:\n",
"\n",
"**reasoning_effort**: The depth of reasoning the model performs e.g., in this case number of approaches, generally increases when the parameter is increased from low, medium to high. You can try with different levels of reasoning effort to see the difference.\n",
"\n",
"**Dynamically Generated Tool Calling**: The tool (Python script) to analyze the data was not manually written or predetermined by the developer. Instead, the o3-mini model created the relevant data exploration and correlation analysis code at runtime.\n",
"\n",

View File

@ -1,4 +1,5 @@
# object_oriented_agents/core_classes/agent_signature.py
from typing import Optional, Dict, Any, List
from .tool_manager import ToolManager
@ -8,12 +9,14 @@ class AgentSignature:
- The developer prompt
- The model name
- The list of tool definitions
- The default reasoning effort (if any)
"""
def __init__(self, developer_prompt: str, model_name: str, tool_manager: Optional[ToolManager] = None):
def __init__(self, developer_prompt: str, model_name: str, tool_manager: Optional[ToolManager] = None, reasoning_effort: Optional[str] = None):
self.developer_prompt = developer_prompt
self.model_name = model_name
self.tool_manager = tool_manager
self.reasoning_effort = reasoning_effort
def to_dict(self) -> Dict[str, Any]:
"""
@ -21,17 +24,21 @@ class AgentSignature:
1. The developer prompt
2. The model name
3. A list of tool definitions (function schemas)
4. The default reasoning effort if defined
"""
if self.tool_manager:
# Each item in get_tool_definitions() looks like {"type": "function", "function": {...}}
tool_definitions = self.tool_manager.get_tool_definitions()
# We need the whole definition for the final signature
functions = [t for t in tool_definitions]
else:
functions = []
return {
signature_dict = {
"developer_prompt": self.developer_prompt,
"model_name": self.model_name,
"tools": functions
}
}
if self.reasoning_effort is not None:
signature_dict["reasoning_effort"] = self.reasoning_effort
return signature_dict

View File

@ -1,4 +1,5 @@
# object_oriented_agents/core_classes/base_agent.py
from abc import ABC, abstractmethod
from typing import Optional
from .chat_messages import ChatMessages
@ -19,7 +20,8 @@ class BaseAgent(ABC):
developer_prompt: str,
model_name: str,
logger=None,
language_model_interface: LanguageModelInterface = None
language_model_interface: LanguageModelInterface = None,
reasoning_effort: Optional[str] = None
):
self.developer_prompt = developer_prompt
self.model_name = model_name
@ -27,6 +29,7 @@ class BaseAgent(ABC):
self.tool_manager: Optional[ToolManager] = None
self.logger = logger or get_logger(self.__class__.__name__)
self.language_model_interface = language_model_interface
self.reasoning_effort = reasoning_effort
@abstractmethod
def setup_tools(self) -> None:
@ -40,12 +43,16 @@ class BaseAgent(ABC):
self.logger.debug(f"Adding user message: {content}")
self.messages.add_user_message(content)
def task(self, user_task: str, tool_call_enabled: bool = True, return_tool_response_as_is: bool = False) -> str:
def task(self, user_task: str, tool_call_enabled: bool = True, return_tool_response_as_is: bool = False,
reasoning_effort: Optional[str] = None) -> str:
# Use the reasoning_effort provided in the method call if present, otherwise fall back to the agent's default
final_reasoning_effort = reasoning_effort if reasoning_effort is not None else self.reasoning_effort
if self.language_model_interface is None:
error_message = "Error: Cannot execute task without the LanguageModelInterface."
self.logger.error(error_message)
raise ValueError(error_message)
self.logger.debug(f"Starting task: {user_task} (tool_call_enabled={tool_call_enabled})")
# Add user message
@ -56,13 +63,17 @@ class BaseAgent(ABC):
tools = self.tool_manager.get_tool_definitions()
self.logger.debug(f"Tools available: {tools}")
# Submit to OpenAI
# Build parameter dict and include reasoning_effort only if not None
params = {
"model": self.model_name,
"messages": self.messages.get_messages(),
"tools": tools
}
if final_reasoning_effort is not None:
params["reasoning_effort"] = final_reasoning_effort
self.logger.debug("Sending request to language model interface...")
response = self.language_model_interface.generate_completion(
model=self.model_name,
messages=self.messages.get_messages(),
tools=tools,
)
response = self.language_model_interface.generate_completion(**params)
tool_calls = response.choices[0].message.tool_calls
if tool_call_enabled and self.tool_manager and tool_calls:
@ -71,7 +82,8 @@ class BaseAgent(ABC):
response,
return_tool_response_as_is,
self.messages,
self.model_name
self.model_name,
reasoning_effort=final_reasoning_effort
)
# No tool call, normal assistant response
@ -86,10 +98,12 @@ class BaseAgent(ABC):
- The developer prompt
- The model name
- The tool definitions (function schemas)
- The default reasoning effort if set
"""
signature_obj = AgentSignature(
developer_prompt=self.developer_prompt,
model_name=self.model_name,
tool_manager=self.tool_manager
tool_manager=self.tool_manager,
reasoning_effort=self.reasoning_effort
)
return signature_obj.to_dict()

View File

@ -1,7 +1,7 @@
# object_oriented_agents/core_classes/tool_manager.py
import json
from typing import Dict, Any, List
from typing import Dict, Any, List, Optional
from .chat_messages import ChatMessages
from .tool_interface import ToolInterface
from ..utils.logger import get_logger
@ -16,7 +16,6 @@ class ToolManager:
- Handle the entire tool call sequence
"""
def __init__(self, logger=None, language_model_interface: LanguageModelInterface = None):
self.tools = {}
self.logger = logger or get_logger(self.__class__.__name__)
@ -47,7 +46,8 @@ class ToolManager:
response,
return_tool_response_as_is: bool,
messages: ChatMessages,
model_name: str
model_name: str,
reasoning_effort: Optional[str] = None
) -> str:
"""
If the model wants to call a tool, parse the function arguments, invoke the tool,
@ -90,11 +90,15 @@ class ToolManager:
complete_payload.append(function_call_result_message)
self.logger.debug("Calling the model again with the tool response to get the final answer.")
# Use the injected openai_client here
response_after_tool_call = self.language_model_interface.generate_completion(
model=model_name,
messages=complete_payload
)
# Build parameter dict and only include reasoning_effort if not None
params = {
"model": model_name,
"messages": complete_payload
}
if reasoning_effort is not None:
params["reasoning_effort"] = reasoning_effort
response_after_tool_call = self.language_model_interface.generate_completion(**params)
final_message = response_after_tool_call.choices[0].message.content
self.logger.debug("Received final answer from model after tool call.")

View File

@ -15,14 +15,17 @@ class LanguageModelInterface(ABC):
self,
model: str,
messages: List[Dict[str, str]],
tools: Optional[List[Dict[str, Any]]] = None
tools: Optional[List[Dict[str, Any]]] = None,
reasoning_effort: Optional[str] = None
) -> Dict[str, Any]:
"""
Generate a completion (response) from the language model given a set of messages and optional tool definitions.
Generate a completion (response) from the language model given a set of messages, optional tool definitions,
and an optional reasoning effort parameter.
:param model: The name of the model to call.
:param messages: A list of messages, where each message is a dict with keys 'role' and 'content'.
:param tools: Optional list of tool definitions.
:param reasoning_effort: Optional parameter to indicate additional reasoning effort.
:return: A dictionary representing the model's response. The shape of this dict follows the provider's format.
"""
pass

View File

@ -19,10 +19,11 @@ class OpenAILanguageModel(LanguageModelInterface):
self,
model: str,
messages: List[Dict[str, str]],
tools: Optional[List[Dict[str, Any]]] = None
tools: Optional[List[Dict[str, Any]]] = None,
reasoning_effort: Optional[str] = None
) -> Dict[str, Any]:
"""
Calls the OpenAI API to generate a chat completion using the provided messages and tools.
Calls the OpenAI API to generate a chat completion using the provided messages, tools, and optional reasoning_effort.
"""
kwargs = {
"model": model,
@ -34,6 +35,10 @@ class OpenAILanguageModel(LanguageModelInterface):
# Adjust this as necessary if the API format changes.
kwargs["tools"] = tools
# Append reasoning_effort to kwargs if provided
if reasoning_effort is not None:
kwargs["reasoning_effort"] = reasoning_effort
self.logger.debug("Generating completion with OpenAI model.")
self.logger.debug(f"Request: {kwargs}")
try:

View File

@ -16,6 +16,7 @@ myapp_logger = get_logger("MyApp", level=logging.INFO)
# Create a LanguageModelInterface instance using the OpenAILanguageModel
language_model_api_interface = OpenAILanguageModel(api_key=os.getenv("OPENAI_API_KEY"), logger=myapp_logger)
class PythonExecAgent(BaseAgent):
"""
An agent specialized in executing Python code in a Docker container.
@ -33,17 +34,18 @@ class PythonExecAgent(BaseAgent):
3. Generate Python code to analyze the data and call the tool `execute_python_code` to run the code and get results.
4. You can use Python libraries pandas, numpy, matplotlib, seaborn, and scikit-learn.
5. Interpret the results of the code execution and provide analysis to the user.
""",
model_name: str = "o3-mini",
logger=myapp_logger,
language_model_interface = language_model_api_interface
):
language_model_interface=language_model_api_interface,
reasoning_effort: str = None # optional; if provided, passed to API calls
):
super().__init__(
developer_prompt=developer_prompt,
model_name=model_name,
logger=logger,
language_model_interface=language_model_interface
language_model_interface=language_model_interface,
reasoning_effort=reasoning_effort
)
self.setup_tools()
@ -52,9 +54,9 @@ class PythonExecAgent(BaseAgent):
Create a ToolManager, instantiate the PythonExecTool and register it with the ToolManager.
"""
self.tool_manager = ToolManager(logger=self.logger, language_model_interface=self.language_model_interface)
# Create the Python execution tool
python_exec_tool = PythonExecTool()
# Register the Python execution tool
self.tool_manager.register_tool(python_exec_tool)

View File

@ -1798,9 +1798,9 @@
- usage-api
- cost-api
- title: Build Your Own Code Interpreter - Empowering LLM Agents with Dynamic Tool Calling
- title: Build Your Own Code Interpreter - Dynamic Tool Generation and Execution With o3-mini
path: examples/object_oriented_agentic_approach/Secure_code_interpreter_tool_for_LLM_agents.ipynb
date: 2025-01-26
date: 2025-02-03
authors:
- msingh-openai
tags: