Team Ai
Apppublic

lexlepty/functioncall

sourceHugging Facemitupdated 2y agoView on Hugging Face
0likes
app.py296 linesDownload Raw Back to root
1import os2import json3import requests4import smtplib5from email.mime.text import MIMEText6from email.mime.multipart import MIMEMultipart7from flask import Flask, request, jsonify, send_from_directory8from openai import OpenAI9from bs4 import BeautifulSoup10import random11from functions import FUNCTIONS_GROUP_1, FUNCTIONS_GROUP_2, get_function_descriptions12 13app = Flask(__name__)14API_KEY = os.getenv("OPENAI_API_KEY")15BASE_URL = os.getenv("OPENAI_BASE_URL")16emailkey = os.getenv("EMAIL_KEY")17client = OpenAI(api_key=API_KEY, base_url=BASE_URL)18 19def search_duckduckgo(keywords):20    search_term = " ".join(keywords)21    url = "https://www.bing.com/search"22    23    user_agents = [24        "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36",25        "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:89.0) Gecko/20100101 Firefox/89.0",26        "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15",27    ]28    headers = {29        "User-Agent": random.choice(user_agents)30    }31    32    params = {33        "q": search_term,34        "setlang": "zh-CN"35    }36 37    response = requests.get(url, params=params, headers=headers)38    39    results = []40    if response.status_code == 200:41        soup = BeautifulSoup(response.text, 'html.parser')42        for item in soup.select('.b_algo')[:5]:  # Limit to 5 results43            title_elem = item.select_one('h2 a')44            snippet_elem = item.select_one('.b_caption p')45            46            if title_elem and snippet_elem:47                results.append({48                    "title": title_elem.text,49                    "href": title_elem['href'],50                    "body": snippet_elem.text51                })52    return results53 54def search_papers(query):55    url = f"https://api.crossref.org/works?query={query}"56    response = requests.get(url)57    if response.status_code == 200:58        data = response.json()59        papers = data['message']['items']60        processed_papers = []61        for paper in papers:62            processed_paper = {63                "标题": paper.get('title', [''])[0],64                "作者": ", ".join([f"{author.get('given', '')} {author.get('family', '')}" for author in paper.get('author', [])]),65                "DOI": paper.get('DOI', ''),66                "ISBN": ", ".join(paper.get('ISBN', [])),67                "摘要": paper.get('abstract', '').replace('<p>', '').replace('</p>', '').replace('<italic>', '').replace('</italic>', '')68            }69            processed_papers.append(processed_paper)70        return processed_papers71    else:72        return []73 74def send_email(to, subject, content):75    try:76        with smtplib.SMTP('106.15.184.28', 8025) as smtp:77            smtp.login("jwt", emailkey)78            message = MIMEMultipart()79            message['From'] = "Me <aixiao@aixiao.xyz>"80            message['To'] = to81            message['Subject'] = subject82            message.attach(MIMEText(content, 'html'))83            smtp.sendmail("aixiao@aixiao.xyz", to, message.as_string())84        return True85    except Exception as e:86        print(f"发送邮件时出错: {str(e)}")87        return False88 89def get_openai_response(messages, model="gpt-4o-mini", functions=None, function_call=None):90    try:91        response = client.chat.completions.create(92            model=model,93            messages=messages,94            functions=functions,95            function_call=function_call96        )97        return response.choices[0].message98    except Exception as e:99        print(f"调用OpenAI API时出错: {str(e)}")100        return None101 102def process_function_call(function_name, function_args):103    if function_name == "search_duckduckgo":104        keywords = function_args.get('keywords', [])105        if not keywords:106            return "搜索关键词为空,无法执行搜索。"107        return search_duckduckgo(keywords)108    elif function_name == "search_papers":109        query = function_args.get('query', '')110        if not query:111            return "搜索查询为空,无法执行论文搜索。"112        return search_papers(query)113    elif function_name == "send_email":114        to = function_args.get('to', '')115        subject = function_args.get('subject', '')116        content = function_args.get('content', '')117        if not to or not subject or not content:118            return "邮件信息不完整,无法发送邮件。"119        success = send_email(to, subject, content)120        return {121            "success": success,122            "message": "邮件发送成功" if success else "邮件发送失败",123            "to": to,124            "subject": subject,125            "content": content,126            "is_email": True127        }128    else:129        return "未知的函数调用。"130 131@app.route('/')132def index():133    return send_from_directory('.', 'index.html')134 135@app.route('/chat', methods=['POST'])136def chat():137    data = request.json138    question = data['question']139    history = data.get('history', [])140    messages = history + [{"role": "user", "content": question}]141    142    status_log = []143    144    # 次级模型1: 处理搜索相关函数145    status_log.append("次级模型1:正在判断是否需要选调第一组函数")146    sub_model_1_response = get_openai_response(messages, model="gpt-4o-mini", functions=FUNCTIONS_GROUP_1, function_call="auto")147    148    # 次级模型2: 处理邮件发送相关函数149    status_log.append("次级模型2:正在判断是否需要选调第二组函数")150    sub_model_2_response = get_openai_response(messages, model="gpt-4o-mini", functions=FUNCTIONS_GROUP_2, function_call="auto")151    152    function_call_1 = sub_model_1_response.function_call if sub_model_1_response and sub_model_1_response.function_call else None153    function_call_2 = sub_model_2_response.function_call if sub_model_2_response and sub_model_2_response.function_call else None154    155    if not function_call_1:156        status_log.append("次级模型1:判断不需要选调第一组函数")157    if not function_call_2:158        status_log.append("次级模型2:判断不需要选调第二组函数")159    160    final_function_call = None161    response = None162    search_results = None163    email_sent = False164    165    if function_call_1 and function_call_2:166        # 裁决模型: 决定使用哪个函数调用167        status_log.append("裁决模型:正在决定使用哪个函数调用")168        arbitration_messages = messages + [169            {"role": "system", "content": "两个次级模型都建议使用函数。请决定使用哪个函数更合适。"},170            {"role": "assistant", "content": f"次级模型1建议使用函数:{function_call_1.name}"},171            {"role": "assistant", "content": f"次级模型2建议使用函数:{function_call_2.name}"}172        ]173        arbitration_response = get_openai_response(arbitration_messages, model="gpt-4o-mini")174        if "模型1" in arbitration_response.content or function_call_1.name in arbitration_response.content:175            final_function_call = function_call_1176            status_log.append(f"裁决模型:决定使用函数 {function_call_1.name}")177        else:178            final_function_call = function_call_2179            status_log.append(f"裁决模型:决定使用函数 {function_call_2.name}")180    elif function_call_1:181        final_function_call = function_call_1182        status_log.append(f"次级模型1:决定使用函数 {function_call_1.name}")183    elif function_call_2:184        final_function_call = function_call_2185        status_log.append(f"次级模型2:决定使用函数 {function_call_2.name}")186    else:187        status_log.append("所有次级模型:判断不需要进行任何函数调用")188    189    if final_function_call:190        function_name = final_function_call.name191        function_args = json.loads(final_function_call.arguments)192        status_log.append(f"正在执行函数 {function_name}")193        result = process_function_call(function_name, function_args)194        status_log.append(f"函数 {function_name} 执行完成")195        196        if isinstance(result, dict) and result.get("is_email", False):197            response = f"邮件{'已成功' if result['success'] else '未能成功'}发送到 {result['to']}。\n\n主题:{result['subject']}\n\n内容:\n{result['content']}"198            email_sent = result['success']199        elif isinstance(result, list):200            search_results = result201            messages.append({202                "role": "function",203                "name": function_name,204                "content": json.dumps(result, ensure_ascii=False)205            })206        else:207            messages.append({208                "role": "function",209                "name": function_name,210                "content": str(result)211            })212    213    # 只有在没有邮件发送结果时才调用主模型214    if not response:215        status_log.append("主模型:正在生成回答")216        final_response = get_openai_response(messages, model="gpt-4o-mini")217        response = final_response.content if final_response else "Error occurred"218        status_log.append("主模型:回答生成完成")219    220    return jsonify({221        "response": response,222        "status_log": status_log,223        "search_results": search_results,224        "search_used": bool(search_results),225        "email_sent": email_sent226    })227    228@app.route('/settings', methods=['POST'])229def update_settings():230    data = request.json231    max_history = data.get('max_history', 10)232    return jsonify({"status": "success", "max_history": max_history})233 234if __name__ == '__main__':235    app.run(host='0.0.0.0', port=7860, debug=True)236# from flask import Flask, request, jsonify, send_from_directory237# import requests238# from bs4 import BeautifulSoup239# import random240# import time241 242# app = Flask(__name__)243 244# def perform_bing_search(keywords):245#     search_term = " ".join(keywords)246#     url = "https://www.bing.com/search"247#     user_agents = [248#         "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36",249#         "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:89.0) Gecko/20100101 Firefox/89.0",250#         "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15",251#     ]252#     headers = {"User-Agent": random.choice(user_agents)}253#     params = {"q": search_term, "setlang": "zh-CN"}254    255#     response = requests.get(url, params=params, headers=headers)256#     if response.status_code == 200:257#         soup = BeautifulSoup(response.text, 'html.parser')258#         results = soup.select('.b_algo')259#         search_results = []260#         for result in results[:5]:  # 只取前5个结果261#             title = result.select_one('h2 a')262#             snippet = result.select_one('.b_caption p')263#             if title and snippet:264#                 search_results.append({265#                     "title": title.text,266#                     "url": title['href'],267#                     "snippet": snippet.text268#                 })269#         return search_results270#     return []271 272# @app.route('/')273# def index():274#     return send_from_directory('.', 'we.html')275 276# @app.route('/start_test', methods=['POST'])277# def start_test():278#     data = request.json279#     keywords = data['keywords'].split()280#     interval = int(data['interval'])281    282#     first_search = perform_bing_search(keywords)283#     time.sleep(interval)284#     second_search = perform_bing_search(keywords)285    286#     success = len(first_search) > 0 and len(second_search) > 0287#     return jsonify({288#         "success": success,289#         "first_search": first_search,290#         "second_search": second_search291#     })292 293# if __name__ == '__main__':294#     app.run(host='0.0.0.0', port=7860, debug=True)295 296