基于DeepSeek的美妆Agent开发

作为一名极具责任感的现代青年,在约会时精心雕琢着装风格,绝非仅仅为了展现个人的时尚品位,它更深层次的意义在于,这是对约会对象细致入微的尊重与体贴。然而,如何精准拿捏着装风格的分寸,使之既符合自身气质,又能契合约会氛围,无疑是一大挑战。为此,我们将巧妙借助外部资源,运用高效且精准的信息检索技术,广泛搜集关键数据,同时融合个人的审美见解与缜密的逻辑分析能力,从而打造出令人眼前一亮的约会装扮。自动化获取天气数据如图5-3所示。

图5-3  自动化获取天气数据

在本节中,我们将重点聚焦于开发一款基于图形用户界面(GUI)的智能助手(Agent)。这款智能助手将作为约会装扮的得力参谋,通过智能化的分析与建议,助力用户在实践中不断优化约会装扮策略,轻松应对各种约会场合。

值得一提的是,对于习惯依赖DeepSeek等先进工具来解决复杂问题的用户来说,其卓越的语义解析与逻辑推理能力,确实能在多数情况下迅速给出令人满意的答案。但在实际应用过程中,我们也发现,由于系统回答主要基于预训练知识库,这一静态特性使得其在面对实时数据查询、动态网页信息获取或高度个性化需求时,往往显得力不从心,难以触及问题的核心与本质。

5.2.1  GUI Agent库的安装与使用

首先从项目角度来说,我们需要此处完成的任务是基于浏览器GUI完成对任务项目进行搜索。在开始之前我们需要安装对应的依赖包,首先是通过pipx安装uv辅助包,打开Miniconda Prompt窗口,依次执行如下命令:

python -m pip install --user pipx
python -m pipx ensurepath
pipx install uv

全部安装结束后,我们关闭Miniconda Prompt窗口,再重新打开,让环境变量生效。最后确认UV是否成功安装,命令行如下所示:

uv --version

结果中返回uv版本信息后,第一步uv安装完成,如图5-4所示。

接下来是browser-use搜索库的安装,此时可以使用如下命令进行安装:

pip install browser-use

安装完毕后,界面如图5-5所示。browser-use的核心功能是通过LLM的推理能力分析浏览器页面的HTML内容和文本信息,输出可执行的指令,交给浏览器自动化工具(Playwright)执行。

图5-4  uv安装完毕

图5-5  browser-use的安装

而Playwright的安装如下所示:

pip install playwright

安装完毕后需要执行一些初始化操作,命令行如下:

playwright install

此时我们就可以静待安装结束,部分结果如图5-6所示。


图5-6  Playwright的安装

这时候Playwright会安装Chromium、Firefox和WebKit浏览器并配置一些驱动,我们不必关心中间配置的过程,Playwright会为我们配置好。安装完成之后,我们便可以使用Playwright启动Chromium或Firefox或WebKit浏览器来进行自动化操作了。

下面这个简单的示例将使用Playwright实现浏览器的调用,代码如下:

from playwright.sync_api import sync_playwright
with sync_playwright() as p:
    for browser_type in [p.chromium, p.firefox, p.webkit]:
        browser = browser_type.launch(headless=False)
        page = browser.new_page()
        page.goto('https://www.baidu.com')
        page.screenshot(path=f'screenshot-{browser_type.name}.png')
        print(page.title())
        browser.close()

我们分别尝试调用了3个浏览器,并使用page的一系列API来进行各种自动化操作。比如调用goto方法加载某个页面,这里我们访问的是百度搜索的首页。接着我们调用了page的screenshot方法,参数传一个文件名称,这样截图就会自动保存为该图像名称并且打印出页面的名称,读者可以自行尝试。

使用DeepSeek自动化获取网页端天气信息

下面我们将要完成结合DeepSeek的自动化天气获取。从获取途径上,我们可以首选通过API从对应的网页上获取对应的数据。然而这种方法固然可行,但是对于更多的任务,可能无法获取对应的特定结果。

对于普通的获取天气信息的操作,人工更多的是通过网页获取。因此在具体操作上,我们尝试模仿人工习惯完成从网页获取天气数据。完整代码如下所示:

from langchain_openai import ChatOpenAI
from browser_use import Agent
from dotenv import load_dotenv
import os
load_dotenv()
import asyncio
api_key = "sk-282074c41d594514aee6fx6f179ed292"		#从DeepSeek获取的API
base_url = "https://api.deepseek.com/beta"
model = "deepseek-chat"							#调用的DeepSeek模型
city = "上海"
task = f"""
从下面的网页地址:
https://www.bing.com/search?q={city}天气&mkt=zh-CN
获取天气情况,并总结出明天的天气变化和注意事项。
"""
llm = ChatOpenAI(model=model, api_key=api_key, base_url=base_url)
async def main():
    agent = Agent(
        task=task,
        llm=llm,
        use_vision=False,
    )
    result = await agent.run()
    print("---------------------------------------")
    print(result)
    print("---------------------------------------")
