We are going to create an AI agent which can perform timezone conversion with tools / function calling. Only openai
library is used.
Full source code will be given at the end.
Set up
We only need to install openai
library.
pip <span>install </span>openaipip <span>install </span>openaipip install openai
Enter fullscreen mode Exit fullscreen mode
Define tools
We will define 2 tools. One is to get today’s date and the other is to convert the timezone.
We also define tool_map
which stores the details about the tools. The key of the map is the function name. prompt
is the details we will send to LLM and function
is the function we will call.
If your tools perform sensitive operations, you should verify or sanitize the parameters first.
<span>def</span> <span>get_today_date</span><span>(</span><span>timezone</span><span>):</span><span>return</span> <span>datetime</span><span>.</span><span>datetime</span><span>.</span><span>now</span><span>(</span><span>ZoneInfo</span><span>(</span><span>timezone</span><span>)).</span><span>strftime</span><span>(</span><span>"</span><span>%Y-%m-%d</span><span>"</span><span>)</span><span>def</span> <span>convert_timezone</span><span>(</span><span>source_timezone</span><span>,</span> <span>target_timezone</span><span>,</span> <span>year</span><span>,</span> <span>month</span><span>,</span> <span>day</span><span>,</span> <span>hour</span><span>,</span> <span>minute</span><span>):</span><span>dt</span> <span>=</span> <span>datetime</span><span>.</span><span>datetime</span><span>(</span><span>year</span><span>,</span> <span>month</span><span>,</span> <span>day</span><span>,</span> <span>hour</span><span>,</span> <span>minute</span><span>,</span> <span>tzinfo</span><span>=</span><span>ZoneInfo</span><span>(</span><span>source_timezone</span><span>))</span><span>return</span> <span>dt</span><span>.</span><span>astimezone</span><span>(</span><span>ZoneInfo</span><span>(</span><span>target_timezone</span><span>))</span><span>tool_map</span> <span>=</span> <span>{</span><span>"</span><span>get_today_date</span><span>"</span><span>:</span> <span>{</span><span>"</span><span>prompt</span><span>"</span><span>:</span> <span>"""</span><span>get_today_date(timezone) e.g. get_today_date(</span><span>"</span><span>Asia/Tokyo</span><span>"</span><span>) Description: Get the date of today. </span><span>"""</span><span>,</span><span>"</span><span>function</span><span>"</span><span>:</span> <span>get_today_date</span><span>,</span><span>},</span><span>"</span><span>convert_timezone</span><span>"</span><span>:</span> <span>{</span><span>"</span><span>prompt</span><span>"</span><span>:</span> <span>"""</span><span>convert_timezone(source_timezone, target_timezone, year, month, day, hour, minute) e.g. convert_timezone(</span><span>"</span><span>Asia/Tokyo</span><span>"</span><span>, </span><span>"</span><span>Europe/London</span><span>"</span><span> 2025, 2, 15, 13, 0) Description: Convert time from source timezone to target timezone </span><span>"""</span><span>,</span><span>"</span><span>function</span><span>"</span><span>:</span> <span>convert_timezone</span><span>}</span><span>}</span><span>def</span> <span>get_today_date</span><span>(</span><span>timezone</span><span>):</span> <span>return</span> <span>datetime</span><span>.</span><span>datetime</span><span>.</span><span>now</span><span>(</span><span>ZoneInfo</span><span>(</span><span>timezone</span><span>)).</span><span>strftime</span><span>(</span><span>"</span><span>%Y-%m-%d</span><span>"</span><span>)</span> <span>def</span> <span>convert_timezone</span><span>(</span><span>source_timezone</span><span>,</span> <span>target_timezone</span><span>,</span> <span>year</span><span>,</span> <span>month</span><span>,</span> <span>day</span><span>,</span> <span>hour</span><span>,</span> <span>minute</span><span>):</span> <span>dt</span> <span>=</span> <span>datetime</span><span>.</span><span>datetime</span><span>(</span><span>year</span><span>,</span> <span>month</span><span>,</span> <span>day</span><span>,</span> <span>hour</span><span>,</span> <span>minute</span><span>,</span> <span>tzinfo</span><span>=</span><span>ZoneInfo</span><span>(</span><span>source_timezone</span><span>))</span> <span>return</span> <span>dt</span><span>.</span><span>astimezone</span><span>(</span><span>ZoneInfo</span><span>(</span><span>target_timezone</span><span>))</span> <span>tool_map</span> <span>=</span> <span>{</span> <span>"</span><span>get_today_date</span><span>"</span><span>:</span> <span>{</span> <span>"</span><span>prompt</span><span>"</span><span>:</span> <span>"""</span><span>get_today_date(timezone) e.g. get_today_date(</span><span>"</span><span>Asia/Tokyo</span><span>"</span><span>) Description: Get the date of today. </span><span>"""</span><span>,</span> <span>"</span><span>function</span><span>"</span><span>:</span> <span>get_today_date</span><span>,</span> <span>},</span> <span>"</span><span>convert_timezone</span><span>"</span><span>:</span> <span>{</span> <span>"</span><span>prompt</span><span>"</span><span>:</span> <span>"""</span><span>convert_timezone(source_timezone, target_timezone, year, month, day, hour, minute) e.g. convert_timezone(</span><span>"</span><span>Asia/Tokyo</span><span>"</span><span>, </span><span>"</span><span>Europe/London</span><span>"</span><span> 2025, 2, 15, 13, 0) Description: Convert time from source timezone to target timezone </span><span>"""</span><span>,</span> <span>"</span><span>function</span><span>"</span><span>:</span> <span>convert_timezone</span> <span>}</span> <span>}</span>def get_today_date(timezone): return datetime.datetime.now(ZoneInfo(timezone)).strftime("%Y-%m-%d") def convert_timezone(source_timezone, target_timezone, year, month, day, hour, minute): dt = datetime.datetime(year, month, day, hour, minute, tzinfo=ZoneInfo(source_timezone)) return dt.astimezone(ZoneInfo(target_timezone)) tool_map = { "get_today_date": { "prompt": """get_today_date(timezone) e.g. get_today_date("Asia/Tokyo") Description: Get the date of today. """, "function": get_today_date, }, "convert_timezone": { "prompt": """convert_timezone(source_timezone, target_timezone, year, month, day, hour, minute) e.g. convert_timezone("Asia/Tokyo", "Europe/London" 2025, 2, 15, 13, 0) Description: Convert time from source timezone to target timezone """, "function": convert_timezone } }
Enter fullscreen mode Exit fullscreen mode
Define system prompt
We apply “ReAct Prompting” to enable act and reasoning abilities. This also allows us to use tools.
In order to make LLM stop generating after proposing an action, we ask it to output “PAUSE” text after an action.
<span>system_prompt</span> <span>=</span> <span>f</span><span>"""</span><span>Answer the following questions as best you can. You have access to the following tools: </span><span>{</span><span>"</span><span>\n</span><span>"</span><span>.</span><span>join</span><span>([</span><span>tool</span><span>[</span><span>"</span><span>prompt</span><span>"</span><span>]</span> <span>for</span> <span>tool</span> <span>in</span> <span>tool_map</span><span>.</span><span>values</span><span>()])</span><span>}</span><span> If you need to use the tool, you MUST return PAUSE!!!! This is very IMPORTANT. Use the following format: Question: the input question you must answer Thought: you should always think about what to do Action: the action to take, should be one of [</span><span>{</span><span>"</span><span>, </span><span>"</span><span>.</span><span>join</span><span>(</span><span>tool_map</span><span>.</span><span>keys</span><span>())</span><span>}</span><span>]. This ONLY includes the name of the tool. Action Input: the input to the action. This ONLY includes the parameters of the tool. Example: Action Input: a, </span><span>"</span><span>b</span><span>"</span><span>, c PAUSE Observation: the result of the action Thought: I now know the final answer Final Answer: the final answer to the original input question Begin!</span><span>"""</span><span>system_prompt</span> <span>=</span> <span>f</span><span>"""</span><span>Answer the following questions as best you can. You have access to the following tools: </span><span>{</span><span>"</span><span>\n</span><span>"</span><span>.</span><span>join</span><span>([</span><span>tool</span><span>[</span><span>"</span><span>prompt</span><span>"</span><span>]</span> <span>for</span> <span>tool</span> <span>in</span> <span>tool_map</span><span>.</span><span>values</span><span>()])</span><span>}</span><span> If you need to use the tool, you MUST return PAUSE!!!! This is very IMPORTANT. Use the following format: Question: the input question you must answer Thought: you should always think about what to do Action: the action to take, should be one of [</span><span>{</span><span>"</span><span>, </span><span>"</span><span>.</span><span>join</span><span>(</span><span>tool_map</span><span>.</span><span>keys</span><span>())</span><span>}</span><span>]. This ONLY includes the name of the tool. Action Input: the input to the action. This ONLY includes the parameters of the tool. Example: Action Input: a, </span><span>"</span><span>b</span><span>"</span><span>, c PAUSE Observation: the result of the action Thought: I now know the final answer Final Answer: the final answer to the original input question Begin!</span><span>"""</span>system_prompt = f"""Answer the following questions as best you can. You have access to the following tools: {"\n".join([tool["prompt"] for tool in tool_map.values()])} If you need to use the tool, you MUST return PAUSE!!!! This is very IMPORTANT. Use the following format: Question: the input question you must answer Thought: you should always think about what to do Action: the action to take, should be one of [{", ".join(tool_map.keys())}]. This ONLY includes the name of the tool. Action Input: the input to the action. This ONLY includes the parameters of the tool. Example: Action Input: a, "b", c PAUSE Observation: the result of the action Thought: I now know the final answer Final Answer: the final answer to the original input question Begin!"""
Enter fullscreen mode Exit fullscreen mode
Pseudocode of AI agent
Before we see the actual code of AI agent, we check the pseudocode first.
We have a loop to keep sending messages to LLM and performing actions.
messages = [system_prompt, question_prompt]completion = chat(llm, messages)add completion to messages with role 'assistant'while 'Final Answer' is not in completion and maximum round is not reached:If 'Action' is not found in completion:continueaction = parse_action(completion)If 'Action Input' is not in completion:continueaction_input = parse_action_input(completion)result = action(acion_input)add result to messages with role 'assistant'completion = chat(llm, messages)add completion to messages with role 'assistant'messages = [system_prompt, question_prompt] completion = chat(llm, messages) add completion to messages with role 'assistant' while 'Final Answer' is not in completion and maximum round is not reached: If 'Action' is not found in completion: continue action = parse_action(completion) If 'Action Input' is not in completion: continue action_input = parse_action_input(completion) result = action(acion_input) add result to messages with role 'assistant' completion = chat(llm, messages) add completion to messages with role 'assistant'messages = [system_prompt, question_prompt] completion = chat(llm, messages) add completion to messages with role 'assistant' while 'Final Answer' is not in completion and maximum round is not reached: If 'Action' is not found in completion: continue action = parse_action(completion) If 'Action Input' is not in completion: continue action_input = parse_action_input(completion) result = action(acion_input) add result to messages with role 'assistant' completion = chat(llm, messages) add completion to messages with role 'assistant'
Enter fullscreen mode Exit fullscreen mode
chat
function
chat
function is straight forward. It only creates chat completion with the messages we have.
Stop word “PAUSE” is used to make LLM stop generation after proposing an action.
<span>def</span> <span>chat</span><span>(</span><span>client</span><span>,</span> <span>messages</span><span>)</span> <span>-></span> <span>str</span><span>:</span><span>completion</span> <span>=</span> <span>client</span><span>.</span><span>chat</span><span>.</span><span>completions</span><span>.</span><span>create</span><span>(</span><span>messages</span><span>=</span><span>messages</span><span>,</span> <span>model</span><span>=</span><span>"</span><span>gpt-4o</span><span>"</span><span>,</span> <span>stop</span><span>=</span><span>"</span><span>PAUSE</span><span>"</span><span>)</span><span>completion_content</span> <span>=</span> <span>completion</span><span>.</span><span>choices</span><span>[</span><span>0</span><span>].</span><span>message</span><span>.</span><span>content</span><span>print</span><span>(</span><span>"</span><span>Chat completion:</span><span>"</span><span>)</span><span>print</span><span>(</span><span>completion_content</span><span>)</span><span>return</span> <span>completion_content</span><span>def</span> <span>chat</span><span>(</span><span>client</span><span>,</span> <span>messages</span><span>)</span> <span>-></span> <span>str</span><span>:</span> <span>completion</span> <span>=</span> <span>client</span><span>.</span><span>chat</span><span>.</span><span>completions</span><span>.</span><span>create</span><span>(</span><span>messages</span><span>=</span><span>messages</span><span>,</span> <span>model</span><span>=</span><span>"</span><span>gpt-4o</span><span>"</span><span>,</span> <span>stop</span><span>=</span><span>"</span><span>PAUSE</span><span>"</span><span>)</span> <span>completion_content</span> <span>=</span> <span>completion</span><span>.</span><span>choices</span><span>[</span><span>0</span><span>].</span><span>message</span><span>.</span><span>content</span> <span>print</span><span>(</span><span>"</span><span>Chat completion:</span><span>"</span><span>)</span> <span>print</span><span>(</span><span>completion_content</span><span>)</span> <span>return</span> <span>completion_content</span>def chat(client, messages) -> str: completion = client.chat.completions.create(messages=messages, model="gpt-4o", stop="PAUSE") completion_content = completion.choices[0].message.content print("Chat completion:") print(completion_content) return completion_content
Enter fullscreen mode Exit fullscreen mode
parse_action
function
We use regular expression to extract tool function name. Tool function will be returned. We also make sure tool function is defined in tool_map
for security reason.
You can also change the system prompt to ask LLM returning JSON to ease parsing.
<span>def</span> <span>parse_action</span><span>(</span><span>completion_content</span><span>:</span> <span>str</span><span>):</span><span>action_pattern</span> <span>=</span> <span>r</span><span>"</span><span>Action: ([^\n]*)</span><span>"</span><span>match</span> <span>=</span> <span>re</span><span>.</span><span>search</span><span>(</span><span>action_pattern</span><span>,</span> <span>completion_content</span><span>)</span><span>if</span> <span>not</span> <span>match</span><span>:</span><span>return</span> <span>None</span><span>tool_name</span> <span>=</span> <span>match</span><span>.</span><span>group</span><span>(</span><span>1</span><span>)</span><span>if</span> <span>tool_name</span> <span>not</span> <span>in</span> <span>tool_map</span><span>:</span><span>raise</span> <span>ValueError</span><span>(</span><span>f</span><span>"</span><span>Tool </span><span>'</span><span>{</span><span>tool_name</span><span>}</span><span>'</span><span> does not exist</span><span>"</span><span>)</span><span>return</span> <span>tool_map</span><span>[</span><span>tool_name</span><span>]</span><span>def</span> <span>parse_action</span><span>(</span><span>completion_content</span><span>:</span> <span>str</span><span>):</span> <span>action_pattern</span> <span>=</span> <span>r</span><span>"</span><span>Action: ([^\n]*)</span><span>"</span> <span>match</span> <span>=</span> <span>re</span><span>.</span><span>search</span><span>(</span><span>action_pattern</span><span>,</span> <span>completion_content</span><span>)</span> <span>if</span> <span>not</span> <span>match</span><span>:</span> <span>return</span> <span>None</span> <span>tool_name</span> <span>=</span> <span>match</span><span>.</span><span>group</span><span>(</span><span>1</span><span>)</span> <span>if</span> <span>tool_name</span> <span>not</span> <span>in</span> <span>tool_map</span><span>:</span> <span>raise</span> <span>ValueError</span><span>(</span><span>f</span><span>"</span><span>Tool </span><span>'</span><span>{</span><span>tool_name</span><span>}</span><span>'</span><span> does not exist</span><span>"</span><span>)</span> <span>return</span> <span>tool_map</span><span>[</span><span>tool_name</span><span>]</span>def parse_action(completion_content: str): action_pattern = r"Action: ([^\n]*)" match = re.search(action_pattern, completion_content) if not match: return None tool_name = match.group(1) if tool_name not in tool_map: raise ValueError(f"Tool '{tool_name}' does not exist") return tool_map[tool_name]
Enter fullscreen mode Exit fullscreen mode
parse_action_input
function
As same as parse_action
, we use regular expression to extract parameters of tool.
<span>def</span> <span>parse_action_input</span><span>(</span><span>completion_content</span><span>:</span> <span>str</span><span>):</span><span>action_input_pattern</span> <span>=</span> <span>r</span><span>"</span><span>Action Input: ([^\n]*)</span><span>"</span><span>match</span> <span>=</span> <span>re</span><span>.</span><span>search</span><span>(</span><span>action_input_pattern</span><span>,</span> <span>completion_content</span><span>)</span><span>if</span> <span>not</span> <span>match</span><span>:</span><span>return</span> <span>None</span><span>args_string</span> <span>=</span> <span>match</span><span>.</span><span>group</span><span>(</span><span>1</span><span>)</span><span>return</span> <span>eval</span><span>(</span><span>f</span><span>"</span><span>(</span><span>{</span><span>args_string</span><span>}</span><span>,)</span><span>"</span><span>)</span><span>def</span> <span>parse_action_input</span><span>(</span><span>completion_content</span><span>:</span> <span>str</span><span>):</span> <span>action_input_pattern</span> <span>=</span> <span>r</span><span>"</span><span>Action Input: ([^\n]*)</span><span>"</span> <span>match</span> <span>=</span> <span>re</span><span>.</span><span>search</span><span>(</span><span>action_input_pattern</span><span>,</span> <span>completion_content</span><span>)</span> <span>if</span> <span>not</span> <span>match</span><span>:</span> <span>return</span> <span>None</span> <span>args_string</span> <span>=</span> <span>match</span><span>.</span><span>group</span><span>(</span><span>1</span><span>)</span> <span>return</span> <span>eval</span><span>(</span><span>f</span><span>"</span><span>(</span><span>{</span><span>args_string</span><span>}</span><span>,)</span><span>"</span><span>)</span>def parse_action_input(completion_content: str): action_input_pattern = r"Action Input: ([^\n]*)" match = re.search(action_input_pattern, completion_content) if not match: return None args_string = match.group(1) return eval(f"({args_string},)")
Enter fullscreen mode Exit fullscreen mode
AI agent main logic
Here is the implementaiton of the above pseudocode.
<span>def</span> <span>main</span><span>():</span><span>client</span> <span>=</span> <span>OpenAI</span><span>(</span><span>api_key</span><span>=</span><span>os</span><span>.</span><span>environ</span><span>.</span><span>get</span><span>(</span><span>"</span><span>OPENAI_API_KEY</span><span>"</span><span>))</span><span>question</span> <span>=</span> <span>"</span><span>Convert 13:49 today in London time to Japan time. Please consider daylight saving.</span><span>"</span><span>print</span><span>(</span><span>f</span><span>"</span><span>Question: </span><span>{</span><span>question</span><span>}</span><span>"</span><span>)</span><span>messages</span> <span>=</span> <span>[{</span><span>"</span><span>role</span><span>"</span><span>:</span> <span>"</span><span>system</span><span>"</span><span>,</span> <span>"</span><span>content</span><span>"</span><span>:</span> <span>system_prompt</span><span>},</span> <span>{</span><span>"</span><span>role</span><span>"</span><span>:</span> <span>"</span><span>user</span><span>"</span><span>,</span> <span>"</span><span>content</span><span>"</span><span>:</span> <span>f</span><span>"</span><span>Question: </span><span>{</span><span>question</span><span>}</span><span>"</span><span>}]</span><span>completion_content</span> <span>=</span> <span>chat</span><span>(</span><span>client</span><span>,</span> <span>messages</span><span>)</span><span>messages</span><span>.</span><span>append</span><span>({</span><span>"</span><span>role</span><span>"</span><span>:</span> <span>"</span><span>assistant</span><span>"</span><span>,</span> <span>"</span><span>content</span><span>"</span><span>:</span> <span>completion_content</span><span>})</span><span>current_round</span> <span>=</span> <span>0</span><span>max_round</span> <span>=</span> <span>5</span><span>while</span> <span>"</span><span>Answer</span><span>"</span> <span>not</span> <span>in</span> <span>completion_content</span> <span>and</span> <span>current_round</span> <span><</span> <span>max_round</span><span>:</span><span>current_round</span> <span>+=</span> <span>1</span><span>action</span> <span>=</span> <span>parse_action</span><span>(</span><span>completion_content</span><span>)</span><span>if</span> <span>action</span> <span>is</span> <span>None</span><span>:</span><span>continue</span><span>action_input</span> <span>=</span> <span>parse_action_input</span><span>(</span><span>completion_content</span><span>)</span><span>if</span> <span>action_input</span> <span>is</span> <span>None</span><span>:</span><span>continue</span><span>action_result</span> <span>=</span> <span>action</span><span>[</span><span>"</span><span>function</span><span>"</span><span>](</span><span>*</span><span>action_input</span><span>)</span><span>print</span><span>(</span><span>f</span><span>"</span><span>Action result: </span><span>{</span><span>action_result</span><span>}</span><span>"</span><span>)</span><span>messages</span><span>.</span><span>append</span><span>({</span><span>"</span><span>role</span><span>"</span><span>:</span> <span>"</span><span>assistant</span><span>"</span><span>,</span> <span>"</span><span>content</span><span>"</span><span>:</span> <span>f</span><span>"</span><span>Observation: </span><span>{</span><span>action_result</span><span>}</span><span>"</span><span>})</span><span>completion_content</span> <span>=</span> <span>chat</span><span>(</span><span>client</span><span>,</span> <span>messages</span><span>)</span><span>messages</span><span>.</span><span>append</span><span>({</span><span>"</span><span>role</span><span>"</span><span>:</span> <span>"</span><span>assistant</span><span>"</span><span>,</span> <span>"</span><span>content</span><span>"</span><span>:</span> <span>completion_content</span><span>})</span><span>if</span> <span>__name__</span> <span>==</span> <span>'</span><span>__main__</span><span>'</span><span>:</span><span>main</span><span>()</span><span>def</span> <span>main</span><span>():</span> <span>client</span> <span>=</span> <span>OpenAI</span><span>(</span><span>api_key</span><span>=</span><span>os</span><span>.</span><span>environ</span><span>.</span><span>get</span><span>(</span><span>"</span><span>OPENAI_API_KEY</span><span>"</span><span>))</span> <span>question</span> <span>=</span> <span>"</span><span>Convert 13:49 today in London time to Japan time. Please consider daylight saving.</span><span>"</span> <span>print</span><span>(</span><span>f</span><span>"</span><span>Question: </span><span>{</span><span>question</span><span>}</span><span>"</span><span>)</span> <span>messages</span> <span>=</span> <span>[{</span><span>"</span><span>role</span><span>"</span><span>:</span> <span>"</span><span>system</span><span>"</span><span>,</span> <span>"</span><span>content</span><span>"</span><span>:</span> <span>system_prompt</span><span>},</span> <span>{</span><span>"</span><span>role</span><span>"</span><span>:</span> <span>"</span><span>user</span><span>"</span><span>,</span> <span>"</span><span>content</span><span>"</span><span>:</span> <span>f</span><span>"</span><span>Question: </span><span>{</span><span>question</span><span>}</span><span>"</span><span>}]</span> <span>completion_content</span> <span>=</span> <span>chat</span><span>(</span><span>client</span><span>,</span> <span>messages</span><span>)</span> <span>messages</span><span>.</span><span>append</span><span>({</span><span>"</span><span>role</span><span>"</span><span>:</span> <span>"</span><span>assistant</span><span>"</span><span>,</span> <span>"</span><span>content</span><span>"</span><span>:</span> <span>completion_content</span><span>})</span> <span>current_round</span> <span>=</span> <span>0</span> <span>max_round</span> <span>=</span> <span>5</span> <span>while</span> <span>"</span><span>Answer</span><span>"</span> <span>not</span> <span>in</span> <span>completion_content</span> <span>and</span> <span>current_round</span> <span><</span> <span>max_round</span><span>:</span> <span>current_round</span> <span>+=</span> <span>1</span> <span>action</span> <span>=</span> <span>parse_action</span><span>(</span><span>completion_content</span><span>)</span> <span>if</span> <span>action</span> <span>is</span> <span>None</span><span>:</span> <span>continue</span> <span>action_input</span> <span>=</span> <span>parse_action_input</span><span>(</span><span>completion_content</span><span>)</span> <span>if</span> <span>action_input</span> <span>is</span> <span>None</span><span>:</span> <span>continue</span> <span>action_result</span> <span>=</span> <span>action</span><span>[</span><span>"</span><span>function</span><span>"</span><span>](</span><span>*</span><span>action_input</span><span>)</span> <span>print</span><span>(</span><span>f</span><span>"</span><span>Action result: </span><span>{</span><span>action_result</span><span>}</span><span>"</span><span>)</span> <span>messages</span><span>.</span><span>append</span><span>({</span><span>"</span><span>role</span><span>"</span><span>:</span> <span>"</span><span>assistant</span><span>"</span><span>,</span> <span>"</span><span>content</span><span>"</span><span>:</span> <span>f</span><span>"</span><span>Observation: </span><span>{</span><span>action_result</span><span>}</span><span>"</span><span>})</span> <span>completion_content</span> <span>=</span> <span>chat</span><span>(</span><span>client</span><span>,</span> <span>messages</span><span>)</span> <span>messages</span><span>.</span><span>append</span><span>({</span><span>"</span><span>role</span><span>"</span><span>:</span> <span>"</span><span>assistant</span><span>"</span><span>,</span> <span>"</span><span>content</span><span>"</span><span>:</span> <span>completion_content</span><span>})</span> <span>if</span> <span>__name__</span> <span>==</span> <span>'</span><span>__main__</span><span>'</span><span>:</span> <span>main</span><span>()</span>def main(): client = OpenAI(api_key=os.environ.get("OPENAI_API_KEY")) question = "Convert 13:49 today in London time to Japan time. Please consider daylight saving." print(f"Question: {question}") messages = [{"role": "system", "content": system_prompt}, {"role": "user", "content": f"Question: {question}"}] completion_content = chat(client, messages) messages.append({"role": "assistant", "content": completion_content}) current_round = 0 max_round = 5 while "Answer" not in completion_content and current_round < max_round: current_round += 1 action = parse_action(completion_content) if action is None: continue action_input = parse_action_input(completion_content) if action_input is None: continue action_result = action["function"](*action_input) print(f"Action result: {action_result}") messages.append({"role": "assistant", "content": f"Observation: {action_result}"}) completion_content = chat(client, messages) messages.append({"role": "assistant", "content": completion_content}) if __name__ == '__main__': main()
Enter fullscreen mode Exit fullscreen mode
Sample result
Question: Convert 13:49 today in London time to Japan time. Please consider daylight saving.Chat completion:Thought: To accurately convert 13:49 London time to Japan time, it's important to consider the current date and whether daylight saving time is in effect. I'll first fetch the current date in the "Europe/London" timezone to understand if daylight saving time needs to be taken into account.Action: get_today_dateAction Input: "Europe/London"Action result: 2025-02-23Chat completion:Thought: Today is February 23, 2025. Daylight saving time in London typically starts on the last Sunday in March and ends on the last Sunday in October. Therefore, currently, London is on Greenwich Mean Time (GMT, UTC+0). Japan does not observe daylight saving time and is always on Japan Standard Time (JST, UTC+9). I will now convert 13:49 London time to Japan time for today.Action: convert_timezoneAction Input: "Europe/London", "Asia/Tokyo", 2025, 2, 23, 13, 49Action result: 2025-02-23 22:49:00+09:00Chat completion:Thought: I have successfully converted 13:49 London time to Japan time. The converted time is 22:49 on February 23, 2025.Final Answer: 13:49 in London on February 23, 2025, is 22:49 in Japan time.Question: Convert 13:49 today in London time to Japan time. Please consider daylight saving. Chat completion: Thought: To accurately convert 13:49 London time to Japan time, it's important to consider the current date and whether daylight saving time is in effect. I'll first fetch the current date in the "Europe/London" timezone to understand if daylight saving time needs to be taken into account. Action: get_today_date Action Input: "Europe/London" Action result: 2025-02-23 Chat completion: Thought: Today is February 23, 2025. Daylight saving time in London typically starts on the last Sunday in March and ends on the last Sunday in October. Therefore, currently, London is on Greenwich Mean Time (GMT, UTC+0). Japan does not observe daylight saving time and is always on Japan Standard Time (JST, UTC+9). I will now convert 13:49 London time to Japan time for today. Action: convert_timezone Action Input: "Europe/London", "Asia/Tokyo", 2025, 2, 23, 13, 49 Action result: 2025-02-23 22:49:00+09:00 Chat completion: Thought: I have successfully converted 13:49 London time to Japan time. The converted time is 22:49 on February 23, 2025. Final Answer: 13:49 in London on February 23, 2025, is 22:49 in Japan time.Question: Convert 13:49 today in London time to Japan time. Please consider daylight saving. Chat completion: Thought: To accurately convert 13:49 London time to Japan time, it's important to consider the current date and whether daylight saving time is in effect. I'll first fetch the current date in the "Europe/London" timezone to understand if daylight saving time needs to be taken into account. Action: get_today_date Action Input: "Europe/London" Action result: 2025-02-23 Chat completion: Thought: Today is February 23, 2025. Daylight saving time in London typically starts on the last Sunday in March and ends on the last Sunday in October. Therefore, currently, London is on Greenwich Mean Time (GMT, UTC+0). Japan does not observe daylight saving time and is always on Japan Standard Time (JST, UTC+9). I will now convert 13:49 London time to Japan time for today. Action: convert_timezone Action Input: "Europe/London", "Asia/Tokyo", 2025, 2, 23, 13, 49 Action result: 2025-02-23 22:49:00+09:00 Chat completion: Thought: I have successfully converted 13:49 London time to Japan time. The converted time is 22:49 on February 23, 2025. Final Answer: 13:49 in London on February 23, 2025, is 22:49 in Japan time.
Enter fullscreen mode Exit fullscreen mode
Full source code
<span>import</span> <span>datetime</span><span>import</span> <span>os</span><span>import</span> <span>re</span><span>from</span> <span>zoneinfo</span> <span>import</span> <span>ZoneInfo</span><span>from</span> <span>openai</span> <span>import</span> <span>OpenAI</span><span>def</span> <span>get_today_date</span><span>(</span><span>timezone</span><span>):</span><span>return</span> <span>datetime</span><span>.</span><span>datetime</span><span>.</span><span>now</span><span>(</span><span>ZoneInfo</span><span>(</span><span>timezone</span><span>)).</span><span>strftime</span><span>(</span><span>"</span><span>%Y-%m-%d</span><span>"</span><span>)</span><span>def</span> <span>convert_timezone</span><span>(</span><span>source_timezone</span><span>,</span> <span>target_timezone</span><span>,</span> <span>year</span><span>,</span> <span>month</span><span>,</span> <span>day</span><span>,</span> <span>hour</span><span>,</span> <span>minute</span><span>):</span><span>dt</span> <span>=</span> <span>datetime</span><span>.</span><span>datetime</span><span>(</span><span>year</span><span>,</span> <span>month</span><span>,</span> <span>day</span><span>,</span> <span>hour</span><span>,</span> <span>minute</span><span>,</span> <span>tzinfo</span><span>=</span><span>ZoneInfo</span><span>(</span><span>source_timezone</span><span>))</span><span>return</span> <span>dt</span><span>.</span><span>astimezone</span><span>(</span><span>ZoneInfo</span><span>(</span><span>target_timezone</span><span>))</span><span>tool_map</span> <span>=</span> <span>{</span><span>"</span><span>get_today_date</span><span>"</span><span>:</span> <span>{</span><span>"</span><span>prompt</span><span>"</span><span>:</span> <span>"""</span><span>get_today_date(timezone) e.g. get_today_date(</span><span>"</span><span>Asia/Tokyo</span><span>"</span><span>) Description: Get the date of today. </span><span>"""</span><span>,</span><span>"</span><span>function</span><span>"</span><span>:</span> <span>get_today_date</span><span>,</span><span>},</span><span>"</span><span>convert_timezone</span><span>"</span><span>:</span> <span>{</span><span>"</span><span>prompt</span><span>"</span><span>:</span> <span>"""</span><span>convert_timezone(source_timezone, target_timezone, year, month, day, hour, minute) e.g. convert_timezone(</span><span>"</span><span>Asia/Tokyo</span><span>"</span><span>, </span><span>"</span><span>Europe/London</span><span>"</span><span> 2025, 2, 15, 13, 0) Description: Convert time from source timezone to target timezone </span><span>"""</span><span>,</span><span>"</span><span>function</span><span>"</span><span>:</span> <span>convert_timezone</span><span>}</span><span>}</span><span>system_prompt</span> <span>=</span> <span>f</span><span>"""</span><span>Answer the following questions as best you can. You have access to the following tools: </span><span>{</span><span>"</span><span>\n</span><span>"</span><span>.</span><span>join</span><span>([</span><span>tool</span><span>[</span><span>"</span><span>prompt</span><span>"</span><span>]</span> <span>for</span> <span>tool</span> <span>in</span> <span>tool_map</span><span>.</span><span>values</span><span>()])</span><span>}</span><span> If you need to use the tool, you MUST return PAUSE!!!! This is very IMPORTANT. Use the following format: Question: the input question you must answer Thought: you should always think about what to do Action: the action to take, should be one of [</span><span>{</span><span>"</span><span>, </span><span>"</span><span>.</span><span>join</span><span>(</span><span>tool_map</span><span>.</span><span>keys</span><span>())</span><span>}</span><span>]. This ONLY includes the name of the tool. Action Input: the input to the action. This ONLY includes the parameters of the tool. Example: Action Input: a, </span><span>"</span><span>b</span><span>"</span><span>, c PAUSE Observation: the result of the action Thought: I now know the final answer Final Answer: the final answer to the original input question Begin!</span><span>"""</span><span>def</span> <span>chat</span><span>(</span><span>client</span><span>,</span> <span>messages</span><span>)</span> <span>-></span> <span>str</span><span>:</span><span>completion</span> <span>=</span> <span>client</span><span>.</span><span>chat</span><span>.</span><span>completions</span><span>.</span><span>create</span><span>(</span><span>messages</span><span>=</span><span>messages</span><span>,</span> <span>model</span><span>=</span><span>"</span><span>gpt-4o</span><span>"</span><span>,</span> <span>stop</span><span>=</span><span>"</span><span>PAUSE</span><span>"</span><span>)</span><span>completion_content</span> <span>=</span> <span>completion</span><span>.</span><span>choices</span><span>[</span><span>0</span><span>].</span><span>message</span><span>.</span><span>content</span><span>print</span><span>(</span><span>"</span><span>Chat completion:</span><span>"</span><span>)</span><span>print</span><span>(</span><span>completion_content</span><span>)</span><span>return</span> <span>completion_content</span><span>def</span> <span>parse_action</span><span>(</span><span>completion_content</span><span>:</span> <span>str</span><span>):</span><span>action_pattern</span> <span>=</span> <span>r</span><span>"</span><span>Action: ([^\n]*)</span><span>"</span><span>match</span> <span>=</span> <span>re</span><span>.</span><span>search</span><span>(</span><span>action_pattern</span><span>,</span> <span>completion_content</span><span>)</span><span>if</span> <span>not</span> <span>match</span><span>:</span><span>return</span> <span>None</span><span>tool_name</span> <span>=</span> <span>match</span><span>.</span><span>group</span><span>(</span><span>1</span><span>)</span><span>if</span> <span>tool_name</span> <span>not</span> <span>in</span> <span>tool_map</span><span>:</span><span>raise</span> <span>ValueError</span><span>(</span><span>f</span><span>"</span><span>Tool </span><span>'</span><span>{</span><span>tool_name</span><span>}</span><span>'</span><span> does not exist</span><span>"</span><span>)</span><span>return</span> <span>tool_map</span><span>[</span><span>tool_name</span><span>]</span><span>def</span> <span>parse_action_input</span><span>(</span><span>completion_content</span><span>:</span> <span>str</span><span>):</span><span>action_input_pattern</span> <span>=</span> <span>r</span><span>"</span><span>Action Input: ([^\n]*)</span><span>"</span><span>match</span> <span>=</span> <span>re</span><span>.</span><span>search</span><span>(</span><span>action_input_pattern</span><span>,</span> <span>completion_content</span><span>)</span><span>if</span> <span>not</span> <span>match</span><span>:</span><span>return</span> <span>None</span><span>args_string</span> <span>=</span> <span>match</span><span>.</span><span>group</span><span>(</span><span>1</span><span>)</span><span>return</span> <span>eval</span><span>(</span><span>f</span><span>"</span><span>(</span><span>{</span><span>args_string</span><span>}</span><span>,)</span><span>"</span><span>)</span><span>def</span> <span>main</span><span>():</span><span>client</span> <span>=</span> <span>OpenAI</span><span>(</span><span>api_key</span><span>=</span><span>os</span><span>.</span><span>environ</span><span>.</span><span>get</span><span>(</span><span>"</span><span>OPENAI_API_KEY</span><span>"</span><span>))</span><span>question</span> <span>=</span> <span>"</span><span>Convert 13:49 today in London time to Japan time. Please consider daylight saving.</span><span>"</span><span>print</span><span>(</span><span>f</span><span>"</span><span>Question: </span><span>{</span><span>question</span><span>}</span><span>"</span><span>)</span><span>messages</span> <span>=</span> <span>[{</span><span>"</span><span>role</span><span>"</span><span>:</span> <span>"</span><span>system</span><span>"</span><span>,</span> <span>"</span><span>content</span><span>"</span><span>:</span> <span>system_prompt</span><span>},</span> <span>{</span><span>"</span><span>role</span><span>"</span><span>:</span> <span>"</span><span>user</span><span>"</span><span>,</span> <span>"</span><span>content</span><span>"</span><span>:</span> <span>f</span><span>"</span><span>Question: </span><span>{</span><span>question</span><span>}</span><span>"</span><span>}]</span><span>completion_content</span> <span>=</span> <span>chat</span><span>(</span><span>client</span><span>,</span> <span>messages</span><span>)</span><span>messages</span><span>.</span><span>append</span><span>({</span><span>"</span><span>role</span><span>"</span><span>:</span> <span>"</span><span>assistant</span><span>"</span><span>,</span> <span>"</span><span>content</span><span>"</span><span>:</span> <span>completion_content</span><span>})</span><span>current_round</span> <span>=</span> <span>0</span><span>max_round</span> <span>=</span> <span>5</span><span>while</span> <span>"</span><span>Final Answer</span><span>"</span> <span>not</span> <span>in</span> <span>completion_content</span> <span>and</span> <span>current_round</span> <span><</span> <span>max_round</span><span>:</span><span>current_round</span> <span>+=</span> <span>1</span><span>action</span> <span>=</span> <span>parse_action</span><span>(</span><span>completion_content</span><span>)</span><span>if</span> <span>action</span> <span>is</span> <span>None</span><span>:</span><span>continue</span><span>action_input</span> <span>=</span> <span>parse_action_input</span><span>(</span><span>completion_content</span><span>)</span><span>if</span> <span>action_input</span> <span>is</span> <span>None</span><span>:</span><span>continue</span><span>action_result</span> <span>=</span> <span>action</span><span>[</span><span>"</span><span>function</span><span>"</span><span>](</span><span>*</span><span>action_input</span><span>)</span><span>print</span><span>(</span><span>f</span><span>"</span><span>Action result: </span><span>{</span><span>action_result</span><span>}</span><span>"</span><span>)</span><span>messages</span><span>.</span><span>append</span><span>({</span><span>"</span><span>role</span><span>"</span><span>:</span> <span>"</span><span>assistant</span><span>"</span><span>,</span> <span>"</span><span>content</span><span>"</span><span>:</span> <span>f</span><span>"</span><span>Observation: </span><span>{</span><span>action_result</span><span>}</span><span>"</span><span>})</span><span>completion_content</span> <span>=</span> <span>chat</span><span>(</span><span>client</span><span>,</span> <span>messages</span><span>)</span><span>messages</span><span>.</span><span>append</span><span>({</span><span>"</span><span>role</span><span>"</span><span>:</span> <span>"</span><span>assistant</span><span>"</span><span>,</span> <span>"</span><span>content</span><span>"</span><span>:</span> <span>completion_content</span><span>})</span><span>if</span> <span>__name__</span> <span>==</span> <span>'</span><span>__main__</span><span>'</span><span>:</span><span>main</span><span>()</span><span>import</span> <span>datetime</span> <span>import</span> <span>os</span> <span>import</span> <span>re</span> <span>from</span> <span>zoneinfo</span> <span>import</span> <span>ZoneInfo</span> <span>from</span> <span>openai</span> <span>import</span> <span>OpenAI</span> <span>def</span> <span>get_today_date</span><span>(</span><span>timezone</span><span>):</span> <span>return</span> <span>datetime</span><span>.</span><span>datetime</span><span>.</span><span>now</span><span>(</span><span>ZoneInfo</span><span>(</span><span>timezone</span><span>)).</span><span>strftime</span><span>(</span><span>"</span><span>%Y-%m-%d</span><span>"</span><span>)</span> <span>def</span> <span>convert_timezone</span><span>(</span><span>source_timezone</span><span>,</span> <span>target_timezone</span><span>,</span> <span>year</span><span>,</span> <span>month</span><span>,</span> <span>day</span><span>,</span> <span>hour</span><span>,</span> <span>minute</span><span>):</span> <span>dt</span> <span>=</span> <span>datetime</span><span>.</span><span>datetime</span><span>(</span><span>year</span><span>,</span> <span>month</span><span>,</span> <span>day</span><span>,</span> <span>hour</span><span>,</span> <span>minute</span><span>,</span> <span>tzinfo</span><span>=</span><span>ZoneInfo</span><span>(</span><span>source_timezone</span><span>))</span> <span>return</span> <span>dt</span><span>.</span><span>astimezone</span><span>(</span><span>ZoneInfo</span><span>(</span><span>target_timezone</span><span>))</span> <span>tool_map</span> <span>=</span> <span>{</span> <span>"</span><span>get_today_date</span><span>"</span><span>:</span> <span>{</span> <span>"</span><span>prompt</span><span>"</span><span>:</span> <span>"""</span><span>get_today_date(timezone) e.g. get_today_date(</span><span>"</span><span>Asia/Tokyo</span><span>"</span><span>) Description: Get the date of today. </span><span>"""</span><span>,</span> <span>"</span><span>function</span><span>"</span><span>:</span> <span>get_today_date</span><span>,</span> <span>},</span> <span>"</span><span>convert_timezone</span><span>"</span><span>:</span> <span>{</span> <span>"</span><span>prompt</span><span>"</span><span>:</span> <span>"""</span><span>convert_timezone(source_timezone, target_timezone, year, month, day, hour, minute) e.g. convert_timezone(</span><span>"</span><span>Asia/Tokyo</span><span>"</span><span>, </span><span>"</span><span>Europe/London</span><span>"</span><span> 2025, 2, 15, 13, 0) Description: Convert time from source timezone to target timezone </span><span>"""</span><span>,</span> <span>"</span><span>function</span><span>"</span><span>:</span> <span>convert_timezone</span> <span>}</span> <span>}</span> <span>system_prompt</span> <span>=</span> <span>f</span><span>"""</span><span>Answer the following questions as best you can. You have access to the following tools: </span><span>{</span><span>"</span><span>\n</span><span>"</span><span>.</span><span>join</span><span>([</span><span>tool</span><span>[</span><span>"</span><span>prompt</span><span>"</span><span>]</span> <span>for</span> <span>tool</span> <span>in</span> <span>tool_map</span><span>.</span><span>values</span><span>()])</span><span>}</span><span> If you need to use the tool, you MUST return PAUSE!!!! This is very IMPORTANT. Use the following format: Question: the input question you must answer Thought: you should always think about what to do Action: the action to take, should be one of [</span><span>{</span><span>"</span><span>, </span><span>"</span><span>.</span><span>join</span><span>(</span><span>tool_map</span><span>.</span><span>keys</span><span>())</span><span>}</span><span>]. This ONLY includes the name of the tool. Action Input: the input to the action. This ONLY includes the parameters of the tool. Example: Action Input: a, </span><span>"</span><span>b</span><span>"</span><span>, c PAUSE Observation: the result of the action Thought: I now know the final answer Final Answer: the final answer to the original input question Begin!</span><span>"""</span> <span>def</span> <span>chat</span><span>(</span><span>client</span><span>,</span> <span>messages</span><span>)</span> <span>-></span> <span>str</span><span>:</span> <span>completion</span> <span>=</span> <span>client</span><span>.</span><span>chat</span><span>.</span><span>completions</span><span>.</span><span>create</span><span>(</span><span>messages</span><span>=</span><span>messages</span><span>,</span> <span>model</span><span>=</span><span>"</span><span>gpt-4o</span><span>"</span><span>,</span> <span>stop</span><span>=</span><span>"</span><span>PAUSE</span><span>"</span><span>)</span> <span>completion_content</span> <span>=</span> <span>completion</span><span>.</span><span>choices</span><span>[</span><span>0</span><span>].</span><span>message</span><span>.</span><span>content</span> <span>print</span><span>(</span><span>"</span><span>Chat completion:</span><span>"</span><span>)</span> <span>print</span><span>(</span><span>completion_content</span><span>)</span> <span>return</span> <span>completion_content</span> <span>def</span> <span>parse_action</span><span>(</span><span>completion_content</span><span>:</span> <span>str</span><span>):</span> <span>action_pattern</span> <span>=</span> <span>r</span><span>"</span><span>Action: ([^\n]*)</span><span>"</span> <span>match</span> <span>=</span> <span>re</span><span>.</span><span>search</span><span>(</span><span>action_pattern</span><span>,</span> <span>completion_content</span><span>)</span> <span>if</span> <span>not</span> <span>match</span><span>:</span> <span>return</span> <span>None</span> <span>tool_name</span> <span>=</span> <span>match</span><span>.</span><span>group</span><span>(</span><span>1</span><span>)</span> <span>if</span> <span>tool_name</span> <span>not</span> <span>in</span> <span>tool_map</span><span>:</span> <span>raise</span> <span>ValueError</span><span>(</span><span>f</span><span>"</span><span>Tool </span><span>'</span><span>{</span><span>tool_name</span><span>}</span><span>'</span><span> does not exist</span><span>"</span><span>)</span> <span>return</span> <span>tool_map</span><span>[</span><span>tool_name</span><span>]</span> <span>def</span> <span>parse_action_input</span><span>(</span><span>completion_content</span><span>:</span> <span>str</span><span>):</span> <span>action_input_pattern</span> <span>=</span> <span>r</span><span>"</span><span>Action Input: ([^\n]*)</span><span>"</span> <span>match</span> <span>=</span> <span>re</span><span>.</span><span>search</span><span>(</span><span>action_input_pattern</span><span>,</span> <span>completion_content</span><span>)</span> <span>if</span> <span>not</span> <span>match</span><span>:</span> <span>return</span> <span>None</span> <span>args_string</span> <span>=</span> <span>match</span><span>.</span><span>group</span><span>(</span><span>1</span><span>)</span> <span>return</span> <span>eval</span><span>(</span><span>f</span><span>"</span><span>(</span><span>{</span><span>args_string</span><span>}</span><span>,)</span><span>"</span><span>)</span> <span>def</span> <span>main</span><span>():</span> <span>client</span> <span>=</span> <span>OpenAI</span><span>(</span><span>api_key</span><span>=</span><span>os</span><span>.</span><span>environ</span><span>.</span><span>get</span><span>(</span><span>"</span><span>OPENAI_API_KEY</span><span>"</span><span>))</span> <span>question</span> <span>=</span> <span>"</span><span>Convert 13:49 today in London time to Japan time. Please consider daylight saving.</span><span>"</span> <span>print</span><span>(</span><span>f</span><span>"</span><span>Question: </span><span>{</span><span>question</span><span>}</span><span>"</span><span>)</span> <span>messages</span> <span>=</span> <span>[{</span><span>"</span><span>role</span><span>"</span><span>:</span> <span>"</span><span>system</span><span>"</span><span>,</span> <span>"</span><span>content</span><span>"</span><span>:</span> <span>system_prompt</span><span>},</span> <span>{</span><span>"</span><span>role</span><span>"</span><span>:</span> <span>"</span><span>user</span><span>"</span><span>,</span> <span>"</span><span>content</span><span>"</span><span>:</span> <span>f</span><span>"</span><span>Question: </span><span>{</span><span>question</span><span>}</span><span>"</span><span>}]</span> <span>completion_content</span> <span>=</span> <span>chat</span><span>(</span><span>client</span><span>,</span> <span>messages</span><span>)</span> <span>messages</span><span>.</span><span>append</span><span>({</span><span>"</span><span>role</span><span>"</span><span>:</span> <span>"</span><span>assistant</span><span>"</span><span>,</span> <span>"</span><span>content</span><span>"</span><span>:</span> <span>completion_content</span><span>})</span> <span>current_round</span> <span>=</span> <span>0</span> <span>max_round</span> <span>=</span> <span>5</span> <span>while</span> <span>"</span><span>Final Answer</span><span>"</span> <span>not</span> <span>in</span> <span>completion_content</span> <span>and</span> <span>current_round</span> <span><</span> <span>max_round</span><span>:</span> <span>current_round</span> <span>+=</span> <span>1</span> <span>action</span> <span>=</span> <span>parse_action</span><span>(</span><span>completion_content</span><span>)</span> <span>if</span> <span>action</span> <span>is</span> <span>None</span><span>:</span> <span>continue</span> <span>action_input</span> <span>=</span> <span>parse_action_input</span><span>(</span><span>completion_content</span><span>)</span> <span>if</span> <span>action_input</span> <span>is</span> <span>None</span><span>:</span> <span>continue</span> <span>action_result</span> <span>=</span> <span>action</span><span>[</span><span>"</span><span>function</span><span>"</span><span>](</span><span>*</span><span>action_input</span><span>)</span> <span>print</span><span>(</span><span>f</span><span>"</span><span>Action result: </span><span>{</span><span>action_result</span><span>}</span><span>"</span><span>)</span> <span>messages</span><span>.</span><span>append</span><span>({</span><span>"</span><span>role</span><span>"</span><span>:</span> <span>"</span><span>assistant</span><span>"</span><span>,</span> <span>"</span><span>content</span><span>"</span><span>:</span> <span>f</span><span>"</span><span>Observation: </span><span>{</span><span>action_result</span><span>}</span><span>"</span><span>})</span> <span>completion_content</span> <span>=</span> <span>chat</span><span>(</span><span>client</span><span>,</span> <span>messages</span><span>)</span> <span>messages</span><span>.</span><span>append</span><span>({</span><span>"</span><span>role</span><span>"</span><span>:</span> <span>"</span><span>assistant</span><span>"</span><span>,</span> <span>"</span><span>content</span><span>"</span><span>:</span> <span>completion_content</span><span>})</span> <span>if</span> <span>__name__</span> <span>==</span> <span>'</span><span>__main__</span><span>'</span><span>:</span> <span>main</span><span>()</span>import datetime import os import re from zoneinfo import ZoneInfo from openai import OpenAI def get_today_date(timezone): return datetime.datetime.now(ZoneInfo(timezone)).strftime("%Y-%m-%d") def convert_timezone(source_timezone, target_timezone, year, month, day, hour, minute): dt = datetime.datetime(year, month, day, hour, minute, tzinfo=ZoneInfo(source_timezone)) return dt.astimezone(ZoneInfo(target_timezone)) tool_map = { "get_today_date": { "prompt": """get_today_date(timezone) e.g. get_today_date("Asia/Tokyo") Description: Get the date of today. """, "function": get_today_date, }, "convert_timezone": { "prompt": """convert_timezone(source_timezone, target_timezone, year, month, day, hour, minute) e.g. convert_timezone("Asia/Tokyo", "Europe/London" 2025, 2, 15, 13, 0) Description: Convert time from source timezone to target timezone """, "function": convert_timezone } } system_prompt = f"""Answer the following questions as best you can. You have access to the following tools: {"\n".join([tool["prompt"] for tool in tool_map.values()])} If you need to use the tool, you MUST return PAUSE!!!! This is very IMPORTANT. Use the following format: Question: the input question you must answer Thought: you should always think about what to do Action: the action to take, should be one of [{", ".join(tool_map.keys())}]. This ONLY includes the name of the tool. Action Input: the input to the action. This ONLY includes the parameters of the tool. Example: Action Input: a, "b", c PAUSE Observation: the result of the action Thought: I now know the final answer Final Answer: the final answer to the original input question Begin!""" def chat(client, messages) -> str: completion = client.chat.completions.create(messages=messages, model="gpt-4o", stop="PAUSE") completion_content = completion.choices[0].message.content print("Chat completion:") print(completion_content) return completion_content def parse_action(completion_content: str): action_pattern = r"Action: ([^\n]*)" match = re.search(action_pattern, completion_content) if not match: return None tool_name = match.group(1) if tool_name not in tool_map: raise ValueError(f"Tool '{tool_name}' does not exist") return tool_map[tool_name] def parse_action_input(completion_content: str): action_input_pattern = r"Action Input: ([^\n]*)" match = re.search(action_input_pattern, completion_content) if not match: return None args_string = match.group(1) return eval(f"({args_string},)") def main(): client = OpenAI(api_key=os.environ.get("OPENAI_API_KEY")) question = "Convert 13:49 today in London time to Japan time. Please consider daylight saving." print(f"Question: {question}") messages = [{"role": "system", "content": system_prompt}, {"role": "user", "content": f"Question: {question}"}] completion_content = chat(client, messages) messages.append({"role": "assistant", "content": completion_content}) current_round = 0 max_round = 5 while "Final Answer" not in completion_content and current_round < max_round: current_round += 1 action = parse_action(completion_content) if action is None: continue action_input = parse_action_input(completion_content) if action_input is None: continue action_result = action["function"](*action_input) print(f"Action result: {action_result}") messages.append({"role": "assistant", "content": f"Observation: {action_result}"}) completion_content = chat(client, messages) messages.append({"role": "assistant", "content": completion_content}) if __name__ == '__main__': main()
Enter fullscreen mode Exit fullscreen mode
原文链接:Write AI agent from scratch without LangChain and CrewAI
暂无评论内容