- 💖 Brief:大家好,我是Zeeland。Tags: 大模型创业、LangChain Top Contributor、算法工程师、Promptulate founder、Python开发者。
- 📝 CSDN主页:Zeeland🔥
- 📣 个人说明书:Zeeland
- 📣 个人网站:https://me.zeeland.cn/
- 📚 Github主页: Undertone0809 (Zeeland)
- 🎉 支持我:点赞👍+收藏⭐️+留言📝 我会定期在博客、个人说明书、论坛中做一些技术分享。也欢迎大家阅读我的个人说明书,大家可以在这里快速了解我和我做过的事情,期待和你交个朋友,有机会我们一起做一些有意思的事情
Introduction
本文将介绍GPT-4-turbo+Streamlit+wiki+calculator+Promptulate构建Math Agents应用,使用 Agent 进行推理,解决数学问题。
如果你想直接获取代码,可以从https://github.com/Undertone0809/promptulate/tree/main/example/build-math-application-with-agent 获取。
也可以点击https://github.com/Undertone0809/promptulate/fork fork 更多 examples 到自己的仓库里学习。
Summary
本文详细介绍了如何结合GPT-4-turbo、Streamlit、Wikipedia API、计算器功能以及Promptulate框架,构建一个名为“Math Wiz”的数学辅助应用。这个应用旨在帮助用户解决数学问题或逻辑/推理问题。通过这个项目,我们展示了如何利用Promptulate框架中的Agent进行推理,以及如何使用不同的工具来处理用户的查询。
关键步骤总结:
- 环境搭建:创建了一个新的conda环境,并安装了所有必要的库,包括Promptulate、Wikipedia和numexpr。
- 应用流程:设计了一个应用流程,其中包含了一个能够利用不同工具(如Wikipedia工具、计算器工具和推理工具)来回答用户查询的Agent。这个Agent使用大型语言模型(LLM)作为其“大脑”,指导它的决策。
- 理解Promptulate Agent:介绍了Promptulate Agent的概念,这是一个设计用来与语言模型进行更复杂和交互式任务的接口。
逐步实现:
- 创建了chatbot.py脚本并导入了必要的依赖。
- 定义了基于OpenAI的语言模型。
- 创建了三个工具:Wikipedia工具、计算器工具和推理工具。
- 初始化了Agent,并指定了LLM来帮助它选择使用哪些工具及其顺序。
- 创建Streamlit应用:使用Streamlit框架来构建应用的前端界面,允许用户输入问题并接收Agent的回答。
测试案例:
- 通过几个测试案例,展示了“Math Wiz”应用如何处理不同类型的数学和逻辑问题,包括算术运算、历史事实查询和逻辑推理等。
Building a Math Application with promptulate Agents
This demo is how to use promptulates agents to create a custom Math application utilising OpenAI’s GPT3.5 Model.
For the application frontend, there will be using streamlit, an easy-to-use open-source Python framework.
This generative math application, let’s call it “Math Wiz”, is designed to help users with their math or reasoning/logic questions.
Environment Setup
We can start off by creating a new conda environment with python=3.11:conda create -n math_assistant python=3.11
Activate the environment:conda activate math_assistant
Next, let’s install all necessary libraries:
pip install -U promptulate
pip install wikipedia
pip install numexpr
Sign up at OpenAI and obtain your own key to start making calls to the gpt model. Once you have the key, create a .env file in your repository and store the OpenAI key:
OPENAI_API_KEY="your_openai_api_key"
Application Flow
The application flow for Math Wiz is outlined in the flowchart below. The agent in our pipeline will have a set of tools at its disposal that it can use to answer a user query. The Large Language Model (LLM) serves as the “brain” of the agent, guiding its decisions. When a user submits a question, the agent uses the LLM to select the most appropriate tool or a combination of tools to provide an answer. If the agent determines it needs multiple tools, it will also specify the order in which the tools are used.
The application flow for Math Wiz is outlined below:
The agent in our pipeline will have a set of tools at its disposal that it can use to answer a user query. The Large Language Model (LLM) serves as the “brain” of the agent, guiding its decisions. When a user submits a question, the agent uses the LLM to select the most appropriate tool or a combination of tools to provide an answer. If the agent determines it needs multiple tools, it will also specify the order in which the tools are used.
The agent for our Math Wiz app will be using the following tools:
-
Wikipedia Tool: this tool will be responsible for fetching the latest information from Wikipedia using the Wikipedia API. While there are paid tools and APIs available that can be integrated inside Promptulate, I would be using Wikipedia as the app’s online source of information.
-
Calculator Tool: this tool would be responsible for solving a user’s math queries. This includes anything involving numerical calculations. For example, if a user asks what the square root of 4 is, this tool would be appropriate.
-
Reasoning Tool: the final tool in our application setup would be a reasoning tool, responsible for tackling logical/reasoning-based user queries. Any mathematical word problems should also be handled with this tool.
Now that we have a rough application design, we can begin thinking about building this application.
Understanding promptulate Agents
Promptulate agents are designed to enhance interaction with language models by providing an interface for more complex and interactive tasks. We can think of an agent as an intermediary between users and a large language model. Agents seek to break down a seemingly complex user query, that our LLM might not be able to tackle on its own, into easier, actionable steps.
In our application flow, we defined a few different tools that we would like to use for our math application. Based on the user input, the agent should decide which of these tools to use. If a tool is not required, it should not be used. Promptulate agents can simplify this for us. These agents use a language model to choose a sequence of actions to take. Essentially, the LLM acts as the “brain” of the agent, guiding it on which tool to use for a particular query, and in which order. This is different from Proptulate chains where the sequence of actions are hardcoded in code. Promptulate offers a wide set of tools that can be integrated with an agent. These tools include, and are not limited to, online search tools, API-based tools, chain-based tools etc. For more information on Promptulate agents and their types, see this.
Step-by-Step Implementation
Step 1
Create a chatbot.py
script and import the necessary dependencies:
from promptulate.llms import ChatOpenAI
from promptulate.tools.wikipedia.tools import wikipedia_search
from promptulate.tools.math.tools import calculator
import promptulate as pne
Step 2
Next, we will define our OpenAI-based Language Model.The architectural design of promptulate
is easily compatible with different large language model extensions. In promptulate
, llm is responsible for the most basic part of content generation, so it is the most basic component.By default, ChatOpenAI
in promptulate
uses the gpt-3.5-turbo
model.
llm = pne.LLMFactory.build(model_name="gpt-4-turbo", model_config={"temperature": 0.5})
We would be using this LLM both within our math and reasoning process and as the decision maker for our agent.
Step 3
When constructing your own agent, you will need to provide it with a list of tools that it can use. Difine a tool, the only you need to do is to provide a function to Promptulate. Promptulate will automatically convert it to a tool that can be used by the language learning model (LLM). The final presentation result it presents to LLM is an OpenAI type JSON schema declaration.
Actually, Promptulate will analysis function name, parameters type, parameters attribution, annotations and docs when you provide the function. We strongly recommend that you use the official best practices of Template for function writing. The best implementation of a function requires adding type declarations to its parameters and providing function level annotations. Ideally, declare the meaning of each parameter within the annotations.
We will now create our three tools. The first one will be the online tool using the Wikipedia API wrapper:
# Wikipedia Tool
def wikipedia_tool(keyword: str) -> str:
"""search by keyword in web.
A useful tool for searching the Internet to find information on world events,
issues, dates,years, etc. Worth using for general topics. Use precise questions.
Args:
keyword: keyword to search
Returns:
str: search result
"""
return wikipedia_search(keyword)
Next, let’s define the tool that we will be using for calculating any numerical expressions. Promptulate
offers the calculator
which uses the numexpr
Python library to calculate mathematical expressions. It is also important that we clearly define what this tool would be used for. The description can be helpful for the agent in deciding which tool to use from a set of tools for a particular user query.
# calculator tool for arithmetics
def math_tool(expression: str):
"""Useful for when you need to answer questions about math. This tool is only
for math questions and nothing else. Only input math expressions.
Args:
expression: A mathematical expression, eg: 18^0.43
Attention:
Expressions can not exist variables!
eg: (current age)^0.43 is wrong, you should use 18^0.43 instead.
Returns:
The result of the evaluation.
"""
return calculator(expression)
Finally, we will be defining the tool for logic/reasoning-based queries. We will first create a prompt to instruct the model with executing the specific task. Then we will create a simple AssistantMessage
for this tool, passing it the LLM and the prompt.
# reasoning based tool
def word_problem_tool(question: str) -> str:
"""
Useful for when you need to answer logic-based/reasoning questions.
Args:
question(str): Detail question, the description of the problem requires a
detailed question context. Include a description of the problem
Returns:
question answer
"""
system_prompt: str = """You are a reasoning agent tasked with solving t he user's logic-based questions.
Logically arrive at the solution, and be factual.
In your answers, clearly detail the steps involved and give the final answer.
Provide the response in bullet points.""" # noqa
llm = ChatOpenAI()
return llm(f"{system_prompt}\n\nQuestion:{question}Answer:")
Step 4
We will now initialize our agent with the tools we have created above. We will also specify the LLM to help it choose which tools to use and in what order:
# agent
agent = pne.ToolAgent(tools=[wikipedia_tool, math_tool, word_problem_tool],
llm=llm)
resp: str = agent.run("I have 3 apples and 4 oranges.I give half of my oranges away and buy two dozen new ones,along with three packs of strawberries.Each pack of strawberry has 30 strawberries.How many total pieces of fruit do I have at the end?")
print(resp)
[31;1m[1;3m[Agent] Tool Agent start...[0m
[36;1m[1;3m[User instruction] I have 3 apples and 4 oranges.I give half of my oranges away and buy two dozen new ones,along with three packs of strawberries.Each pack of strawberry has 30 strawberries.How many total pieces of fruit do I have at the end?[0m
[33;1m[1;3m[Thought] I should break down the problem step by step and calculate the total number of fruits at the end.[0m
[33;1m[1;3m[Action] word_problem_tool args: {'question': 'I have 3 apples and 4 oranges. I give half of my oranges away and buy two dozen new ones, along with three packs of strawberries. Each pack of strawberry has 30 strawberries. How many total pieces of fruit do I have at the end?'}[0m
[33;1m[1;3m[Observation] To solve this problem, we can break it down into steps and calculate the total number of fruit pieces you have at the end:
Initial fruits:
- 3 apples
- 4 oranges
Giving away half of the oranges:
- You have 4 oranges, so you give away 4/2 = 2 oranges.
- After giving away 2 oranges, you have 4 - 2 = 2 oranges remaining.
Buying new fruits:
- You buy 2 dozen new oranges, where 1 dozen is equal to 12.
- 2 dozen oranges is 2 * 12 = 24 oranges.
- You also buy 3 packs of strawberries, with each pack having 30 strawberries.
- Total strawberries bought = 3 * 30 = 90 strawberries.
Calculating total fruit pieces at the end:
- After giving away half of your oranges, you have 2 oranges left.
- Adding the new oranges bought, you have a total of 2 + 24 = 26 oranges.
- You initially had 3 apples, so the total apples remain 3.
- You bought 90 strawberries.
- Total fruits at the end = Total oranges + Total apples + Total strawberries
- Total fruits = 26 oranges + 3 apples + 90 strawberries = 26 + 3 + 90 = 119 pieces of fruit
Therefore, at the end of the scenario, you have a total of 119 pieces of fruit.[0m
[32;1m[1;3m[Agent Result] You have a total of 119 pieces of fruit at the end of the scenario.[0m
[38;5;200m[1;3m[Agent] Agent End.[0m
You have a total of 119 pieces of fruit at the end of the scenario.
The app’s response to a logic question is following:
Creating streamlit application
We will be using Streamlit, an open-source Python framework, to build our application. With Streamlit, you can build conversational AI applications with a few simple lines of code. Using streamlit to build the demo of application is demonstrated in the peer child file chabot.py
of the notebook file. You can run the file directly with the command streamlit run chatbot.py
to view the effect and debug the web page.
Let’s begin by importing the Streamlit package to our chatbot.py
script: pip install Streamlit == 1.28
import streamlit as st
Then,let’s build a lifecycle class to display the intermediate state of the agent response on the chat page.If you want to learn more about the life cycle, please click here
from promptulate.hook import Hook, HookTable
class MidStepOutHook:
@staticmethod
def handle_agent_revise_plan(*args, **kwargs):
messages = f"[Revised Plan] {kwargs['revised_plan']}"
st.chat_message("assistant").write(messages)
@staticmethod
def handle_agent_action(*args, **kwargs):
messages = f"[Thought] {kwargs['thought']}\n"
messages += f"[Action] {kwargs['action']} args: {kwargs['action_input']}"
st.chat_message("assistant").write(messages)
@staticmethod
def handle_agent_observation(*args, **kwargs):
messages = f"[Observation] {kwargs['observation']}"
st.chat_message("assistant").write(messages)
@staticmethod
def registry_hooks():
"""Registry and enable stdout hooks. StdoutHook can print colorful
information."""
Hook.registry_hook(
HookTable.ON_AGENT_REVISE_PLAN,
MidStepOutHook.handle_agent_revise_plan,
"component",
)
Hook.registry_hook(
HookTable.ON_AGENT_ACTION, MidStepOutHook.handle_agent_action, "component"
)
Hook.registry_hook(
HookTable.ON_AGENT_OBSERVATION,
MidStepOutHook.handle_agent_observation,
"component",
)
Next,Let’s build a function,and We will be adding our LLM, tools and agent initialization code to this function.
def build_agent(api_key: str) -> pne.ToolAgent:
MidStepOutHook.registry_hooks()
# calculator tool for arithmetics
def math_tool(expression: str):
"""Useful for when you need to answer questions about math. This tool is only
for math questions and nothing else. Only input math expressions.
Args:
expression: A mathematical expression, eg: 18^0.43
Attention:
Expressions can not exist variables!
eg: (current age)^0.43 is wrong, you should use 18^0.43 instead.
Returns:
The result of the evaluation.
"""
return calculator(expression)
# reasoning based tool
def word_problem_tool(question: str) -> str:
"""
Useful for when you need to answer logic-based/reasoning questions.
Args:
question(str): Detail question, the description of the problem requires a
detailed question context. Include a description of the problem
Returns:
question answer
"""
system_prompt: str = """You are a reasoning agent tasked with solving t he user's logic-based questions.
Logically arrive at the solution, and be factual.
In your answers, clearly detail the steps involved and give the final answer.
Provide the response in bullet points.""" # noqa
llm = ChatOpenAI(private_api_key=api_key)
return llm(f"{system_prompt}\n\nQuestion:{question}Answer:")
# Wikipedia Tool
def wikipedia_tool(keyword: str) -> str:
"""search by keyword in web.
A useful tool for searching the Internet to find information on world events,
issues, dates,years, etc. Worth using for general topics. Use precise questions.
Args:
keyword: keyword to search
Returns:
str: search result
"""
return wikipedia_search(keyword)
llm = ChatOpenAI(model="gpt-4-1106-preview", private_api_key=api_key)
return pne.ToolAgent(tools=[wikipedia_tool, math_tool, word_problem_tool], llm=llm)
Set the style of our application
# Create a sidebar to place the user parameter configuration
with st.sidebar:
openai_api_key = st.text_input(
"OpenAI API Key", key="chatbot_api_key", type="password"
)
"[Get an OpenAI API key](https://platform.openai.com/account/api-keys)"
"[View the source code](https://github.com/hizeros/llm-streamlit/blob/master/Chatbot.py)" # noqa
# Set title
st.title("💬 Math Wiz")
st.caption("🚀 Hi there! 👋 I am a reasoning tool by Promptulate to help you "
"with your math or logic-based reasoning questions.")
Next, check our session state and render the user input and agent response to the chat page, so that we successfully build a simple math application using streamlit
# Determine whether to initialize the message variable
# otherwise initialize a message dictionary
if "messages" not in st.session_state:
st.session_state["messages"] = [
{"role": "assistant", "content": "How can I help you?"}
]
# Traverse messages in session state
for msg in st.session_state.messages:
st.chat_message(msg["role"]).write(msg["content"])
# User input
if prompt := st.chat_input():
if not openai_api_key:
st.info("Please add your OpenAI API key to continue.")
st.stop()
agent: pne.ToolAgent = build_agent(api_key=openai_api_key)
# Add the message entered by the user to the list of messages in the session state
st.session_state.messages.append({"role": "user", "content": prompt})
# Display in the chat interface
st.chat_message("user").write(prompt)
response: str = agent.run(prompt)
st.session_state.messages.append({"role": "assistant", "content": response})
st.chat_message("assistant").write(response)
Let’s try to run it:streamlit run chatbot.py
The running result is as follows:
Examples of other questions are given below for testing reference:
- Question 1
- I have 3 apples and 4 oranges.I give half of my oranges away and buy two dozen new ones,along with three packs of strawberries.Each pack of strawberry has 30 strawberries.How many total pieces of fruit do I have at the end?
- correct answer = 119
- Question 2
- What is the cube root of 625?
- correct answer = 8.5498
- Question 3
- what is cube root of 81? Multiply with 13.27, and subtract 5.
- correct answer = 52.4195
- Question 4
- Steve’s sister is 10 years older than him. Steve was born when the cold war
ended. When was Steve’s sister born? - correct answer = 1991 - 10 = 1981
- Steve’s sister is 10 years older than him. Steve was born when the cold war
- Question 5
- Tell me the year in which Tom Cruise’s Top Gun was released, and calculate the square of that year.
- correct answer = 1986**2 = 3944196
Summary
本项目展示了如何利用当前的AI技术和工具来构建一个实用的数学辅助应用。“Math Wiz”能够处理从简单的数学计算到复杂的逻辑推理问题,是一个结合了多种技术的创新示例。通过这个应用,用户可以得到快速准确的数学问题解答,同时也展示了人工智能在教育和日常生活中的潜力。
对于希望深入了解或自行构建此类应用的开发者,本文提供的详细步骤和代码示例是一个宝贵的资源。此外,通过提供的GitHub链接,读者可以直接访问完整的代码,进一步探索和修改以满足特定的需求或兴趣。