高山探险代理:您的冬季山地探险AI助手

社区文章 2025年1月17日发布

进入2025年,LLM代理正迎来高光时刻,马克·扎克伯格甚至提出,AI工程师可能很快就会取代Meta公司传统的编码工作。许多框架正在涌现,以简化AI代理应用程序的开发,同时代理系统在基准测试上的竞争也日益激烈,每个系统都在争相成为第一个实现AGI(通用人工智能)的系统。

但LLM代理究竟是什么?我的同事Aymeric Roucher在他的AI代理简介中提供了一个非常简单的定义:

AI代理是LLM输出控制工作流程的程序。

这些代理可以处理哪些类型的工作流程?尽管代理在基准测试中表现出色,但这些测试往往不足以代表实际应用。我们今天遇到的实际用例,例如代理RAG系统或自我纠正的文本到SQL,无疑是有用的——但对我来说,它们常常感觉有些乏味。

相反,我开始思考:我能开发出哪些真正能改善我日常生活的应用程序?作为一名运动和户外爱好者,我一直梦想着能有一种东西,可以自动化山地旅行的准备研究,并简化规划过程,这样我就可以完全专注于冒险本身。

这就是我创建**高山探险代理(Alpine Agent)**的原因,这是一个简单的 Gradio 应用程序,由 Hugging Face 最新的库 **smolagents** 提供支持。这个应用程序旨在帮助规划法国阿尔卑斯山和比利牛斯山脉的安全滑雪旅行路线。它依赖于 skitour.fr 和法国天气预报机构 Météo France 的数据和 API。

如果您热爱户外运动和滑雪,我非常希望您能测试这个应用程序并分享您的反馈。即使您主要对构建代理感兴趣,也请尝试使用这个应用程序,并跟着这篇博客文章学习它是如何创建的。

使用 Skitour.fr 和 Météo France 规划安全的滑雪旅行

通常,在规划法国阿尔卑斯山或比利牛斯山脉的安全滑雪旅行时,结合 Skitour.fr 详细的路线数据和 Météo-France 可靠的天气和雪崩预报至关重要,这样您才能安心地开始您的冒险。

1. Skitour 是什么?

Skitour.fr是一个专门为滑雪旅行爱好者设计的法国网站,提供了一个全面的平台,用于规划、分享和讨论滑雪旅行路线、条件和经验。该网站提供详细的路线描述、用户生成的旅行报告、设备指南和社区论坛进行讨论。为了方便与其他应用程序集成,Skitour.fr 提供了一个 API,允许开发人员访问其路线和旅行报告数据库。该 API 可在 skitour.fr/api 访问。

image/png

skitour.fr

2. Météo France 是什么?

Météo-France 是法国官方气象服务机构,负责观测、研究和预测法国及其领土的天气状况。除了提供山区详细预报外,Météo-France 还提供雪崩风险评估公报(BERA)作为其主要服务之一。这些公报提供雪情和雪崩状况的全面评估,支持户外爱好者、地方当局和安全团队做出明智的决策。BERA 包括雪况稳定性、潜在雪崩触发因素以及自然和人为雪崩发生概率的关键细节。它还指定了从1(低)到5(非常高)的风险等级,并重点说明了风险最高的具体海拔和坡度方向。这些数据也可以通过 API 门户访问,网址为 portail-api.meteofrance.fr,使开发人员能够将其集成到自己的应用程序或工具中。

image/png

Météo France 的雪崩风险评估公报 (BERA)

透彻分析这些数据并在此基础上做出明智的决定对于确保滑雪旅行期间的安全至关重要。这可能是一个耗时的过程,尤其是在考虑雪况稳定性、雪崩风险、天气预报和特定路线的适宜性等多种因素时。这就是 LLM 可以简化规划过程的地方,通过快速处理和整合复杂数据来提供可操作的建议,从而简化任务。让我们基于这些数据构建一个 LLM 代理!

构建高山探险代理