asyncio.run(main())

在上面代码中,我们首先通过browser_use调用了一个Agent,之后确定了一个新的任务task,即从特定的网页获取目标城市的名称,执行天气查询任务,并总结一下明天的天气和注意事项。运行结果如下所示(根据网络配置和个人硬件,Agent默认启动后运行可能会很慢):

INFO     [agent] ? Step 1
INFO     [agent] ? Eval: Unknown - Starting the task
INFO     [agent] ? Memory: Starting the task to get weather information for Shanghai. 0 out of 10 steps completed.
INFO     [agent] ? Next goal: Navigate to the Bing search page for Shanghai weather
INFO     [agent] ?️  Action 1/1: {"go_to_url":{"url":"https://www.bing.com/search?q=上海天气&mkt=zh-CN"}}
INFO     [controller] ?  Navigated to https://www.bing.com/search?q=上海天气&mkt=zh-CN
INFO     [agent] ? Step 2
INFO     [agent] ? Eval: Success - Navigated to the Bing search page for Shanghai weather
INFO     [agent] ? Memory: Navigated to the Bing search page for Shanghai weather. 1 out of 10 steps completed.
INFO     [agent] ? Next goal: Extract the weather information for tomorrow
INFO     [agent] ?️  Action 1/1: {"extract_content":{"goal":"Extract the weather information for tomorrow"}}
INFO     [controller] ?  Extracted from page
: '''json
{
  "weather_tomorrow": {
    "date": "周四 20",
    "temperature": {
      "high": "20°C",
      "low": "8°C"
    },
    "condition": "晴",
    "wind": {
      "speed": "6 公里/小时",
      "direction": "北"
    },
    "humidity": "32%"
  },
  "source": "MSN 天气",
  "additional_info": {
    "sunrise": "06:01",
    "sunset": "18:05",
    "uv_index": "2,低"
  }
}
'''
INFO     [agent] ? Step 3
INFO     [agent] ? Eval: Success - Extracted the weather information for tomorrow
INFO     [agent] ? Memory: Extracted the weather information for tomorrow. 2 out of 10 steps completed.
INFO     [agent] ? Next goal: Summarize the weather changes and precautions for tomorrow
INFO     [agent] ?️  Action 1/1: {"done":{"text":"明天的天气情况如下:\n- 日期: 周四 20\n- 温度: 最高 20°C,最低 8°C\n- 天气状况: 晴\n- 风速: 6 公里/小时,北\n- 湿度: 32%\n- 日出: 06:01\n- 日落: 18:05\n- 紫外线指数: 2,低\n\n注意事项:\n- 天气晴朗,适合户外活动,但早晚温差较大,请注意保暖。\n- 紫外线指数较低,但仍建议做好防晒措施。\n- 风速较小,适合进行户外运动。","success":true}}
INFO     [agent] ? Result: 明天的天气情况如下:
- 日期: 周四 20
- 温度: 最高 20°C,最低 8°C
- 天气状况: 晴
- 风速: 6 公里/小时,北
- 湿度: 32%
- 日出: 06:01
- 日落: 18:05
- 紫外线指数: 2,低
注意事项:
- 天气晴朗,适合户外活动,但早晚温差较大,请注意保暖。
- 紫外线指数较低,但仍建议做好防晒措施。
- 风速较小,适合进行户外运动。
INFO     [agent] ✅ Task completed
INFO     [agent] ✅ Successfully
---------------------------------------
AgentHistoryList(all_results=[ActionResult(is_done=False, success=None, extracted_content='?  Navigated to https://www.bing.com/search?q=上海天气&mkt=zh-CN', error=None, include_in_memory=True), ActionResult(is_done=False, success=None, extracted_content='?  Extracted from page\n: '''json\n{\n  "weather_tomorrow": {\n    "date": "周四 20",\n    "temperature": {\n      "high": "20°C",\n      "low": "8°C"\n    },\n    "condition": "晴",\n    "wind": {\n      "speed": "6 公里/小时",\n      "direction": "北"\n    },\n    "humidity": "32%"\n  },\n  "source": "MSN 天气",\n  "additional_info": {\n    "sunrise": "06:01",\n    "sunset": "18:05",\n    "uv_index": "2,低"\n  }\n}\n'''\n', error=None, include_in_memory=True), ActionResult(is_done=True, success=True, extracted_content='明天的天气情况如下:\n- 日期: 周四 20\n- 温度: 最高 20°C,最低 8°C\n- 天气状况: 晴\n- 风速: 6 公里/小时,北\n- 湿度: 32%\n- 日出: 06:01\n- 日落: 18:05\n- 紫外线指数: 2,低\n\n注意事项:\n- 天气晴朗,适合户外活动,但早晚温差较大,请注意保暖。\n- 紫外线指数较低,但仍建议做好防晒措施。\n- 风速较小,适合进行户外运动。', error=None, include_in_memory=False)], all_model_outputs=[{'go_to_url': {'url': 'https://www.bing.com/search?q=上海天气&mkt=zh-CN'}, 'interacted_element': None}, {'extract_content': {'goal': 'Extract the weather information for tomorrow'}, 'interacted_element': None}, {'done': {'text': '明天的天气情况如下:\n- 日期: 周四 20\n- 温度: 最高 20°C,最低 8°C\n- 天气状况: 晴\n- 风速: 6 公里/小时,北\n- 湿度: 32%\n- 日出: 06:01\n- 日落: 18:05\n- 紫外线指数: 2,低\n\n注意事项:\n- 天气晴朗,适合户外活动,但早晚温差较大,请注意保暖。\n- 紫外线指数较低,但仍建议做好防晒措施。\n- 风速较小,适合进行户外运动。', 'success': True}, 'interacted_element': None}])
---------------------------------------

从上面代码可以看到,我们设定了任务目标,通过browser_use中的Agent完成了对任务的拆解,并且实际对其进行操作。最终的打印部分我们也可以调取Agent的打印结果从而实现本阶段的任务目标。

根据天气信息给出美妆建议

假设读者是一名28岁左右,在上海工作的男性年轻程序员,由于工作紧迫而对于具体的美妆细节并不了解,因此在今天出门约会时则需要具体的装扮指导,基于此我们可以通过DeepSeek构建一个男性约会装扮的Agent。

在具体实现上,一个朴素的想法就是结合我们前面讲解的自动化天气获取,使用DeepSeek强大的推理和知识储备,对结果进行整理和输出,给出具体的约会装扮建议。代码如下所示:

from langchain_openai import ChatOpenAI
from browser_use import Agent
from dotenv import load_dotenv
import os
load_dotenv()
import asyncio
api_key = "sk-282074c41d594514aee6fd6f179ed292"
base_url = "https://api.deepseek.com/beta"
model = "deepseek-chat"
from openai import OpenAI
client = OpenAI(api_key=api_key,base_url=base_url)
city = "上海"
task_1 = f"""
从下面的网页地址:
https://www.bing.com/search?q={city}天气&mkt=zh-CN
获取天气情况,并总结出明天的天气变化和注意事项。
"""
describe_master = "年轻男性28岁,居住上海,皮肤白皙,程序员"
task_2 = f"""
根据传递给你的{describe_master},总结出一份明日男性约会美妆建议,天气描述如下:
"""
llm = ChatOpenAI(model=model, api_key=api_key, base_url=base_url)
async def main():
    agent = Agent(
        task=task_1,
        llm=llm,
        use_vision=False,
    )
    weather_report = await agent.run()
    response = client.chat.completions.create(
        model="deepseek-chat",
        messages=[
            {"role": "system", "content": "你是一个专精于男性美妆和化妆品使用的美妆助手,懂得如何护肤,而又保持我的男性气概。"},
            {"role": "user","content": f"根据传递给你的'{describe_master}',总结出一份明天出门男性美妆建议,天气描述如下:'{weather_report}'"},
        ],
        max_tokens=1024,
        temperature=0.9,
        stream=False
    )
    print("---------------------")
    print(response.choices[0].message.content)
if __name__ == '__main__':
    asyncio.run(main())

在上面代码中,我们首先完成了天气信息的获取,之后通过DeepSeek设定了其扮演的角色,并根据其获取和整理的天气信息完成需要的任务输入,最终返回结果:

INFO     [agent] ? Result: 明天的天气情况如下:
- 日期: 星期四 20
- 温度: 最高 20°C,最低 9°C
- 天气状况: 晴
- 风速: 8 km/h,风向: 北
- 湿度: 32%
- 紫外线指数: 3 (中等)
- 日出时间: 06:01
- 日落时间: 18:05
注意事项:
- 由于天气晴朗,紫外线指数为中等,建议外出时做好防晒措施。
- 风速较低,适合户外活动。
- 早晚温差较大,请注意适时增减衣物。
INFO     [agent] ✅ Task completed
INFO     [agent] ✅ Successfully
---------------------

根据你提供的信息,28岁、皮肤白皙的男性程序员,居住在上海,明天天气晴朗,温度在9℃到20℃之间,紫外线指数为中等。以下是为明天出门准备的男性美妆建议:

### 1. **护肤步骤**
   - **清洁**: 
   - **保湿**: 
   - **防晒**: 
### 2. **底妆**
   - **隔离霜**: 
   - **BB霜或轻薄的粉底液**: 
### 3. **眉毛**
   - **眉笔或眉粉**: 
### 4. **眼部**
   - **眼霜**: 
   - **睫毛膏**
...
### 8. **其他注意事项**
   - **衣物搭配**: 
   - **补水**:

可以看到,根据设定的要求和角色扮演的指示,我们的Agent可以较好地生成对应的结果,并给出合理化建议。这样通过整合,我们完成了一项基本的约会装扮Agent的开发。

本文《DeepSeek原生应用与智能体开发实践》一书,获出版社和作者授权发布,仅供读者个人学习使用。





请使用浏览器的分享功能分享到微信等