掘金 人工智能 03月31日 16:33
2025年的春天用三行代码就能创建第一个代理
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

本文介绍了Smolagents,一个由Hugging Face团队开发的轻量级Python库,它简化了AI代理的构建过程。文章通过实例演示了如何结合Smolagents、Web Scraper和DeepSeek R1,创建一个强大的多代理聊天机器人,并提供了代码示例。Smolagents的优势在于其简洁性、灵活性以及与Hugging Face Hub的集成,使得开发者能够以更少的代码构建高效的AI代理。文章还强调了Smolagents在解决复杂问题和扩展应用方面的潜力。

💡Smolagents是一个轻量级的Python库,旨在通过简洁的代码来构建高效的AI代理,解决了传统代理开发中代码臃肿、流程低效等问题。

🤖Smolagents支持安全地“编写行动代码”的代理,并与Hugging Face Hub集成,这使得开发者能够更容易地利用现有的资源和工具。

🔑Smolagents结合Web Scraper和DeepSeek R1,可以创建一个多代理聊天机器人。通过代码示例,演示了如何抓取房地产数据并保存为CSV文件,展示了其在实际应用中的潜力。

💰DeepSeek R1是一个价格亲民的大型语言模型,它在保持高精度自然语言处理能力的同时,提供了灵活的定制选项,适用于特定行业和应用。

春天来了,让我们一起打造一个超级智能聊天机器人!🌸

如果你一直在关注AI社区的动态,你可能已经注意到Nvidia最近宣布了一个价值数十亿美元的人工智能代理项目,或者听说过Zark提到他们未来一年内不会招聘中级工程师的消息。这些新闻让我思考:这一切是如何发生的?在我开发AI代理系统时,我花费了数天的时间来完成这项任务。构建智能代理一直是一项复杂且技术要求极高的工作,涉及许多繁琐的步骤,如API集成、环境配置和依赖管理。

想象一下,在喝一杯咖啡的时间里就能搭建一个AI代理——这正是 Smolagents 带来的可能性。这是一个由Hugging Face团队打造的新一代代理框架,它让构建AI变得简单而强大。对于开发者来说,这就像是一份礼物——既简洁又功能强大。

接下来展示如何使用 **Smolagents**、Web Scraper 和 DeepSeek R1 来创建一个强大的多代理聊天机器人。无论是用于商业还是个人用途,这个聊天机器人都能成为你的得力助手。

Smolagents 旨在找到复杂性和简易性之间的完美平衡。编写代码是 Smolagents 的最大亮点之一。最令人印象深刻的是,只需三行代码就能创建你的第一个代理,并且它还能构建 Agent-Retrieval-Generation (Agent-RAG) 系统。与 Crew AI 和 Autogen 相比,虽然它们功能丰富但复杂度较高。

在新的一年伊始,DeepSeek 推出了其最新的大规模语言模型 DeepSeek R1,这是一个拥有671B参数的混合专家(MoE)语言模型。DeepSeek R1 最吸引人的一点是它的价格非常亲民。不要以为“便宜就不好”!事实上,DeepSeek R1 在保持高精度自然语言处理能力的同时,价格却远低于竞争对手如 GPT-4 和 Claude。

用户可以自由定制 DeepSeek R1,使其适用于特定行业和应用的AI模型变得简单易行。这种灵活性是它区别于其他竞争产品的关键所在。

接下来,我将通过一个实时聊天机器人的演示来展示我的意思。我访问了一个房地产网站,抓取了代理的名字、电话号码和公司名称,并使用了一些精心设计的输入和工具以获得更好的结果。我们知道 DeepSeek R1 在编码能力和基于链式思维及工具化方法方面表现优异。

在视频结束时,你将了解 Smolagents 是什么,它的特点是什么,为什么它值得我们关注,它是如何工作的,以及如何利用 Smolagents 创建一个超级智能代理。

免责声明:本文仅用于教育目的。我们不鼓励任何人抓取网站内容,尤其是那些有条款和条件禁止此类行为的网站。

SmolAgents 是什么?

SmolAgents 是一个轻量级的 Python 库,它让开发者能够用极简的方式构建高效的代理。这个库解决了代理开发中的常见痛点:代码臃肿、流程低效以及工具集成困难。它支持安全地“编写行动代码”的代理,并且与 Hugging Face Hub 集成。此外,它还为你处理了许多非例行的复杂性问题,比如确保系统提示、解析器和执行链接中代码格式的一致性。

为什么值得关注?

SmolAgents 致力于简洁性和对 LLM 无关的设计,专注于支持安全的代码编写代理,并且与 Hugging Face Hub 集成。这个代理系统打破了传统工作流程对于狭窄任务的限制,扩展了处理更复杂现实问题的可能性。Hugging Face 的工程师们表示,代理为 LLM 提供了访问外部世界的能力。

在这个万物复苏的春天,让我们一起探索 SmolAgents 如何帮助我们构建更加智能和高效的代理吧!

Smolagents 采用代码而非 JSON 来描述动作,这种方式带来了更多的组合性、数据管理和灵活性。构建代理时面临的挑战包括解析代理的输出和基于前几轮迭代合成提示词,这些正是 Smolagents 提供的关键功能。