我使用 smolagents 库开发了一个系统,能够回答用户查询,例如“您能推荐一条在沙莫尼附近、难度适中、天气良好且雪崩条件安全的滑雪旅行路线吗?”该系统会自动确定必要的工作流程,从 Skitour 和/或 Météo-France 检索数据,以提供最准确和最有用的响应。

smolagents 中,对**代码代理(Code Agents)**提供了头等支持,代码代理是通过代码执行其操作的代理。大量研究表明,使用代码来支持 LLM 中的工具调用可以显著提高性能。有关详细概述,请查看 smolagents 文档

要构建这样的代理,您至少需要两个元素:

  • tools:代理可以访问的工具列表,这些工具将封装 skitour 和 Météo France API 路由
  • model:作为代理引擎的 LLM。

1. LLM 引擎

对于模型,您可以使用任何 LLM,无论是使用 smolagents 的 HfApiModel 类的开源模型(它利用 Hugging Face 的免费推理 API),还是您可以使用 LiteLLMModel 来利用 litellm 并从 100 多种不同的云 LLM 中进行选择。

我建议关注具有强大推理能力的模型,因为代理工作流中的错误可能源于真正的失误或 LLM 引擎在有效推理方面的局限性。通过测试,我发现 Qwen/Qwen2.5-Coder-32B-Instructmeta-llama/Llama-3.3-70B-Instruct 和 openai-gpt4o 是为高山代理提供动力的绝佳选择。

实例化引擎

from smolagents import HfApiModel, LiteLLMModel

def create_llm_engine(type_engine: str, api_key: str = None):
    if type_engine == "Qwen/Qwen2.5-Coder-32B-Instruct":
        llm_engine = HfApiModel(model_id=os.environ["HUGGINGFACE_ENDPOINT_ID_QWEN"])
        return llm_engine
    elif type_engine == "meta-llama/Llama-3.3-70B-Instruct":
        llm_engine = HfApiModel(model_id=os.environ["HUGGINGFACE_ENDPOINT_ID_LLAMA"])
        return llm_engine
    elif type_engine == "openai/gpt-4o" and api_key:
        llm_engine = LiteLLMModel(model_id="openai/gpt-4o", api_key=api_key)
        return llm_engine
    elif type_engine == "openai/gpt-4o" and not api_key:
        raise ValueError("You need to provide an API key to use the the model engine.")
    else:
        raise ValueError("Invalid engine type. Please choose either 'openai/gpt-4o' or 'Qwen/Qwen2.5-Coder-32B-Instruct'.")

2. 定义工具

