Pārlūkot izejas kodu

feat: 添加jack6249毕业设计V1.0

jack6249 7 mēneši atpakaļ
vecāks
revīzija
1533ab49d5

+ 6 - 0
Co-creation-projects/jack6249-GiftGeniusAgent/.env example

@@ -0,0 +1,6 @@
+#大模型参数
+LLM_MODEL_ID = "yourmodel"
+LLM_API_KEY = "yourkey"
+LLM_BASE_URL = "yourbaseurl"
+#Tavily参数
+TAVILY_API_KEY = "yourTavilyKey"

+ 135 - 0
Co-creation-projects/jack6249-GiftGeniusAgent/README.md

@@ -0,0 +1,135 @@
+# 🎁 GiftGenius: 智能送礼助手
+
+基于 HelloAgents 框架的多智能体协作系统,为你提供精准、走心的礼物推荐方案。
+
+## 📝 项目简介
+
+GiftGenius 是一个智能化的礼物推荐 Agent,旨在解决“送什么礼物”这个千古难题。它不仅仅是一个简单的关键词搜索工具,而是一个模拟人类决策过程的多智能体流水线 (Multi-Agent Pipeline)。
+
+通过 军师 (策略制定) -> 猎人 (全网搜索) -> 编辑 (数据清洗与文案创作) 的分工协作,它能根据用户的 MBTI、星座、预算等个性化画像,从全网检索最新的商品信息,并生成一份图文并茂、价格透明的送礼指南。
+
+- 解决什么问题?
+
+   解决送礼时的选择困难症,以及推荐商品过时、价格超预算、文案枯燥等问题。
+
+- 有什么特色功能?
+
+   支持 MBTI/星座心理分析、自动比价与平替查找、防幻觉数据提取。
+
+- 适用于什么场景? 
+
+  节日送礼、生日惊喜、纪念日策划等需要个性化推荐的场景。
+
+## ✨ 核心功能
+
+- [x] 精准画像分析:基于 MBTI 人格、星座、年龄等维度,深度解析受礼者的潜在偏好,制定个性化搜索策略。
+
+- [x] 智能预算控制:支持自定义预算范围(如 "500-1000元"),并具备“价格守门员”机制,自动拦截超预算商品并触发降级搜索(找平替)。
+
+- [x]  实时联网搜索:利用 Tavily 搜索引擎获取 2025年最新 的商品信息、价格和图片,拒绝过时推荐。
+
+- [x] 可视化报告:最终生成包含商品图、价格参考、种草文案的 Markdown 表格,直观易读。
+
+## 🛠️ 技术栈
+
+- 框架: HelloAgents
+
+- 智能体范式:Reflection
+
+  用于从搜索结果中提取专家的数据反思和修正。
+
+- 工具与API:Tavily Search API (用于联网检索)
+
+- 其他依赖: python-dotenv, numpy (用于价格计算), jupyter
+
+## 🚀 快速开始
+
+### 环境要求
+
+Python 3.10+
+
+Jupyter Notebook / Jupyter Lab
+
+### 安装依赖
+
+```bash
+pip install -r requirements.txt
+```
+
+### 配置API密钥
+
+复制配置文件模板:
+
+```bash
+# 创建.env文件
+cp .env.example .env
+# 编辑.env文件,填入你的API密钥
+```
+
+
+
+### 运行项目
+
+修改 user_profile.json 文件,填入你的送礼对象信息(如 MBTI、预算等)。
+
+启动 Jupyter Notebook:
+
+```bash
+jupyter notebook main.ipynb
+```
+
+
+点击 "Run All" 运行所有单元格,最终结果将生成在 outputs/gift_plan_output.md 中。
+
+## 📖 使用示例
+
+输入配置 (user_profile.json):
+
+```json
+{
+    "性别": "男",
+    "年龄": "24岁",
+    "MBTI": "ISTJ",
+    "星座": "白羊座",
+    "预算": "200-500",
+    "节日": "生日",
+    "自定义": "喜欢数码"
+}
+```
+
+运行结果 (final_gift_plan.md):
+
+![example](/Co-creation-projects/jack6249-GiftGeniusAgent/example.png)
+
+## 🎯 项目亮点
+
+- 双流架构 (Dual-Stream):将“硬数据搜索”(找价格)和“软文案生成”(找卖点)拆分为两条并行流水线,大幅减少了上下文干扰,提升了文案质量。
+
+- 代码级防幻觉 (Code-based Guardrails):不依赖 LLM 直接生成 JSON,而是通过 Python 正则表达式从搜索结果中暴力提取价格和图片,从根源上杜绝了“编造价格”的幻觉。
+
+- 动态策略修正 (Feedback Loop):实现了“价格守门员”机制。如果搜到的商品均价超预算,会重新触发“军师”制定“平替”策略,直到找到合适商品为止。
+
+## 🔮 未来计划
+
+- [ ] 前端交互:新增前端页面,提供更好的用户交互体验
+
+- [ ] 数据源增强:接入百度或BigGo的MCP Server,获取更精准的实时价格和商品信息
+
+- [ ] 丰富选项:增加更多的个人喜好选项,如喜欢的商品类型、品牌等
+
+
+🤝 贡献指南
+
+欢迎提出 Issue 和 Pull Request!如果你有更好的 Prompt 优化技巧或新的 Agent 模式想法,请随时分享。
+
+📄 许可证
+
+MIT License
+
+👤 作者
+
+GitHub: [@jack6249](https://github.com/jack6249)
+
+🙏 致谢
+
+感谢 Datawhale 社区 和 Hello-Agents 项目提供的优秀框架与教程支持!

+ 9 - 0
Co-creation-projects/jack6249-GiftGeniusAgent/data/test_cases.json

@@ -0,0 +1,9 @@
+{
+    "性别": "男",
+    "年龄": "24岁",
+    "MBTI": "ISTJ",
+    "星座": "白羊座",
+    "预算": "200-500",
+    "节日": "生日",
+    "自定义": "喜欢数码"
+}

BIN
Co-creation-projects/jack6249-GiftGeniusAgent/example.png


+ 669 - 0
Co-creation-projects/jack6249-GiftGeniusAgent/main.ipynb

@@ -0,0 +1,669 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "id": "38b007c8",
+   "metadata": {},
+   "source": [
+    "\n",
+    "## GiftGeniusAgent——你的送礼智能Agent\n",
+    "\n",
+    "### 项目简介\n",
+    "本项目演示一个基于HelloAgents框架的智能送礼Agent\n",
+    "\n",
+    "### 作者信息\n",
+    "- 姓名:张善祺\n",
+    "- GitHub:@jack6249\n",
+    "- 日期:2025-11-21\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "62a3b6a3",
+   "metadata": {},
+   "source": [
+    "### 第1部分:环境配置"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "dd9b8a20",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#导入库和参数配置\n",
+    "from hello_agents import SimpleAgent, HelloAgentsLLM, ReflectionAgent\n",
+    "from hello_agents.tools import Tool, ToolParameter\n",
+    "from typing import Dict, Any, List\n",
+    "from tavily import TavilyClient\n",
+    "import os\n",
+    "import json\n",
+    "import re\n",
+    "import numpy as np \n",
+    "from dotenv import load_dotenv\n",
+    "\n",
+    "load_dotenv()\n",
+    "\n",
+    "#LLM参数\n",
+    "LLM_MODEL_ID = os.getenv(\"LLM_MODEL_ID\")\n",
+    "#\"deepseek-chat\"\n",
+    "LLM_API_KEY = os.getenv(\"LLM_API_KEY\")\n",
+    "LLM_BASE_URL = os.getenv(\"LLM_BASE_URL\")\n",
+    "#Tavily参数\n",
+    "TAVILY_API_KEY = os.getenv(\"TAVILY_API_KEY\")\n",
+    "\n",
+    "print(\"✅ 环境配置完成\")\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "27482621",
+   "metadata": {},
+   "source": [
+    "### 第2部分:定义工具"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "2087de45",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "class BatchSearchTool(Tool):\n",
+    "    def __init__(self):\n",
+    "        super().__init__(\n",
+    "            name=\"batch_search\",\n",
+    "            description=\"高级批量搜索工具。\"\n",
+    "        )\n",
+    "\n",
+    "    def search_raw(self, query: str) -> List[Dict]:\n",
+    "        if \"TAVILY_API_KEY\" not in os.environ: \n",
+    "            print(\"❌ 错误:缺少 API Key\")\n",
+    "            return []\n",
+    "\n",
+    "        print(f\"    🚀 [直连搜索] 正在抓取: {query} ...\")\n",
+    "        try:\n",
+    "            tavily = TavilyClient(api_key=os.environ[\"TAVILY_API_KEY\"])\n",
+    "            # 搜索包含图片\n",
+    "            response = tavily.search(query, max_results=5, include_images=True) # 增加到5条,提高命中率\n",
+    "            \n",
+    "            results = []\n",
+    "            # 1. 提取文本结果\n",
+    "            if 'results' in response:\n",
+    "                for r in response['results']:\n",
+    "                    results.append({\n",
+    "                        \"title\": r['title'],\n",
+    "                        \"url\": r['url'],\n",
+    "                        \"content\": r['content'], \n",
+    "                        \"type\": \"text\"\n",
+    "                    })\n",
+    "            \n",
+    "            # 2. 提取图片结果\n",
+    "            if 'images' in response and response['images']:\n",
+    "                results.append({\n",
+    "                    \"images\": response['images'][:3], # 取前3张\n",
+    "                    \"type\": \"image\"\n",
+    "                })\n",
+    "                \n",
+    "            return results\n",
+    "            \n",
+    "        except Exception as e:\n",
+    "            print(f\"      ⚠️ 搜索异常: {e}\")\n",
+    "            return []\n",
+    "    \n",
+    "    # 兼容 Agent 调用接口\n",
+    "    def run(self, parameters: Any) -> str:\n",
+    "        return \"请使用 Python 代码直接调用 search_raw 方法获取数据。\"\n",
+    "    \n",
+    "    def get_parameters(self) -> List[ToolParameter]:\n",
+    "        return [ToolParameter(name=\"query\", type=\"string\", description=\"关键词\", required=True)]\n",
+    "\n",
+    "print(\"✅ BatchSearchTool定义完成\")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "e8ffecb0",
+   "metadata": {},
+   "source": [
+    "### 第3部分:创建智能体\n",
+    "\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "6c5a2e82",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from hello_agents import ToolRegistry\n",
+    "\n",
+    "#创建工具\n",
+    "tool_registry = ToolRegistry()\n",
+    "tool_registry.register_tool(BatchSearchTool())\n",
+    "\n",
+    "print(tool_registry.list_tools())\n",
+    "\n",
+    "\n",
+    "# 初始化大模型\n",
+    "llm = HelloAgentsLLM()\n",
+    "\n",
+    "# --- 1. 军师 (Profiler) - 已升级支持多维度画像 ---\n",
+    "PROFILER_PROMPT = \"\"\"\n",
+    "你是一个精通 MBTI 人格分析与消费市场趋势的 \"送礼军师\"。\n",
+    "你的任务是根据用户提供的多维度画像,制定 3 个**极度精准**的搜索关键词。\n",
+    "\n",
+    "【⚠️ 时效性死命令 (CRITICAL)】\n",
+    "当前时间视作 **2025年11月**。\n",
+    "1. **严禁过时**:绝对不要推荐 2024 年或更早的旧款(除非是经典恒久款如黑胶唱片)。\n",
+    "2. **锁定新品**:对于**化妆品、数码、盲盒**,必须搜索 **\"2025圣诞限定\"**、**\"2025秋冬新品\"** 或 **\"2026春季预告\"**。\n",
+    "3. **价格尺度**:给出的价格单位是人民币元。请严格遵照范围进行联想,禁止超出预算范围。\n",
+    "\n",
+    "为了确保推荐质量,请参考以下的【优秀思考范例】:\n",
+    "\n",
+    "### 范例 1\n",
+    "**用户画像**: \n",
+    "- 女, 26岁, ISFP (探险家), 金牛座\n",
+    "- 预算: 500-1000元\n",
+    "- 场景: 情人节\n",
+    "- 自定义: 喜欢有质感的生活小物\n",
+    "**军师分析**: \n",
+    "ISFP 重视审美和感官体验,金牛座喜欢实实在在的质感。情人节需要浪漫。\n",
+    "**生成策略**:\n",
+    "1. 观夏 (To Summer) 昆仑煮雪 晶石香薰 (符合质感与审美)\n",
+    "2. 野兽派 2025 情人节限定 睡衣礼盒 (金牛座喜欢的舒适)\n",
+    "3. 富士 Instax mini Evo 拍立得 (记录生活瞬间)\n",
+    "\n",
+    "### 范例 2\n",
+    "**用户画像**: \n",
+    "- 男, 30岁, INTJ (建筑师), 处女座\n",
+    "- 预算: 1000元以上\n",
+    "- 场景: 生日\n",
+    "- 自定义: 程序员,喜欢整洁\n",
+    "**军师分析**: \n",
+    "INTJ 追求极致的逻辑和效率,处女座有洁癖,喜欢桌面整洁。\n",
+    "**生成策略**:\n",
+    "1. Keychron Q1 Pro 机械键盘 铝坨坨 (符合极客对工具的追求)\n",
+    "2. 明基 (BenQ) ScreenBar Halo 屏幕挂灯 (极致护眼与桌面美学)\n",
+    "3. 赫曼米勒 (Herman Miller) 显示器支架 (人体工学)\n",
+    "\n",
+    "### 范例 3\n",
+    "**用户画像**: \n",
+    "- 女, 20岁, ENFP (竞选者), 狮子座\n",
+    "- 预算: 300元以内\n",
+    "- 场景: 圣诞节\n",
+    "- 自定义: 喜欢二次元,痛包\n",
+    "**军师分析**: \n",
+    "ENFP 热情奔放,狮子座喜欢张扬、闪亮的东西。预算有限但要素多。\n",
+    "**生成策略**:\n",
+    "1. 泡泡玛特 圣诞系列 盲盒整端 (符合节日气氛和二次元)\n",
+    "2. WEGO 痛包 镭射款 (符合自定义需求,狮子座喜欢的亮眼)\n",
+    "3.  Chiikawa 吉伊卡哇 圣诞公仔 (当下顶流二次元IP)\n",
+    "\n",
+    "---\n",
+    "\n",
+    "**现在的任务**:\n",
+    "请根据以下【当前用户画像】进行分析,模仿上述范例的深度,制定搜索策略。\n",
+    "\n",
+    "【当前用户画像】\n",
+    "{user_profile_text}\n",
+    "\n",
+    "【关键词生成要求】\n",
+    "1. **必须具体**:格式为 `[品牌] + [产品名/系列] + [限定/属性]`。\n",
+    "2. **拒绝大词**:严禁搜索 \"礼物\"、\"口红\"、\"玩具\" 这种泛词。\n",
+    "3. **必须包含品牌**:根据预算推断合适的品牌(如:预算低选名创优品/泡泡玛特,预算高选Dior/索尼)。\n",
+    "\n",
+    "【输出格式】\n",
+    "只输出 3 行搜索关键词,每行一个。不要输出分析过程,不要序号。\n",
+    "\"\"\"\n",
+    "\n",
+    "profiler_agent = SimpleAgent(\n",
+    "    llm=llm,\n",
+    "    name=\"Agent_Profiler\",\n",
+    "    system_prompt=PROFILER_PROMPT\n",
+    ")\n",
+    "\n",
+    "# ==============================================================================\n",
+    "# 2. 提取专家 (Extractor) - 数据清洗 (加入反思机制)\n",
+    "# ==============================================================================\n",
+    "EXTRACTOR_PROMPTS = {\n",
+    "    \"initial\": \"\"\"\n",
+    "    你是一个 **纯粹的数据提取器**。\n",
+    "    你的任务是从 `<<<原始数据>>>` 中提取商品参数。\n",
+    "\n",
+    "    ### 🧠 CoT 提取逻辑\n",
+    "    1.  **扫描**: 快速浏览文本,寻找 \"¥\", \"$\", \"http\" 等关键符号。\n",
+    "    2.  **验证**: 确认找到的信息是否属于\"核心商品\"(而非广告推荐)。\n",
+    "    3.  **格式化**: 将提取到的信息填入 JSON。\n",
+    "\n",
+    "    ### 🚫 绝对禁令\n",
+    "    1.  **严禁伪造**: 没找到价格就填 \"暂无报价\",绝对不要编数字!\n",
+    "    2.  **严禁 API 格式**: 不要输出 `{{ \"status\": ... }}`。\n",
+    "    3.  **严禁 Markdown**: 直接输出列表 `[...]`。\n",
+    "\n",
+    "    ### ✅ 正确范例\n",
+    "    输入: ...Dior 口红...价格 ¥350...图片 http://img...\n",
+    "    输出:\n",
+    "    [\n",
+    "        {{\n",
+    "            \"name\": \"Dior 口红\",\n",
+    "            \"price\": \"¥350\",\n",
+    "            \"img\": \"http://img...\"\n",
+    "        }}\n",
+    "    ]\n",
+    "\n",
+    "    ---\n",
+    "    <<<原始数据开始>>>\n",
+    "    {task}\n",
+    "    <<<原始数据结束>>>\n",
+    " \n",
+    "    请提取数据并输出 JSON 列表:\n",
+    "    \"\"\",\n",
+    "    \"reflect\": \"检查输出:是否以 `[` 开头?是否包含幻觉商品?\",\n",
+    "    \"refine\": \"修正格式,只输出纯净的 JSON 列表 `[...]`。\"\n",
+    "}\n",
+    "\n",
+    "extractor_agent = ReflectionAgent(\n",
+    "    name=\"Agent_Extractor\",\n",
+    "    llm=llm,\n",
+    "    max_iterations=1, \n",
+    "    custom_prompts=EXTRACTOR_PROMPTS\n",
+    ")\n",
+    "\n",
+    "# ==============================================================================\n",
+    "# 3. 种草达人 (Pitcher) - 文案创作 (加入风格指导)\n",
+    "# ==============================================================================\n",
+    "PITCHER_PROMPT = \"\"\"\n",
+    "你是一个 **金牌种草文案**。\n",
+    "用户会给你一个 **【商品名称】**。\n",
+    "\n",
+    "### 🎯 关键要点 (Few Points)\n",
+    "1.  **痛点直击**: 一句话说清楚为什么买它(限定?显白?绝美?)。\n",
+    "2.  **情绪价值**: 使用 \"绝绝子\", \"氛围感\", \"心动\" 等高频热词。\n",
+    "3.  **字数限制**: 严格控制在 **40字以内**,短小精悍。\n",
+    "4.  **Emoji**: 必须包含 1-2 个 emoji。\n",
+    "\n",
+    "### 🌟 创作范例 (Few-Shot)\n",
+    "**输入**: Dior 999 烈艳蓝金\n",
+    "**输出**: 💄本宫不死终是妃!Dior 999 传奇正红,显白更有气场,送女友绝对没错!\n",
+    "\n",
+    "**输入**: 泡泡玛特 Labubu 坐坐派对\n",
+    "**输出**: ✨太可爱了吧!Labubu 坐坐派对系列,每一个都丑萌到心巴上,摆在桌上超治愈~\n",
+    "\n",
+    "**输入**: 罗技 MX Master 3S\n",
+    "**输出**: 🖱️打工人本命!罗技 Master 3S 静音又顺滑,人体工学设计,手腕再也不累了。\n",
+    "\n",
+    "---\n",
+    "\n",
+    "**当前任务**:\n",
+    "请为【{input}】写一句朋友圈风格种草语。\n",
+    "\"\"\"\n",
+    "pitcher_agent = SimpleAgent(\n",
+    "    llm=llm,\n",
+    "    name=\"Agent_Pitcher\",\n",
+    "    system_prompt=PITCHER_PROMPT\n",
+    ")\n",
+    "\n",
+    "print(\"✅ 智能体初始化完成!\")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "25907c14",
+   "metadata": {},
+   "source": [
+    "### 第4部分:读取数据"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "58bd39dd",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "\n",
+    "INPUT_FILENAME = \"data/test_cases.json\"\n",
+    "\n",
+    "def load_user_profile(filename):\n",
+    "    # 1. 检查文件是否存在\n",
+    "    if not os.path.exists(filename):\n",
+    "        print(f\"⚠️ 未找到配置文件: {filename}\")\n",
+    "        # 如果没有文件,将默认数据写入文件\n",
+    "        default_data = {\n",
+    "            \"性别\": \"女\",\n",
+    "            \"年龄\": \"24岁\",\n",
+    "            \"MBTI\": \"ENFP\",\n",
+    "            \"星座\": \"天秤座\",\n",
+    "            \"预算\": \"500元以内\",\n",
+    "            \"节日\": \"恋爱一周年纪念日\",\n",
+    "            \"自定义\": \"喜欢二次元,平时喜欢喝咖啡,不要送太实用的家电\"\n",
+    "        }\n",
+    "        with open(filename, \"w\", encoding=\"utf-8\") as f:\n",
+    "            json.dump(default_data, f, ensure_ascii=False, indent=4)\n",
+    "        print(f\"✅ 已自动生成默认配置文件,请修改 {filename} 后再次运行。\")\n",
+    "        return default_data\n",
+    "\n",
+    "    # 2. 读取文件内容\n",
+    "    try:\n",
+    "        with open(filename, \"r\", encoding=\"utf-8\") as f:\n",
+    "            data = json.load(f)\n",
+    "        print(f\"✅ 成功加载用户画像: {filename}\")\n",
+    "        print(f\"📋 内容预览: {json.dumps(data, ensure_ascii=False)}\")\n",
+    "        return data\n",
+    "    except Exception as e:\n",
+    "        print(f\"❌ 读取 JSON 失败: {e}\")\n",
+    "        return {}\n",
+    "\n",
+    "# 加载数据\n",
+    "user_input_data = load_user_profile(INPUT_FILENAME)\n",
+    "\n",
+    "\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "0fdcab5a",
+   "metadata": {},
+   "source": [
+    "### 第5部分:生成礼物计划"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "cdaef6b1",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "\n",
+    "def parse_budget_range(budget_str):\n",
+    "    \"\"\"解析用户预算字符串,返回 (min, max)\"\"\"\n",
+    "    nums = [float(x) for x in re.findall(r'\\d+', str(budget_str).replace(',', ''))]\n",
+    "    if not nums: return 0, 999999 \n",
+    "    if \"以内\" in budget_str or \"以下\" in budget_str: return 0, nums[0]\n",
+    "    if \"以上\" in budget_str: return nums[0], 999999\n",
+    "    if len(nums) >= 2: return min(nums), max(nums)\n",
+    "    return 0, nums[0]\n",
+    "\n",
+    "def extract_all_prices(raw_results):\n",
+    "    \"\"\"从搜索结果列表中提取所有有效的价格\"\"\"\n",
+    "    prices = []\n",
+    "    for res in raw_results:\n",
+    "        # 只处理文本类型的结果\n",
+    "        if res.get('type') == 'text':\n",
+    "            text = res.get('title', '') + \" \" + res.get('content', '')\n",
+    "            # 匹配 ¥, $, 元 等格式\n",
+    "            matches = re.findall(r'(?:¥|¥|\\$|HK\\$|NT\\$)\\s*(\\d+(?:,\\d{3})*(?:\\.\\d+)?)', text)\n",
+    "            for m in matches:\n",
+    "                val = float(m.replace(',', ''))\n",
+    "                # 过滤掉像年份(2025)或过小/过大的异常值\n",
+    "                if 10 < val < 100000 and val not in [2024, 2025, 2026]:\n",
+    "                    prices.append(val)\n",
+    "            # 备用正则:匹配 \"xxx元\"\n",
+    "            matches_yuan = re.findall(r'(\\d+(?:,\\d{3})*(?:\\.\\d+)?)\\s*元', text)\n",
+    "            for m in matches_yuan:\n",
+    "                val = float(m.replace(',', ''))\n",
+    "                if 10 < val < 100000 and val not in [2024, 2025, 2026]:\n",
+    "                    prices.append(val)\n",
+    "    return prices\n",
+    "\n",
+    "def find_best_product(hunter, profiler_agent, keyword, budget_limit):\n",
+    "    \"\"\"\n",
+    "    智能搜索核心函数:包含 初次搜索 -> 价格校验 -> 策略修正 -> 自动降级 -> 智能兜底\n",
+    "    \"\"\"\n",
+    "    # 容器:用于收集所有搜索到的潜在结果(用于兜底)\n",
+    "    all_candidates = []\n",
+    "    current_kw = keyword\n",
+    "    \n",
+    "    # --- Round 1: 首次搜索 ---\n",
+    "    print(f\"       🕵️ 第1次搜索: {current_kw} 价格\")\n",
+    "    results_1 = hunter.search_raw(f\"{current_kw} 价格 RMB\")\n",
+    "    \n",
+    "    # 提取第一轮搜索到的通用图片(以防具体条目没图)\n",
+    "    fallback_img = \"\"\n",
+    "    for r in results_1:\n",
+    "        if r.get('images'): \n",
+    "            fallback_img = r['images'][0]\n",
+    "            break\n",
+    "\n",
+    "    # 检查 Round 1 结果\n",
+    "    for res in results_1:\n",
+    "        if res.get('type') == 'text':\n",
+    "            p_vals = extract_all_prices([res])\n",
+    "            if p_vals:\n",
+    "                res['price_val'] = p_vals[0]\n",
+    "                all_candidates.append(res) # 存入候选池\n",
+    "                if p_vals[0] <= budget_limit:\n",
+    "                    # 完美命中!\n",
+    "                    if not res.get('img') and fallback_img: res['img'] = fallback_img\n",
+    "                    return res, f\"约 {p_vals[0]}元\", current_kw\n",
+    "\n",
+    "    # --- Round 2: 策略修正 (Feedback Loop) ---\n",
+    "    # 只有当找到了价格但都超标时,才触发修正\n",
+    "    avg_price = np.mean([c['price_val'] for c in all_candidates]) if all_candidates else 0\n",
+    "    \n",
+    "    if avg_price > budget_limit:\n",
+    "        print(f\"       💸 价格超标 (均价 {int(avg_price)} > 预算 {int(budget_limit/1.2)}),触发修正...\")\n",
+    "        \n",
+    "        correction_prompt = f\"\"\"\n",
+    "        原策略 \"{current_kw}\" 市场均价约 {int(avg_price)}元,超预算。\n",
+    "        请推荐一个 **同品类但更便宜** 的具体型号(平替)。\n",
+    "        只输出关键词,不要解释。\n",
+    "        \"\"\"\n",
+    "        new_kw = profiler_agent.run(correction_prompt).strip()\n",
+    "        print(f\"       🔄 军师修正策略为: {new_kw}\")\n",
+    "        current_kw = new_kw # 更新关键词\n",
+    "        \n",
+    "        # 执行第二次搜索\n",
+    "        results_2 = hunter.search_raw(f\"{new_kw} 价格 RMB\")\n",
+    "        \n",
+    "        # 提取第二轮的图片\n",
+    "        for r in results_2:\n",
+    "            if r.get('images'): \n",
+    "                fallback_img = r['images'][0]\n",
+    "                break\n",
+    "        \n",
+    "        # 检查 Round 2 结果\n",
+    "        for res in results_2:\n",
+    "            if res.get('type') == 'text':\n",
+    "                p_vals = extract_all_prices([res])\n",
+    "                if p_vals:\n",
+    "                    res['price_val'] = p_vals[0]\n",
+    "                    all_candidates.append(res) \n",
+    "                    if p_vals[0] <= budget_limit:\n",
+    "                        if not res.get('img') and fallback_img: res['img'] = fallback_img\n",
+    "                        return res, f\"约 {p_vals[0]}元 (平替)\", current_kw\n",
+    "\n",
+    "    # --- Round 3: 智能兜底 ---\n",
+    "    # 既然都没完美匹配,就从候选池里挑一个最便宜的,或者直接硬取第一个\n",
+    "    \n",
+    "    best_fallback = None\n",
+    "    status_msg = \"暂无报价\"\n",
+    "    \n",
+    "    if all_candidates:\n",
+    "        # 按价格排序,取最低的那个\n",
+    "        best_fallback = sorted(all_candidates, key=lambda x: x['price_val'])[0]\n",
+    "        status_msg = f\"约 {best_fallback['price_val']}元 (⚠️超预算)\"\n",
+    "    elif results_1:\n",
+    "        # 连价格都没搜到,就硬取第一条文本结果\n",
+    "        for res in results_1:\n",
+    "            if res.get('type') == 'text':\n",
+    "                best_fallback = res\n",
+    "                break\n",
+    "    \n",
+    "    if best_fallback:\n",
+    "        # 补图逻辑\n",
+    "        if not best_fallback.get('img') and fallback_img:\n",
+    "            best_fallback['img'] = fallback_img\n",
+    "        return best_fallback, status_msg, current_kw\n",
+    "        \n",
+    "    return None, \"搜索失败\", current_kw\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "4ec82cc7",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# ==========================================\n",
+    "# 🚀 主执行流程\n",
+    "# ==========================================\n",
+    "\n",
+    "if not user_input_data:\n",
+    "    print(\"❌ 未加载用户数据\")\n",
+    "else:\n",
+    "    # 0. 解析预算\n",
+    "    budget_min, budget_max = parse_budget_range(user_input_data.get('预算', ''))\n",
+    "    budget_limit = budget_max * 1.2 # 允许超标 20%\n",
+    "    print(f\"\\n💰 预算红线: {budget_max}元 (容忍至 {budget_limit}元)\")\n",
+    "\n",
+    "    # 1. 军师制定策略\n",
+    "    profile_text = \"\\n\".join([f\"- {k}: {v if v else '未知/不限'}\" for k, v in user_input_data.items()])\n",
+    "    print(f\"\\n🚀 任务启动...\\n{'-'*40}\")\n",
+    "    print(\"\\n🧠 [1/3] 军师正在制定初步策略...\")\n",
+    "    search_strategy = profiler_agent.run(f\"请根据以下用户画像制定搜索策略:\\n\\n{profile_text}\")\n",
+    "    print(f\"📝 策略: \\n{search_strategy}\")\n",
+    "\n",
+    "    # 2. 准备循环\n",
+    "    keywords = [k.strip() for k in search_strategy.replace(\",\", \",\").replace(\"\\n\", \",\").split(',') if k.strip()]\n",
+    "    final_items = []\n",
+    "    hunter = BatchSearchTool()\n",
+    "\n",
+    "    print(f\"\\n🔄 进入处理流程 (共 {len(keywords)} 个商品)...\")\n",
+    "\n",
+    "    for index, kw in enumerate(keywords):\n",
+    "        print(f\"\\n    👉 [商品 {index+1}/{len(keywords)}] 正在处理: {kw}\")\n",
+    "        \n",
+    "        # 调用智能搜索函数\n",
+    "        valid_result, price_status, final_kw = find_best_product(hunter, profiler_agent, kw, budget_limit)\n",
+    "        \n",
+    "        if not valid_result:\n",
+    "            print(\"       ❌ 彻底无数据,跳过。\")\n",
+    "            continue\n",
+    "            \n",
+    "        # === 生成文案 ===\n",
+    "        product_name = valid_result.get('title', final_kw)\n",
+    "        \n",
+    "        print(f\"       ✍️ 正在撰写文案: {product_name[:15]}...\")\n",
+    "        pitch_prompt = f\"\"\"\n",
+    "        商品:{product_name}\n",
+    "        价格:{price_status}\n",
+    "        卖点片段:{valid_result.get('content', '')[:200]}...\n",
+    "        \n",
+    "        请写一句30字以内的种草文案。\n",
+    "        \"\"\"\n",
+    "        pitch = pitcher_agent.run(pitch_prompt)\n",
+    "        \n",
+    "        # 整理最终数据\n",
+    "        final_items.append({\n",
+    "            \"name\": final_kw, \n",
+    "            \"title_full\": product_name,\n",
+    "            \"price\": price_status,\n",
+    "            \"desc\": pitch.replace(\"\\n\", \" \").strip(),\n",
+    "            \"img\": valid_result.get('img', ''),\n",
+    "            \"link\": valid_result.get('url', '')\n",
+    "        })\n",
+    "        print(f\"       ✅ 已收录 (状态: {price_status})\")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "0197ef43",
+   "metadata": {},
+   "source": [
+    "\n",
+    "### 第6部分:输出礼物计划"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "8426fb13",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# --- 4. 渲染与保存 (保持不变) ---\n",
+    "print(f\"\\n💾 正在生成最终报告...\")\n",
+    "if not final_items:\n",
+    "    final_md = \"很抱歉,网络搜索似乎出现了问题,未能获取到任何商品信息。\"\n",
+    "else:\n",
+    "    table_header = \"| 🎁 礼物名称 | 💰 价格 | ✨ 种草理由 | 🖼️ 图片/链接 |\\n| :--- | :--- | :--- | :--- |\\n\"\n",
+    "    table_rows = []\n",
+    "    for item in final_items:\n",
+    "        name = item['name'].replace(\"|\", \"/\")\n",
+    "        price = item['price']\n",
+    "        desc = item['desc'].replace(\"|\", \"/\")\n",
+    "        link = item['link']\n",
+    "        img = item['img']\n",
+    "        \n",
+    "        if img and img.startswith(\"http\"):\n",
+    "            media = f\"[![图]({img})]({link})\"\n",
+    "        else:\n",
+    "            media = f\"[点击购买]({link})\"\n",
+    "        \n",
+    "        table_rows.append(f\"| [{name}]({link}) | {price} | {desc} | {media} |\")\n",
+    "    final_md = table_header + \"\\n\".join(table_rows)\n",
+    "filename = \"outputs/gift_plan_output.md\"\n",
+    "with open(filename, \"w\", encoding=\"utf-8\") as f:\n",
+    "    f.write(final_md)\n",
+    "print(f\"🎉 任务完成!文件已保存: {os.path.abspath(filename)}\")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "d8b884b5",
+   "metadata": {},
+   "source": [
+    "### 第7部分:总结与展望"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "08b0b8e8",
+   "metadata": {},
+   "source": [
+    "#### 实现的功能\n",
+    "- 基于用户输入的个人信息,生成符合预算的礼物建议\n",
+    "- 支持用户自定义预算范围、节日、个人喜好等\n",
+    "- 利用搜索引擎获取最新的商品信息和价格\n",
+    "- 提供可视化的建议结果展示\n",
+    "#### 遇到的挑战\n",
+    "- 如何解决大模型的幻觉问题\n",
+    "- 如何解决上下文过长导致提取失败\n",
+    "- 如何设计合理的提示词,优化大模型的输出\n",
+    "\n",
+    "#### 未来改进方向\n",
+    "- 前端交互:新增前端页面,提供更好的用户交互体验\n",
+    "- 数据源增强:接入百度或BigGo的MCP Server,获取更精准的实时价格和商品信息\n",
+    "- 丰富选项:增加更多的个人喜好选项,如喜欢的商品类型、品牌等\n"
+   ]
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "ai_3.10",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.10.19"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}

+ 5 - 0
Co-creation-projects/jack6249-GiftGeniusAgent/outputs/gift_plan_output.md

@@ -0,0 +1,5 @@
+| 🎁 礼物名称 | 💰 价格 | ✨ 种草理由 | 🖼️ 图片/链接 |
+| :--- | :--- | :--- | :--- |
+| [罗技 M720 无线鼠标 2025商务版](https://finance.sina.com.cn/tech/roll/2025-10-01/doc-infskwan1349321.shtml) | 约 711.0元 (⚠️超预算) | 🖱️新款MX Master 3S蓝牙直连,省去接收器烦恼,办公党福音! | [![图](https://img12.360buyimg.com/n1/jfs/t1/342700/23/8550/37781/68db9c62F3c91cc49/4b2932c48df6f477.jpg)](https://finance.sina.com.cn/tech/roll/2025-10-01/doc-infskwan1349321.shtml) |
+| [Anker 737 移动电源 240W快充](https://www.taobao.com/list/item/dEpRSkN3aG1FZkthNmtza2dNU0ZMQT09.htm) | 约 599.0元 | ⚡安克737充电宝,140W双向快充,大容量可上飞机,出行必备神器! | [![图](https://gw.alicdn.com/imgextra/i1/844902603/O1CN01AGxtg51V6DnKFmX92_!!844902603.jpg_Q75.jpg_.webp)](https://www.taobao.com/list/item/dEpRSkN3aG1FZkthNmtza2dNU0ZMQT09.htm) |
+| [索尼 WH-CH720N 降噪耳机 2025新色](https://dcdv.zol.com.cn/940/9405436.html) | 约 359.0元 | 🎧索尼CH720N无线降噪耳机,防水设计运动无忧,359元性价比绝了! | [![图](https://dwfavn5d0m4r1.cloudfront.net/App_Images/750/ChannelProduct/2025/0820/m_bf07ed79-3942-4160-9fc3-abff392844cd.jpg.webp)](https://dcdv.zol.com.cn/940/9405436.html) |

+ 18 - 0
Co-creation-projects/jack6249-GiftGeniusAgent/requirements.txt

@@ -0,0 +1,18 @@
+#HelloAgents框架
+
+hello-agents[all]>=0.1.0
+
+#LLM与搜索工具
+
+openai
+tavily-python
+numpy
+
+#Jupyter环境
+
+jupyter>=1.0.0
+notebook>=7.0.0
+
+#环境变量管理
+
+python-dotenv>=1.0.0