Hugging Face 还与其他模型进行了基准测试,发现开放模型在减少步骤和 API 调用方面比传统解决方案减少了 30%,同时在困难的基准测试中表现更佳。除了 Smolagents,还有其他公司如 OpenAI 的 Swarm 和微软的 Magentic-One 等也在这一领域有所作为。SmolAgents 在安全上也下了功夫,内置了沙箱模式以确保代码的安全执行,并且通过与 Hugging Face Hub 的集成,只需一行代码即可轻松分享。

Smolagents 工作原理

Smolagents 旨在实现易用性和效率的完美结合。其直观的 API 让开发者能够轻松构建智能代理来完成任务,如命令理解、外部数据源连接、动态代码生成与执行等。具体功能包括:

语言理解: 利用先进的自然语言处理(NLP)模型,Smolagents 能够理解和解析命令及查询。

智能搜索: 连接外部数据源以提供快速准确的搜索结果。

动态代码执行: 代理可以根据需要生成并执行代码来解决特定问题。

SmolAgents 的模块化设计使其适用于多种场景,无论是快速原型制作还是全规模生产环境应用。通过利用预训练模型,开发者可以节省大量时间和精力,并获得强大的性能,而无需从头开始定制模型。

动手编码

现在让我们一步步探索如何创建 SmolAgents。首先,我们需要安装支持该模型的库。这一步我们使用 pip install requirements 命令来完成。

pip install -r requirements.txt

接下来是导入相关库的步骤,随着我们的深入,这些库的重要性将逐渐显现。

    CodeAgent:这是默认代理,它会在每一步编写并执行 Python 代码片段。LiteLLM Model:让你能够调用超过100种不同的模型。tool:一个列表 Tools,代理可以使用这个列表中的工具来解决问题。

一旦你有了这两个参数 toolsmodel,就可以创建代理并运行它了。你可以使用任何你喜欢的 LLM,无论是通过 Hugging Face APItransformersollama 还是 LiteLLM

from typing import Optional, Dictfrom smolagents import CodeAgent, tool, LiteLLMModel , GradioUIimport requestsimport osimport timefrom bs4 import BeautifulSoupimport pandas as pd

首先,我创建了一个抓取函数来从realtor.com网站上搜集房地产代理的信息。我们的目标是获取名字、电话号码和公司名称。

你可以指定州(例如,“CA”代表加利福尼亚)和城市(例如,“Angeles”),以及你想要抓取的页面数量。初始化列表用于存储数据,并使用头部信息来模仿浏览器请求,动态地为每个页面URL设置请求头。

接着,我创建了一个循环从第一页到指定的页数进行迭代。对于第一页,链接很简单;而对于后续页面,则在链接中添加了页码。

我利用requests库下载网页内容。如果HTTP响应状态码不是200(表示成功),抓取器将停止并返回错误信息。

我们通过搜索HTML中的类名为agent-name的元素来查找代理的名字。找到后,去除多余的空格并将名字添加到列表中。同样地,我们也检查所有可能的位置以获取电话号码和公司名称。如果找到了这些信息,我们会清理数据并将其加入各自的列表中。如果没有找到任何代理信息,则返回错误消息。否则,将整理好的数据组织成字典形式并返回。