对于完整的滑雪旅行指南,我定义了以下封装 skitour 和 Météo France API 路由的路由:

  • list_mountain_ranges:根据用户给定的位置搜索最接近的山脉 ID。它封装了 skitour APIGET/api/massifs

  • list_routes:在给定的山脉列表中查找滑雪旅行路线列表。它封装了 skitour APIGET/api/topos

  • describe_route:搜索特定滑雪旅行路线的关键信息,包括天气预报和相关的雪崩风险。它封装了 skitour APIGET/api/toposMeteo France APIGET/massif/BRAmeteofrance-api package

  • forecast:搜索给定位置的天气预报以及当前的雪崩风险评估公报。它封装了 Meteo France APIGET/massif/BRAmeteofrance-api package

  • recent_outings:搜索 skitour 社区用户在给定山脉中发布的最新出行信息。它封装了 [skitour API](https://skitour.fr/apiGET/api/sorties

让我们深入了解其中一个工具(如 describe_route)的实现。首先,我们需要定义一些实用函数来与 API 交互。

import os
import requests
import xml.etree.ElementTree as ET

from typing import List, Dict, Union
from meteofrance_api import MeteoFranceClient

METEOFRANCE_API_URL = 'https://public-api.meteofrance.fr/public/DPBRA/v1/'
SKITOUR_API_URL = 'https://skitour.fr/api/'

def get_details_route(id_route) -> :
    """
    Fetch the details of a specific route from skitour API
    
    Args:
        id_route (str): ID of the route.
    Returns:
        Dict: Details of the route.
    """
    url = SKITOUR_API_URL + f'topo/{id_route}'
    headers = {'cle': os.getenv('SKITOUR_API_TOKEN')}
    response = requests.get(url, headers=headers)
    return response.json()


def extract_text(element: ET.Element) -> str:
    """
    Extract all text from an XML element recursively.

    Args:
        element (ET.Element): XML element.

    Returns:
        str: Extracted text.
    """
    texte = element.text or ""
    for enfant in element:
        texte += extract_text(enfant)
    texte += element.tail or ""
    return texte

def get_massif_conditions(massif_id: str) -> str:
    """
    Fetch the weather conditions for a given mountain range.

    Args:
        range_id (str): ID of the mountain range.

    Returns:
        str: Weather conditions in plain text.
    """
    url = METEOFRANCE_API_URL + 'massif/BRA'
    headers = {'apikey': METEO_FRANCE_TOKEN, 'accept': '*/*'}
    params = {'id-massif': massif_id, "format": "xml"}
    response = requests.get(url, headers=headers, params=params)
    xml_text = response.text
    root = ET.fromstring(xml_text)
    text = extract_text(root)
    #remove file names
    text = re.sub(r'\b[\w\-]+\.[a-zA-Z0-9]+\b', '', text).strip()
    return text

def llm_summarizer(text: str, llm_engine: Union[HfApiModel, LiteLLMModel]) -> str:
    """
    Summarize a text using a language model.
    
    Args:
        text (str): The input text to summarize.
        llm_engine (Union[HfApiModel, LiteLLMModel]): The language model to use.
    Returns:
        str: The summarized text.
    """
    messages=[
           {
            "role": "system",
            "content": """You're an expert at summarizing data on weather forecast and avalanche conditions. 
            Summarize the data that's been provided to you below
            """
        }, 
        {
            "role": "user",
            "content": text,
        }
    ]
    
    summary = llm_engine(messages)
    return summary["content"]

例如,让我们看看 get_details_route 函数的输出。

info_route = get_details_route(2)
print(info_route)
{'id': '2',
 'nom': 'Col de la Balmette, Versant Est',
 'orientation': 'E',
 'denivele': '1670',
 'dif_ski': '3.1',
 'expo': '1',
 'difficulte': 'R',
 'gpx': '/topos/gpx/2.gpx',
 'massif': {'id': '12', 'nom': 'Belledonne'},
 'depart': {'id': '2',
  'nom': 'Articol',
  'altitude': '1005',
  'acces': "Depuis Grenoble, prendre la route de Bourg d'Oisans. A Rochetaillée, partir en direction du lac de Grandmaison. Articol se trouve un peu avant le rivier d'Allemond. Départ par un petit sentier face aux maisons.",
  'latlon': ['45.1779', '6.03655']},
 'sommets': [{'id': '66',
   'nom': 'Col de la Balmette',
   'altitude': '2667',
   'latlon': ['45.1735', '5.991']},
  {'id': '6345',
   'nom': 'Pic Lamartine',
   'altitude': '2735',
   'latlon': ['45.1753', '5.99239']}],
 'refuges': [{'id': '519',
   'nom': 'Chalet du Rif Premier',
   'altitude': '2087',
...
 'auteur': {'id': '1', 'pseudo': 'Jeroen'},
 'photos': [{'id': '1388',
   'com': 'Depuis le Rissiou',
   'url': '/topos/photos/1388.jpg',
   'auteur': {'id': '446', 'pseudo': 'Etienne-H-'}}]}

从 API 接收到的数据块可能特别长,尤其是在涉及天气预报时。这就是为什么我创建了一个 `llm_summarizer` 函数,使这些数据对代理来说更易于理解。

现在让我们来实现我们的 describe_route 工具。

class DescribeRouteTool(Tool):
    name = "describe_route"
    description = """ 
    Searches for key information about a specific ski touring route,
    including weather forecasts and associated avalanche risks. 
    Always use this tool after using the `list_routes` tool.
    This tool returns a dictionary containing the route's information,
    the avalanche risk estimation bulletin, and the weather forecast for the coming days of the route.
    """
    inputs = {
        "id_route": {
            "description": "id of the route",
            "type": "string",
        },
        "id_range": {
            "description": "mountain range id of the route",
            "type": "string"}
    }
    output_type = "any"
    
    def __init__(self, skitour2meteofrance: dict, llm_engine: Union[HfApiModel, LiteLLMModel]):
        super().__init__()
        #Dictionary matching mountain ranges ids between skitour and Meteo France
        self.massifs_infos = skitour2meteofrance 
        self.weather_client =  MeteoFranceClient(access_token=os.getenv("METEO_FRANCE_API_KEY"))   
        self.llm_engine = llm_engine

    def forward(self, id_route: str, id_range: str) -> dict:

        # Get route info from skitour
        route_info = get_details_route(str(id_route))
        #Get mountain range conditions from Meteo France
        avalanche_conditions = get_range_conditions(
            self.massifs_infos[str(id_range)]['meteofrance_id']
            )
        lat, lon = topo_info["depart"]["latlon"]
        weather_forecast = self.weather_client.get_forecast(float(lat), float(lon))
        daily_forecast = weather_forecast.forecast

        for day_forecast in daily_forecast:
            day_forecast["dt"] = weather_forecast.timestamp_to_locale_time(day_forecast["dt"]).isoformat()

        # Use an LLM to condense and present the data in a more digestible and user-friendly forma
        forecast_summary = llm_summarizer(str(daily_forecast), self.llm_engine)
        avalanche_summary = llm_summarizer(str(avalanche_conditions), self.llm_engine)

        return {
            "route_info": route_info, 
            "avalanche_conditions": avalanche_summary,
            "daily_weather_forecast": forecast_summary,
            "route_link": f"https://skitour.fr/topos/{id_route}"
            }

您也可以使用装饰器 @tool 来实现您的工具。测试工具。

#Create engine
llm_engine = HfApiModel(model_id="Qwen/Qwen2.5-Coder-32B-Instruct")

#Dictionary matching mountain ranges ids between skitour and Meteo France computed manually
with open('data/skitour2meteofrance.json', 'r') as f:
    skitour2meteofrance = json.load(f)

#Instantiate the tool
describe_route_tool = DescribeRouteTool(skitour2meteofrance, llm_engine)

print(describe_route_tool(id_route=2, id_range=12))

输出

{'route_info': {'id': '2',
  'nom': 'Col de la Balmette, Versant Est',
  'orientation': 'E',
  'denivele': '1670',
  'dif_ski': '3.1',
  'expo': '1',
  'difficulte': 'R',
  'gpx': '/topos/gpx/2.gpx',
  'massif': {'id': '12', 'nom': 'Belledonne'},
  'depart': {'id': '2',
   'nom': 'Articol',
   'altitude': '1005',
   'acces': "Depuis Grenoble, prendre la route de Bourg d'Oisans. A Rochetaillée, partir en direction du lac de Grandmaison. Articol se trouve un peu avant le rivier d'Allemond. Départ par un petit sentier face aux maisons.",
   'latlon': ['45.1779', '6.03655']},
  'sommets': [{'id': '66',
    'nom': 'Col de la Balmette',
    'altitude': '2667',
    'latlon': ['45.1735', '5.991']},
   {'id': '6345',
    'nom': 'Pic Lamartine',
    'altitude': '2735',
    'latlon': ['45.1753', '5.99239']}],
  'refuges': [{'id': '519',
    'nom': 'Chalet du Rif Premier',
    'altitude': '2087',
...
    'url': '/topos/photos/1388.jpg',
    'auteur': {'id': '446', 'pseudo': 'Etienne-H-'}}]},
 'avalanche_conditions': "Le bulletin météo et d'avalanches du 17 janvier 2025 indique un risque limité d'avalanches, en particulier en altitude, où il existe quelques plaques à vent. ... Les limites de skiabilité se sont élevées autour de 1000/1200 m sur les pentes nord et 1700 m au sud. La qualité de la neige est très variable, dépendant de l'altitude et de l'exposition au vent.\n\nLe temps est annoncé sec et ensoleillé, favorisant la stabilisation progressive du manteau neigeux.",
 'daily_weather_forecast': 'The weather data from January 17th to the morning of January 18th, 2025, shows a clear and mostly sunny weather pattern with low humidity and no precipitation. Temperatures ranged from a high of 6.1°C during the day on January 17th to a low of -2.9°C overnight. ... Sea level pressure gradually decreased from around 1031.2 hPa to 1027.3 hPa. The data also included the 0°C isotherm level (iso0) fluctuating between 2150m to 2900m, indicating relatively stable atmospheric conditions with no significant snowfall or rain. Overall, pleasant and stable weather conditions persisted through the forecast period.',
 'route_link': 'https://skitour.fr/topos/2'}

3. 构建代理

现在我们有了 LLM 引擎和工具,我们可以很容易地使用 smolagents 实例化一个 CodeAgent


from smolagents import HfApiModel
from smolagents import CodeAgent
from src.tools import (MountainRangesTool, ForecastTool, GetRoutesTool, DescribeRouteTool, RecentOutingsTool

#Dictionary containing clusters of summits in a given moutain range to assign a location to a moutain range
#check src/utils.py
with open('data/summit_clusters.json', 'r') as f:
    summit_clusters = json.load(f)

#Dictionary matching mountain ranges ids between skitour and Meteo France computed manually
with open('data/skitour2meteofrance.json', 'r') as f:
    skitour2meteofrance = json.load(f)

#Loading tools
def get_tools(llm_engine):
    mountain_ranges_tool = MountainRangesTool(summit_clusters)
    forecast_tool = ForecastTool(
        llm_engine=llm_engine, 
        clusters=summit_clusters, 
        skitour2meteofrance=skitour2meteofrance
        )
    get_routes_tool = GetRoutesTool()
    description_route_tool = DescribeRouteTool(
        skitour2meteofrance=skitour2meteofrance, 
        llm_engine=llm_engine
        )
    recent_outings_tool = RecentOutingsTool()
    return [mountain_ranges_tool, forecast_tool, get_routes_tool, description_route_tool, recent_outings_tool]

alpine_agent = CodeAgent(
            tools = get_tools(llm_engine),
            model = llm_engine,
            additional_authorized_imports=["pandas"], #other libraries that the agent can execute
            max_steps=10, # Max number of action steps
    )

4. 运行代理

代理实例化后,您可以使用 .run() 方法来回答问题。有了工具定义在其上下文中,并且 smolagent 设置了系统提示,该代理已经具备了相当好的性能。

为了成为一名出色的山地专家助手,我发现提供额外的特定信息至关重要,例如滑雪难度分级系统的定义以及与用户沟通的首选语言。幸运的是,.run() 实现了 additional_args 参数,允许传递额外的信息,这些信息将被包含在 LLM 上下文中。让我们创建这个提示:

ROLE
You are an expert assistant specializing in ski touring. Your primary task is to assist users in {language} by providing tailored recommendations for ski touring itineraries, focusing on safety, grading systems, and user preferences.

TASK REQUIREMENTS

Use APIs and tools to gather data on:
Ski touring itineraries
Weather forecasts
Avalanche risks and conditions
Mountain hut access
Analyze the data and deliver user-friendly, detailed recommendations.
Always interogate yourself about the routes access, snow and weather conditions before suggesting them to the users. `describe_route` tool will be useful for that. It's the most important part of your job.
Answer general queries unrelated to ski touring to the best of your ability.

GRADING SYSTEMS

Ski Difficulty (1–5): Define skill levels based on slope gradient, exposure, and terrain.
Ascent Grading (R, F, PD, AD, D): Classify ascents based on technical challenges.
Exposure Grading (E1–E4): Highlight the severity of risks, from minor obstacles to life-threatening falls.
RESPONSE FORMAT

json
Copy code
{{
  "message": "string (a detailed, user-friendly response in {language})",
  "itineraries": [
    {{
      "topo_id": "string (ID of the itinerary from the API)",
      "name": "string (name of the itinerary)",
      "topo_start_lat": "float (latitude of itinerary start)",
      "topo_start_lon": "float (longitude of itinerary start)",
      "topo_link": "string (link to the itinerary from the API)"
    }}
  ])
}}
Use the message field to explain recommendations and safety precautions clearly.
If no itineraries match or the query isn’t itinerary-related, set itineraries to None.
GUIDELINES

Always prioritize user safety. Warn users of unsafe conditions and suggest alternatives.
Respond only in {language}.
Structure messages to include relevant information such as:
Difficulty, ascent, and exposure grading.
Weather and avalanche conditions.
Recommendations for preparation and safety.

EXAMPLES

{{"question": Que proposes tu comme itinéraire de ski de randonnée vers Briançon?}}
{{'message': "Je vous recommande l'itinéraire 'Col de l'Aiguillette, Aller Retour depuis le pont
de l'Alpe', situé dans le massif des Cerces - Thabor - Mont Cenis. Ce parcours est d'une difficulté de ski de 2.2 
et d'une exposition de 1, adapté pour les skieurs ayant un certain niveau de maîtrise. L'ascension est classée R, 
facilement accessible, avec un gain d'élévation de 850 mètres.\n\n**Conditions Avalanches:**\nLes conditions 
actuelles montrent un risque marqué d'avalanches en raison de nombreuses plaques friables et plus dures. Les 
avalanches spontanées ainsi que celles déclenchées par les skieurs sont anticipées, un risque à considérer 
sérieusement avant de poursuivre cet itinéraire.\n\n**Prévisions Météo:**\nLe 8 janvier, un léger enneigement est 
prévu, avant de se transformer en pluie dans la matinée. Les températures commencent à refroidir et l'humidité est 
élevée. Il est recommandé de bien se préparer pour ces conditions durant vos activités outdoor.\n\nPour votre 
sécurité, évaluez toujours les conditions météo et avalanches directement sur le terrain avant de vous lancer dans 
l'itinéraire. Bonne randonnée et restez prudent.", 'itineraries': [{{'topo_id': '104', 'name':Col de l'Aiguillette, Aller Retour depuis le pont
de l'Alpe ,'topo_link': 
'https://skitour.fr/topos/104', 'topo_start_lat': 45.0181, 'topo_start_lon': 6.4663}}]}}

