from flask import Flask, request, jsonify, render_template
import requests
import json # 用于解析嵌套的 JSON 字符串app = Flask(__name__)COZE_BOT_ID = '7508736911423963162'
COZE_API_KEY = 'pat_cHXqrFzcvtktfmmlp4pjF3O2qmjioQW46uU8UNbUugyvSlFZclklpunc53DbR8ws'
COZE_API_URL = 'https://api.coze.cn/open_api/v2/chat'@app.route('/zhoushibo')
def index():return render_template('index.html')@app.route('/chat', methods=['POST'])
def chat():user_input = request.json.get('message')headers = {'Authorization': f'Bearer {COZE_API_KEY}','Content-Type': 'application/json'}payload = {'bot_id': COZE_BOT_ID,'user': 'user_001','query': user_input}response = requests.post(COZE_API_URL, headers=headers, json=payload)data = response.json()# 1. 先拿到 Coze 返回的 messages 列表messages = data.get("messages", [])# 2. 遍歷每條消息,優先返回第一條“非知識召回”類型的回復;否則把所有知識召回的 chunks 拼起來collected_chunks = [] # 用來收集所有 knowledge_recall 類型消息里的 chunksfinal_reply = "" # 要發送給前端的最終文本for msg in messages:raw_content = msg.get("content", "")# 嘗試把 raw_content 解析成 JSONtry:parsed_outer = json.loads(raw_content)msg_type = parsed_outer.get("msg_type", "")inner_data_str = parsed_outer.get("data", "")if msg_type != "knowledge_recall":# 如果這一條不是知識召回類型,直接取它的 content 當作最終回復# (不同 msg_type 里真正要呈現的聊天文本,往往在 parsed_outer["content"])final_reply = parsed_outer.get("content", raw_content)breakelse:# msg_type == "knowledge_recall",進一步解析 inner_data_str 看看有沒有 chunksif inner_data_str:parsed_inner = json.loads(inner_data_str)chunks = parsed_inner.get("chunks", [])# 如果 chunks 是列表且非空,就把這些片段收集起來if isinstance(chunks, list) and len(chunks) > 0:for chunk in chunks:# 每個 chunk 通常是 {"content": "這里是一段文本"}collected_chunks.append(chunk.get("content", ""))# 如果 inner_data_str 為 "" 或 chunks 為空,直接忽略,繼續處理下一條消息except (ValueError, json.JSONDecodeError):# 如果 raw_content 根本不是合法 JSON,就把它作為“非知識召回”類型直接返回final_reply = raw_contentbreak# 3. 如果在遍歷過程中沒有碰到“非知識召回”類型的回復,且 collected_chunks 非空,就拼接后返回if not final_reply and collected_chunks:final_reply = "".join(collected_chunks)# 4. 如果以上都沒有拿到有效文本,就返回一個默認提示if not final_reply:final_reply = "對不起,暫時無法獲取有效回復。"return jsonify({'reply': final_reply})if __name__ == '__main__':app.run(debug=True)
這是我的Flask源代碼,在Apifox的測試中僅僅只能完成傳入一個message這個消息串的簡單操作,不能傳參數。
我的原先代碼能正常運行,是因為我之前只接收了一個 message 字段,把它直接作為 query 傳遞給 Coze:
user_input = request.json.get('message')
payload = {'bot_id': COZE_BOT_ID,'user': 'user_001','query': user_input
}
這是我現在的新需求(實現多參數的輸入):
{"message": "請幫我推薦大模型","場景": "文本生成","預算": "500元"
}
如果我還是 user_input = request.json.get('message'),只會把 "請幫我推薦大模型" 傳給 Coze,其他參數全部丟失。
我需要把所有參數(如 "場景"、"預算")一起傳遞,大模型才能“理解上下文”。
而final_prompt的作用是把 message 和所有其他參數拼成一句話。
所以這里需要改兩個地方:
第一個:
將
user_input = request.json.get('message')
?改為:
# 2. 單獨提取 message,其余參數合成結構化內容user_message = data.get('message', '')params = {k: v for k, v in data.items() if k != 'message'}params_text = "\n".join([f"{k}:{v}" for k, v in params.items()]) if params else ""final_prompt = f"用戶請求:{user_message}\n{params_text}" if params_text else f"用戶請求:{user_message}"
第二個:
payload = {'bot_id': COZE_BOT_ID,'user': 'user_001','query': user_input}
?改為:
payload = {'bot_id': COZE_BOT_ID,'user': 'user_001','query': final_prompt # 改為 final_prompt}
//
如果用戶只傳了 message,那 final_prompt 也只是那一句話,對原來功能無影響。