diff --git a/examples/spo/README.md b/examples/spo/README.md index 08ed6f804..8bfa3b206 100644 --- a/examples/spo/README.md +++ b/examples/spo/README.md @@ -1,5 +1,7 @@ # SPO | Self-Supervised Prompt Optimization +[![Paper](https://img.shields.io/badge/Paper-arXiv-red)](https://arxiv.org/pdf/2502.06855) +[![Demo](https://img.shields.io/badge/Demo-Hugging%20Face-yellow)](https://huggingface.co/spaces/XiangJinYu/SPO) An automated prompt engineering tool for Large Language Models (LLMs), designed for universal domain adaptation. @@ -16,7 +18,10 @@ ## ✨ Core Advantages - ⚡ **Universal Adaptation** - _Closed & open-ended tasks supported_ - 🔄 **Self-Evolving** - _Auto-optimization via LLM-as-judge mechanism_ -[Read our paper on arXiv](https://arxiv.org/pdf/2502.06855) +## 🔗 Quick Links + +- [📝 Read our paper](https://arxiv.org/pdf/2502.06855) +- [🤗 Try our demo](https://huggingface.co/spaces/XiangJinYu/SPO) ## 📊 Experiment @@ -52,7 +57,7 @@ ### 2. Define Your Iteration template 📝 count: None -faq: +qa: - question: | ... answer: | diff --git a/examples/spo/config2.example.yaml b/examples/spo/config2.example.yaml index 3afa5406b..a19d6e815 100644 --- a/examples/spo/config2.example.yaml +++ b/examples/spo/config2.example.yaml @@ -1,12 +1,25 @@ +llm: + api_type: "openai" + model: "gpt-4o-mini" + base_url: "" + api_key: "" + temperature: 0 models: - "": # model: "gpt-4-turbo" # or gpt-3.5-turbo + "gpt-4o": # model: "gpt-4-turbo" # or gpt-3.5-turbo api_type: "openai" # or azure / ollama / groq etc. - base_url: "" + base_url: "" api_key: "" temperature: 0 - "": - api_type: "openai" + "deepseek-chat": # api_type: "openai" # or azure / ollama / groq etc. + api_type: "openai" # or azure / ollama / groq etc. + base_url: "" + api_key: "" + temperature: 0 + "gpt-4o-mini": # api_type: "openai" # or azure / ollama / groq etc. + api_type: "openai" # or azure / ollama / groq etc. base_url: "" api_key: "" temperature: 0 +# Other models + diff --git a/metagpt/ext/spo/app.py b/metagpt/ext/spo/app.py index 963775be4..20895a420 100644 --- a/metagpt/ext/spo/app.py +++ b/metagpt/ext/spo/app.py @@ -15,7 +15,7 @@ def load_yaml_template(template_path: Path) -> Dict: if template_path.exists(): with open(template_path, "r", encoding="utf-8") as f: return yaml.safe_load(f) - return {"prompt": "", "requirements": "", "count": None, "faq": [{"question": "", "answer": ""}]} + return {"prompt": "", "requirements": "", "count": None, "qa": [{"question": "", "answer": ""}]} def save_yaml_template(template_path: Path, data: Dict) -> None: @@ -23,9 +23,9 @@ def save_yaml_template(template_path: Path, data: Dict) -> None: "prompt": str(data.get("prompt", "")), "requirements": str(data.get("requirements", "")), "count": data.get("count"), - "faq": [ - {"question": str(faq.get("question", "")).strip(), "answer": str(faq.get("answer", "")).strip()} - for faq in data.get("faq", []) + "qa": [ + {"question": str(qa.get("question", "")).strip(), "answer": str(qa.get("answer", "")).strip()} + for qa in data.get("qa", []) ], } @@ -76,7 +76,25 @@ def main(): if "optimization_results" not in st.session_state: st.session_state.optimization_results = [] - st.title("SPO | Self-Supervised Prompt Optimization 🤖") + st.markdown( + """ +
+
+

SPO | Self-Supervised Prompt Optimization 🤖