{{"question": Quelles sont les conditions météo pour le massif du Mont-Blanc ?}}
{{'message': "Les conditions météorologiques pour le massif du Mont-Blanc du 7 au 8 janvier 2025
indiquent des températures froides avec des vents de vitesse variable et un ciel couvert, accompagnés de périodes 
de chutes de neige. Points clés :\n\n- **Températures** : Commençant à -19,3°C ressentis -30,5°C le 7 janvier à 
16h, elles augmentent graduellement la nuit à environ -7°C à -8,6°C ressentis -11,4°C à -14,9°C le lendemain 
après-midi.\n\n- **Vent** : Principalement de l'ouest-nord-ouest (260° à 300°) avec des vitesses de 6 à 10 km/h et 
rafales jusqu'à 22 km/h, plus fortes pendant les chutes de neige.\n\n- **Conditions Météo** : Alternance de petites
éclaircies et ciel partiellement nuageux (30% de couverture), se chargeant fortement (90%) à partir de 20h avec des
épisodes de neige durant la nuit et au petit matin suivant.\n\n- **Précipitations** : Pas de pluie ; début de 
légères chutes de neige à 21h avec accumulation augmentant pour atteindre jusqu'à 4,7 mm/heure durant la nuit du 8 
janvier. La neige s'atténue ensuite.\n\n- **Humidité** : De 45% le soir à 100% la nuit, restant élevée durant les 
chutes de neige.\n\n- **Pression au niveau de la mer** : Fluctuations légères, autour de 1010-1015 hPa, indiquant 
des conditions stables avec un abaissement de pression la nuit.\n\n- **Limite Pluie-Neige et Niveau Iso:0** : Non 
pertinent initialement, mais augmentant à 1550m à 2550m, suggérant des masses d'air chaud en 
altitude.\n\n\nConcernant les avalanches, le bulletin du 8 janvier 2025 met en garde contre de nombreuses plaques 
sensibles dans la neige fraîche, avec un risque marqué. Des avalanches peuvent se produire spontanément jusqu'à la 
mi-journée au-dessus de 1800 m, et peuvent être facilement déclenchées par les skieurs au-dessus de 2000 m. Les 
plaques vont de petite à moyenne taille (Taille 1 à 2), bien que des plaques plus grandes puissent se former 
au-dessus de 2600/3000 m.\n\nPour votre sécurité, tenez compte des prévisions de précipitations ventées dès 
mercredi soir. La neige est lourde et mouillée sous 1600 m, affectée par les pluies. L'enneigement reste moyen pour
la saison au-dessus de 2000 m.\n\nPour des mises à jour de vigilance, veuillez consulter les sites dédiés.", 
'itineraries': None}}

