Write AI agent from scratch without LangChain and CrewAI

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>openai
pip <span>install </span>openai
pip 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:
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'
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_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.
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

© 版权声明
THE END
喜欢就支持一下吧
点赞12 分享
Remember happiness doesn't depend upon who you are or what you have; it depends solely on what you think.
幸福不在于你是谁,你拥有什么,而仅仅在于你自己怎么看待
评论 抢沙发

请登录后发表评论

    暂无评论内容