+
+
+ + Paper + + + GitHub + + A framework for self-supervised prompt optimization +
+
+ """, + unsafe_allow_html=True, + ) # Sidebar for configurations with st.sidebar: @@ -126,51 +144,51 @@ def main(): if "current_template" not in st.session_state or st.session_state.current_template != template_name: st.session_state.current_template = template_name - st.session_state.faqs = template_data.get("faq", []) + st.session_state.qas = template_data.get("qa", []) # Edit template sections prompt = st.text_area("Prompt", template_data.get("prompt", ""), height=100) requirements = st.text_area("Requirements", template_data.get("requirements", ""), height=100) - # FAQ section - st.subheader("FAQ Examples") + # qa section + st.subheader("Q&A Examples") - # Add new FAQ button - if st.button("Add New FAQ"): - st.session_state.faqs.append({"question": "", "answer": ""}) + # Add new qa button + if st.button("Add New Q&A"): + st.session_state.qas.append({"question": "", "answer": ""}) - # Edit FAQs - new_faqs = [] - for i in range(len(st.session_state.faqs)): - st.markdown(f"**FAQ #{i + 1}**") + # Edit qas + new_qas = [] + for i in range(len(st.session_state.qas)): + st.markdown(f"**QA #{i + 1}**") col1, col2, col3 = st.columns([45, 45, 10]) with col1: question = st.text_area( - f"Question {i + 1}", st.session_state.faqs[i].get("question", ""), key=f"q_{i}", height=100 + f"Question {i + 1}", st.session_state.qas[i].get("question", ""), key=f"q_{i}", height=100 ) with col2: answer = st.text_area( - f"Answer {i + 1}", st.session_state.faqs[i].get("answer", ""), key=f"a_{i}", height=100 + f"Answer {i + 1}", st.session_state.qas[i].get("answer", ""), key=f"a_{i}", height=100 ) with col3: if st.button("🗑️", key=f"delete_{i}"): - st.session_state.faqs.pop(i) + st.session_state.qas.pop(i) st.rerun() - new_faqs.append({"question": question, "answer": answer}) + new_qas.append({"question": question, "answer": answer}) # Save template button if st.button("Save Template"): - new_template_data = {"prompt": prompt, "requirements": requirements, "count": None, "faq": new_faqs} + new_template_data = {"prompt": prompt, "requirements": requirements, "count": None, "qa": new_qas} save_yaml_template(template_path, new_template_data) - st.session_state.faqs = new_faqs + st.session_state.qas = new_qas st.success(f"Template saved to {template_path}") st.subheader("Current Template Preview") - preview_data = {"prompt": prompt, "requirements": requirements, "count": None, "faq": new_faqs} + preview_data = {"qa": new_qas, "requirements": requirements, "prompt": prompt} st.code(yaml.dump(preview_data, allow_unicode=True), language="yaml") st.subheader("Optimization Logs") diff --git a/metagpt/ext/spo/settings/Navigate.yaml b/metagpt/ext/spo/settings/Navigate.yaml index a5d8a1651..3b20a6de9 100644 --- a/metagpt/ext/spo/settings/Navigate.yaml +++ b/metagpt/ext/spo/settings/Navigate.yaml @@ -9,7 +9,7 @@ requirements: | count: None -faq: +qa: - question: | If you follow these instructions, do you return to the starting point? Always face forward. Take 7 steps left. Take 2 steps backward. Take 7 steps backward. Take 7 steps backward. Take 3 steps forward. Options: diff --git a/metagpt/ext/spo/settings/Poem.yaml b/metagpt/ext/spo/settings/Poem.yaml index 74aa1565f..dba690c45 100644 --- a/metagpt/ext/spo/settings/Poem.yaml +++ b/metagpt/ext/spo/settings/Poem.yaml @@ -6,7 +6,7 @@ requirements: | count: None -faq: +qa: - question: | Write a modern sonnet about climate change answer: | diff --git a/metagpt/ext/spo/utils/load.py b/metagpt/ext/spo/utils/load.py index f8c4f53fc..6333b2775 100644 --- a/metagpt/ext/spo/utils/load.py +++ b/metagpt/ext/spo/utils/load.py @@ -29,7 +29,7 @@ def load_meta_data(k: int = SAMPLE_K): qa = [] - for item in data["faq"]: + for item in data["qa"]: question = item["question"] answer = item["answer"] qa.append({"question": question, "answer": answer})