{{"question": Hello how are you?}}
{{'message': "I'm doing great and you, how can I help you today?", 'itineraries': None}}

请注意,我添加了一些少样本示例,以引导代理生成首选响应。好的,现在我们来运行代理。

alpine_agent.run("Can you suggest a route near Grenoble with good conditions?",
                additional_args={
                  "skier_agent_definition": SKI_TOURING_ASSISTANT_PROMPT.format(language="English")
                })

最终答案

Final answer: {'message': "I recommend the route 'Col de la Balmette, Versant Est' in the Belledonne massif. This route has a moderate difficulty level of 3.1 and a low exposure level of 1, 
making it suitable for intermediate skiers. The avalanche conditions are stable, and the weather forecast is favorable with clear skies and no precipitation expected. The route starts from Articol and
ascends to the Col de la Balmette, offering beautiful views and a challenging descent. Be sure to check the latest avalanche conditions and weather forecast before setting out.", 'itineraries': 
[{'topo_id': '2', 'name': 'Col de la Balmette, Versant Est', 'topo_start_lat': 45.1779, 'topo_start_lon': 6.03655, 'topo_link': 'https://skitour.fr/topos/2'}]}
运行代理

现在您可以直接尝试这个代理,它被封装在一个 Gradio Space 中,可在 florentgbelidji-alpine-agent.hf.space 访问。