@tooldef scrape_realtor(state: str, city_name: str, num_pages: Optional[int] = 2) -> Dict[str, any]:    """从realtor.com抓取指定城市和州的代理信息        参数:        state: 州缩写(例如,'CA', 'NY')        city_name: 城市名称,用连字符代替空格(例如,'buffalo')        num_pages: 要抓取的页面数量(默认:2)    """    try:                results = []                 phone_results = []           office_results = []          pages_scraped = 0                        headers = {            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36",            "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",            "Accept-Language": "en-US,en;q=0.5",
            "Connection": "keep-alive"        }                for page in range(1, num_pages + 1):                        if page == 1:                url = f'https://www.realtor.com/realestateagents/{city_name}_{state}/'            else:                url = f'https://www.realtor.com/realestateagents/{city_name}_{state}/pg-{page}'                        print(f"正在抓取第 {page} 页...")                                    r = requests.get(url, headers=headers)            if r.status_code != 200:                return {"error": f"无法访问第 {page} 页: 状态码 {r.status_code}"}            soup = BeautifulSoup(r.text, features="html.parser")                                    agent_cards = soup.find_all('div', class_='agent-list-card')                        for card in agent_cards:                                name_elem = card.find('div', class_='agent-name')                if name_elem:                    name = name_elem.text.strip()                    if name and name not in results:                        results.append(name)                        print(f"找到经纪人: {name}")                                phone_elem = card.find('a', {'data-testid': 'agent-phone'}) or \                            card.find(class_='btn-contact-me-call') or \                            card.find('a', href=lambda x: x and x.startswith('tel:'))                                if phone_elem:                    phone = phone_elem.get('href', '').replace('tel:', '').strip()                    if phone:                        phone_results.append(phone)                        print(f"找到电话号码: {phone}")                                office_elem = card.find('div', class_='agent-group') or \                            card.find('div', class_='text-semibold')                if office_elem:                    office = office_elem.text.strip()                    office_results.append(office)                    print(f"找到办公室: {office}")                else:                    office_results.append("")                        pages_scraped += 1            time.sleep(2)          if not results:            return {"error": "未找到经纪人。可能是网站结构发生了变化,或者该地区没有结果。"}                return {            "names": results,            "phones": phone_results,            "offices": office_results,            "total_agents": len(results),            "pages_scraped": pages_scraped,            "city": city_name,            "state": state        }            except Exception as e:        return {"error": f"抓取错误: {s

接下来,我创建了一个函数,用于将抓取到的房地产数据保存为CSV文件。这个函数接受一个字典data作为参数,里面包含了抓取的信息,并且可以选填一个文件名。如果data中包含错误信息,则直接返回该错误消息。

如果没有错误,它会确保所有列表(names, phones, offices)的长度相等,通过在较短的列表末尾填充空字符串来实现这一点。然后,从这些列表创建一个DataFrame,并使用UTF-8编码将其写入CSV文件中。如果操作成功,则返回一条包含保存文件名和条目总数的成功消息;否则,返回错误信息。

@tooldef save_to_csv(data: Dict[str, any], filename: Optional[str] = None) -> str:    """将抓取的房地产数据保存到CSV文件        参数:        data: 包含抓取结果的字典        filename: 可选的文件名(默认:cityname.csv)    """    try:        if "error" in data:            return f"错误: {data['error']}"                    if not filename:            filename = f"{data['city'].replace('-', '')}.csv"                            max_length = max(len(data['names']), len(data['phones']), len(data['offices']))                        data['names'].extend([""] * (max_length - len(data['names'])))        data['phones'].extend([""] * (max_length - len(data['phones'])))        data['offices'].extend([""] * (max_length - len(data['offices'])))                        df = pd.DataFrame({            'Names': data['names'],            'Phone': data['phones'],            'Office': data['offices']        })                df.to_csv(filename, index=False, encoding='utf-8')        return f"数据已保存到 {filename}。总条目数: {len(df)}"            except Exception as e:        return f"保存CSV时出错: {str(e)}"

要使用 LiteLLMModel,你需要设置环境变量 ANTHROPIC_API_KEYOPENAI_API_KEY,或者在初始化时传递 api_key 变量。默认情况下,我们使用 CodeAgent 来执行 Python 代码。这应该是安全的,因为唯一可以调用的是你提供的工具和一组预定义的安全函数或来自 math 模块的函数,所以你的执行范围已经受到了限制。

Python 解释器默认不允许从一个安全列表之外导入模块,因此最常见的攻击方式不会构成威胁。你可以通过传递授权模块列表来允许额外的导入:

deepseek_model = LiteLLMModel(        model_id="ollama/nezahatkorkmaz/deepseek-R1"    )agent = CodeAgent(        tools=[scrape_realtor, save_to_csv],        model=deepseek_model,        additional_authorized_imports=["pandas", "bs4", "time"]    )

最后,让我们运行代理,启动 Gradio 界面,并测试聊天机器人。请记住,你的提示越精确,得到的结果就越好:

result = agent.run("""Thought: 让我们来抓取房地产数据吧!Code:```python# 抓取房地产数据data = scrape_realtor(state="NY", city_name="buffalo", num_pages=2)# 保存到 CSV 文件if "error" not in data:    result = save_to_csv(data)    print(result)else:    print(f"Error: {data['error']}")""")

结论 :

Hugging Face 对开发者用户有着深刻的理解。再加上其社区的优势,它发布的许多框架都获得了良好的反响。

这个框架可能是过去两年整个AI社区思考和积累的结果。

这提醒我们,有时候,小巧而精致才是最好的选择。

2025年春天来了,随着代理技术的蓬勃发展,SmolAgents以最简洁的方式解决了最关键的问题。

在这个AIGC时代,找到知己不易,自我修炼更难。抓住前沿科技的机会,与我们一起成为创新超个体(掌握个人力量)。

结论 :

通过今天的分享,我们不仅深入了解了SmolAgents的工作原理及其重要性,还动手实践了一次实际的代码编写过程。在这个过程中,你学会了如何初始化结果、设置请求头以及处理页面内容等关键步骤。希望这些知识能帮助你在未来的项目中更加得心应手。

随着春天的到来,技术领域也迎来了新的生机与活力。不妨将今天学到的知识应用到你的下一个项目中,看看能否带来意想不到的惊喜!

Fish AI Reader

Fish AI Reader

AI辅助创作,多种专业模板,深度分析,高质量内容生成。从观点提取到深度思考,FishAI为您提供全方位的创作支持。新版本引入自定义参数,让您的创作更加个性化和精准。

FishAI

FishAI

鱼阅,AI 时代的下一个智能信息助手,助你摆脱信息焦虑

联系邮箱 441953276@qq.com

相关标签

Smolagents AI代理 Hugging Face DeepSeek R1
相关文章