了解如何在 Python 脚本中集成新的 OpenAI o1-preview 模型,以增强您的人工智能项目。该脚本允许您使用 o1-preview 模型与 OpenAI API 交互,并通过内置的网页抓取功能在提示中包含网页内容。此外,它还能正确处理模型回答中的 LaTeX 数学表达式,将其转换为终端可读的 Unicode 文本。
介绍
2024 年 9 月 12 日,OpenAI 发布了其新一代 AI 模型系列,名为 OpenAI o1。这些模型在给出回答之前会进行更深入的推理,使它们能够解决科学、编程和数学中的复杂问题。o1-preview 模型在这些领域表现尤为出色,优于之前的模型如 gpt-4o。
脚本的要点:
- 集成 o1-preview 模型:脚本默认使用 o1-preview 模型,从而提供先进的推理能力。
- 内置网页抓取:可以提取网页内容以丰富提示的上下文。
- LaTeX 表达式处理:将回答中的数学表达式转换为终端可读的 Unicode 文本。
- 可定制:脚本允许选择 OpenAI 模型,并可根据不同用例进行调整。
在本文中,我将详解脚本代码,解释其工作原理,并演示一系列复杂的提示示例。
先决条件
在开始之前,请确保您具备以下条件:
- 已在您的机器上安装 Python 3.x。
- 拥有一把 OpenAI API 密钥。您可以通过在 OpenAI 网站注册获取。
- 一个 Python 虚拟环境(推荐用于隔离依赖)。
- 所需的 Python 模块。
配置虚拟环境
为隔离本项目的依赖,建议使用虚拟环境。下面是创建虚拟环境并安装所需依赖的方法:
python3 -m venv env
source env/bin/activate # Sur Windows, utilisez env\Scripts\activate
pip install openai selenium webdriver-manager pylatexenc
设置 OpenAI API 密钥
将您的 OpenAI API 密钥设置为环境变量:
export OPENAI_API_KEY='votre_clé_api_ici'
将 'votre_clé_api_ici' 替换为您实际的 API 密钥。
完整脚本代码
以下是完整的 Python 脚本代码:
#!/usr/bin/env python3
import os
import sys
import argparse
import re
from openai import OpenAI
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from webdriver_manager.chrome import ChromeDriverManager
from pylatexenc.latex2text import LatexNodes2Text
def get_web_content(url):
if not url:
return ""
try:
# Configure les options de Chrome
chrome_options = Options()
# Ne pas utiliser le mode headless pour éviter les problèmes de vérification humaine
# Utilise ChromeDriverManager pour gérer l\'installation de ChromeDriver
driver = webdriver.Chrome(
service=Service(ChromeDriverManager().install()), options=chrome_options
)
# Charge la page web
driver.get(url)
# Récupère le contenu textuel de la page
web_content = driver.execute_script("return document.documentElement.innerText")
# Ferme le navigateur
driver.quit()
return web_content if web_content else None
except Exception as e:
return None
def convert_latex_to_text(latex_str):
# Convertit les expressions LaTeX en texte Unicode
return LatexNodes2Text().latex_to_text(latex_str)
def clean_output(content):
# Trouve toutes les expressions LaTeX dans le contenu et les convertit
patterns = [r"\\\\[.*?\\\\]", r"\\\(.*?\\\)", r"\$\$.*?\$\$", r"\$.*?\$"]
for pattern in patterns:
matches = re.findall(pattern, content, flags=re.DOTALL)
for match in matches:
plain_text = convert_latex_to_text(match)
content = content.replace(match, plain_text)
return content
def get_response(prompt, client, model="o1-preview"):
urls = re.findall(r"(https?://\S+)", prompt)
for url in urls:
web_content = get_web_content(url)
if web_content:
prompt = prompt.replace(url, web_content)
else:
return f"Erreur: Le contenu web pour {url} ne peut être récupéré."
try:
response = client.chat.completions.create(
model=model,
messages=[
{
"role": "user",
"content": prompt,
},
],
)
first_choice_message = response.choices[0].message
content = first_choice_message.content
# Convertit les expressions LaTeX en texte lisible
cleaned_content = clean_output(content)
return cleaned_content
except Exception as e:
return f"Une erreur est survenue : {e}"
def main():
parser = argparse.ArgumentParser()
parser.add_argument("prompt", nargs="?", help="Le prompt contenant des URLs")
parser.add_argument(
"--model",
default="o1-preview",
choices=["gpt-4o", "o1-preview", "o1-mini"],
help="Le modèle OpenAI à utiliser (par défaut o1-preview)",
)
args = parser.parse_args()
openai_api_key = os.getenv("OPENAI_API_KEY")
if not openai_api_key:
raise ValueError(
"La clé API OPENAI_API_KEY n'est pas définie dans les variables d\'environnement."
)
with OpenAI(api_key=openai_api_key) as client:
prompt = args.prompt or sys.stdin.read()
response = get_response(prompt, client, model=args.model)
print(response)
if __name__ == "__main__":
main()
代码说明
导入所需模块
脚本首先导入以下必要模块:
- os, sys, argparse, re:标准模块,用于处理环境变量、命令行参数和正则表达式。
- openai:用于与 OpenAI API 交互的模块。
- selenium 和 webdriver_manager:用于执行网页抓取。
- pylatexenc:用于将 LaTeX 表达式转换为可读的 Unicode 文本。
函数 get_web_content
此函数获取网页的文本内容。
def get_web_content(url):
if not url:
return ""
try:
# Configure les options de Chrome
chrome_options = Options()
# Ne pas utiliser le mode headless pour éviter les problèmes de vérification humaine
# Utilise ChromeDriverManager pour gérer l\'installation de ChromeDriver
driver = webdriver.Chrome(
service=Service(ChromeDriverManager().install()), options=chrome_options
)
# Charge la page web
driver.get(url)
# Récupère le contenu textuel de la page
web_content = driver.execute_script("return document.documentElement.innerText")
# Ferme le navigateur
driver.quit()
return web_content if web_content else None
except Exception as e:
return None
要点:
- Chrome 选项:脚本不使用无头(headless)模式,以避免某些页面对无头浏览器实施的人机验证问题。
- ChromeDriverManager:自动管理 ChromeDriver 的安装和更新。
- 内容提取:使用 JavaScript 提取页面的完整文本。
- 异常处理:在发生错误时,函数返回
None。
函数 convert_latex_to_text
此函数将 LaTeX 表达式转换为 Unicode 文本。
def convert_latex_to_text(latex_str):
# Convertit les expressions LaTeX en texte Unicode
return LatexNodes2Text().latex_to_text(latex_str)
要点:
- 使用库
pylatexenc将 LaTeX 表达式转换,使数学公式在终端中可读。
函数 clean_output
此函数处理模型的响应,将 LaTeX 表达式进行转换。
def clean_output(content):
# Trouve toutes les expressions LaTeX dans le contenu et les convertit
patterns = [r"\\\\[.*?\\\\]", r"\\\(.*?\\\)", r"\$\$.*?\$\$", r"\$.*?\$"]
for pattern in patterns:
matches = re.findall(pattern, content, flags=re.DOTALL)
for match in matches:
plain_text = convert_latex_to_text(match)
content = content.replace(match, plain_text)
return content
要点:
- 查找 LaTeX 表达式:使用正则表达式识别公式。
- 转换:将每个公式转换为 Unicode 文本。
- 替换:用可读的等价文本替换 LaTeX 公式。
函数 get_response
准备提示(prompt),在必要时处理网页抓取,调用 OpenAI API 并清理响应。
def get_response(prompt, client, model="o1-preview"):
urls = re.findall(r"(https?://\S+)", prompt)
for url in urls:
web_content = get_web_content(url)
if web_content:
prompt = prompt.replace(url, web_content)
else:
return f"Erreur: Le contenu web pour {url} ne peut être récupéré."
try:
response = client.chat.completions.create(
model=model,
messages=[
{
"role": "user",
"content": prompt,
},
],
)
first_choice_message = response.choices[0].message
content = first_choice_message.content
# Convertit les expressions LaTeX en texte lisible
cleaned_content = clean_output(content)
return cleaned_content
except Exception as e:
return f"Une erreur est survenue : {e}"
要点:
- 处理 URL:如果提示中包含 URL,会提取该页面内容并插入提示中。
- 调用 OpenAI API:将修改后的提示发送到指定的模型。
- 响应清理:将 LaTeX 表达式转换为便于阅读的形式。
函数 main
处理命令行参数并执行脚本。
def main():
parser = argparse.ArgumentParser()
parser.add_argument("prompt", nargs="?", help="Le prompt contenant des URLs")
parser.add_argument(
"--model",
default="o1-preview",
choices=["gpt-4o", "o1-preview", "o1-mini"],
help="Le modèle OpenAI à utiliser (par défaut o1-preview)",
)
args = parser.parse_args()
openai_api_key = os.getenv("OPENAI_API_KEY")
if not openai_api_key:
raise ValueError(
"La clé API OPENAI_API_KEY n'est pas définie dans les variables d\'environnement."
)
with OpenAI(api_key=openai_api_key) as client:
prompt = args.prompt or sys.stdin.read()
response = get_response(prompt, client, model=args.model)
print(response)
要点:
- 参数:脚本接受一个提示(prompt)和一个模型参数。
- API 密钥:检查是否已设置 API 密钥。
- 执行:调用函数
get_response并打印响应。
脚本执行
if __name__ == "__main__":
main()
使用示例
提出需要推理的问题
./openai_poc.py "Dans un triangle rectangle, si les côtés adjacents à l'angle droit mesurent 3 cm et 4 cm, calcule la longueur de l'hypoténuse."
要计算一个直角三角形中两条直角边分别为 3 cm 和 4 cm 时斜边的长度,我们使用毕达哥拉斯定理:
将给定数值代入:
对两边取平方根:
因此,斜边的长度为 5 cm。
斜边的长度为 5 cm。
生成网页摘要
./openai_poc.py "Fais-moi un résumé de cette page : https://openai.com/index/introducing-openai-o1-preview/"
OpenAI 于 2024 年 9 月 12 日宣布推出一系列新的 AI 模型,称为 OpenAI o1,该系列模型被设计为在回答前花更多时间进行思考。这些模型能够在复杂任务中进行推理,并解决比以前模型在科学、编程和数学方面更困难的问题。
该系列的首个模型 o1-preview 已可在 ChatGPT 以及 OpenAI API 中使用。同时还提供一个更轻量、更经济的版本 OpenAI o1-mini,它以比 o1-preview 低约 80% 的成本提供有效的编码能力。
计算简单乘法
./openai_poc.py "Quel est le résultat de 15 x 12 ?"
的结果是 180。
解决简单方程
./openai_poc.py "Résous l'équation 2x + 5 = 15."
为了解方程 ,请按以下步骤操作:
- 两边同时减去 5 以隔离含有未知数的项:
- 两边同时除以 2 以求解 :
解: 。
计算百分比
./openai_poc.py "Quel est 20% de 250 ?"
的 等于 50。
计算过程:
计算圆的面积
./openai_poc.py "Calcule l'aire d'un cercle de rayon 5 cm."
要计算半径为 5 cm 的圆的面积,使用圆面积公式:
其中:
- 是圆的面积,
- 是圆的半径。
将 代入 5 cm:
因此,圆的面积是 。
如果需要近似值,取 :
所以,圆的面积约为 78,54 cm²。
计算简单积分
./openai_poc.py "Calcule l'intégrale de 0 à 1 de x^2 dx."
要计算函数 在 0 到 1 上的积分,我们对 关于 积分并在上下限 0 和 1 处求值。
计算步骤:
- 对 积分:
其中 C 为积分常数。
- 在上下限 0 到 1 之间求值:
- 计算上下限值:
- 相减得到最终结果:
结论:
函数 在 0 到 1 上的积分值为 。
计算平均速度
./openai_poc.py "Si une voiture parcourt 150 km en 3 heures, quelle est sa vitesse moyenne ?"
要计算一辆车在 3 小时内行驶 150 km 的平均速度,使用平均速度公式:
代入数值:
该车的平均速度为 50 km/h。
经典力学
./openai_poc.py "Un bloc de 5 kg est tiré sur une surface sans frottement par une force de 20 N. Calcule son accélération."
要计算物块的加速度,我们使用牛顿第二定律,表明作用在物体上的合力等于物体质量乘以加速度()。
已知:
- 物块质量
- 作用力
- 无摩擦面(因此没有摩擦力)
将公式重排以求加速度 :
代入数值:
答案:物块的加速度为 。
常微分方程求解
./openai_poc.py "Résous l'équation différentielle dy/dx = x^2 + y^2 avec la condition initiale y(0) = 1."
考虑求解微分方程:
满足初始条件 。注意该方程为非线性方程,不能用诸如变量分离或常规积分因子等基础方法求解。不过我们可以尝试将其转化为更易处理的形式。
第 1 步:识别方程的类型
该方程为 Riccati 方程,通式为:
在本例中:
第 2 步:转化为二阶线性方程
为解 Riccati 方程,可以使用以下替换:
其中 , 为 对 的导数。
计算 :
应用商法则得:
第 3 步:代入原方程
将 和 代入原方程:
化简:
两边同乘以 消去分母:
化简得到:
在假设 下除以 :
第 4 步:求解二阶线性方程
得到的方程为二阶齐次线性常微分方程:
该方程属于系数为变量的线性方程,通常与 Airy 方程相关。其解不能用初等函数表示,而是用特殊函数表示。
方程的通解为:
其中 和 为第一类和第二类 Airy 函数, 为虚数单位()。
第 5 步:回到
记住:
知道 后,通过求导并取负比可以得到 。
第 6 步:应用初始条件
要确定常数 和 ,需应用初始条件 。由于 Airy 函数在复参数下的复杂性,显式计算较为繁琐。
结论
带有初始条件 的方程解可以用 Airy 特殊函数表示,不能用初等函数显式表示。
最终回答:
微分方程 且满足 的解以 Airy 特殊函数给出,无法用初等函数显式表示。
电磁学
./openai_poc.py "Calcule le champ électrique à une distance r d'une charge ponctuelle Q."
点电荷 在距离 处产生的电场 由库仑定律给出。计算电场的公式为:
其中:
- 为电场(单位伏特每米,V/m),
- 为点电荷(单位库仑,C),
- 为到电荷的距离(单位米,m),
- 为真空介电常数,近似值为 。
计算示例:
假设电荷 (2 微库仑),欲计算距离 处的电场。
- 计算分数前的常数:
- 代入公式:
结论:
距离为 的点电荷 在该点产生的电场为 。
因此,若要计算某一距离处的电场,只需将具体的 和 值代入上述公式。
化学平衡
./openai_poc.py "Explique comment le principe de Le Chatelier s'applique à l'équilibre suivant : N2 + 3H2 ⇌ 2NH3."
勒夏特列原理(Le Chatelier 原理)指出,当处于平衡的系统受到外部扰动(应力)时,系统会作出反应以减小该扰动并建立新的平衡。应用于以下化学平衡:
我们可以分析不同变化如何影响平衡位置。
1. 浓度的变化: - 增加反应物浓度(N₂ 或 H₂): 如果向体系中加入氮气(N₂)或氢气(H₂),这些反应物的浓度会增加。根据勒夏特列原理,平衡会朝消耗这些额外反应物的方向移动,即向右移动,有利于生成氨(NH₃)。
-
减少产物浓度(NH₃): 如果从体系中移除氨,NH₃ 的浓度会降低。平衡将向右移动以补偿这种降低,再次有利于氨的生成。
-
增加产物浓度(NH₃): 如果向体系中加入氨,平衡将向左移动以减少 NH₃ 的过量,有利于生成 N₂ 和 H₂。
2. 压力的变化:
-
系统总压增大: 对于气体,压力增大(通过减少体积)有利于产生气体摩尔数较少的反应。在此反应中,从 4 摩尔气体(1 N₂ + 3 H₂)变为 2 摩尔气体(2 NH₃)。因此,增压使平衡向右移动,有利于氨的形成。
-
系统总压降低: 相反,压力降低会有利于产生更多气体摩尔数的反应,使平衡向左移动,并促进 NH₃ 解离为 N₂ 和 H₂。
3. 温度的变化:
-
反应的放热性质: 合成氨是放热反应(),即放出热量。
-
温度升高: 提高温度会向体系提供热量。根据勒夏特列原理,平衡会朝吸收这部分额外热量的方向移动,因此向左(吸热反应)移动,促进 NH₃ 解离为 N₂ 和 H₂。
-
温度降低: 降低温度时,体系会通过生成热量来补偿这种损失。平衡因此向右(放热反应)移动,有利于氨的形成。
4. 催化剂的存在:
- 催化剂的作用: 添加催化剂(例如经助催化剂处理的细粉铁)可以加快达到平衡的速率,但不会改变平衡位置。它对正反应和逆反应的加速作用是相等的。
总结:
勒夏特列原理可以预测化学平衡在系统条件改变时的移动方向。对于合成氨:
- 高压 有利于 NH₃ 的生成(气体摩尔数较少)。
- 低温 有利于 NH₃ 的生成(放热反应)。
- 增加 N₂ 或 H₂ 的浓度 有利于 NH₃ 的生成。
- 从体系中移除 NH₃ 有利于生成更多的 NH₃。
这些原理在哈伯-博世(Haber-Bosch)工艺中得到应用,以优化工业上氨的生产。
结论
该 Python 脚本为 OpenAI o1-preview 模型提供了实用的集成,使其先进的推理能力可用于从简单到复杂的各种问题。无论您是好奇的初学者,还是希望测试模型极限的专家,这个脚本都是您人工智能项目的一个不错的工具。
资源
本文件已使用模型 gpt-5-mini 将 fr 版本翻译为 zh 语言。有关翻译过程的更多信息,请参阅 https://gitlab.com/jls42/ai-powered-markdown-translator