构建高山探险代理的经验总结

  • 1️⃣ smolagents 简化了代理应用开发。 它能够以最少的编码工作实现开源或闭源模型的无缝集成,并且没有不必要的抽象。

  • 2️⃣ LLM 代理需要响应时间。 复杂的任务通常涉及多个步骤,这使得它们比即时输出要慢,但仍比手动规划快得多。

  • 3️⃣ 长上下文 LLM 至关重要。 上下文充当规划、操作和多步骤观察的内存缓冲区。我发现至少需要 32,000 个 token,而系统在 64,000 个 token 或更多时表现得更好。

  • 4️⃣ 强大的 LLM 对成功至关重要。 有效的工作流程需要强大的推理能力。我的测试表明,Qwen2.5-Coder-32B-Instruct、Llama-3.3-70B-Instruct 和 GPT-4 是此用例的绝佳选择。

  • 5️⃣ 特定领域的提示能改善响应。 精心设计的提示,与代理库的系统提示相辅相成,包含与领域相关的信息,并结合少量示例,有助于代理更准确地响应用户。

  • 6️⃣ 清晰的工具定义是关键。 工具必须有明确的定义,说明何时使用它们,以帮助代理建立正确的工作流程。随着工具列表的增长,精确的定义对于代理选择合适的工具变得更加关键。

致谢

感谢 Aymeric Roucher 的指导和此工具的测试。

社区

喜欢这个用例!下次 Instagram 拍摄会非常方便!

注册登录 发表评论