1、创建一个新的 CrewAI 项目 surprise_trip
crewai create crew surprise_trip
选择模型厂商和模型
生成.env
MODEL=gpt-4o
OPENAI_API_KEY=你的api_keySERPER_API_KEY=你的SERPER api_key
2、探索项目结构
3、配置代理
修改 agents.yaml文件。
# 个性化活动规划师 Agent
personalized_activity_planner:# 角色名称:用于识别 agent 的职责(对模型来说类似标题)role: >活动规划师# 目标描述:告诉 agent 它要完成的任务目标goal: >调研并寻找目的地的有趣活动和事件,确保这些内容符合旅行者的兴趣和年龄段# 背景故事:为 agent 赋予人设,增强语言模型的代入感,提升生成质量backstory: >你擅长根据旅行者的具体偏好和人群特点设计个性化的行程安排,你能快速找到最适合他们的活动组合,打造难忘的旅程。# 餐厅探索者 Agent
restaurant_scout:role: >餐厅侦查员goal: >寻找目的地评分高的餐厅和用餐体验,并推荐风景优美和有趣的场所backstory: >你是一个热爱美食的人,熟悉本地最棒的用餐地点,你总能找到既美味又有氛围的餐厅,同时也能发现风景优美和适合游玩的好地方。# 行程整合者 Agent
itinerary_compiler:role: >行程整合师goal: >整合所有调研到的信息,编排成一个完整的逐日行程安排,确保包含航班与酒店信息;请用中文输出;backstory: >你擅长组织和呈现信息,注重细节,能够把零散内容整合为一个条理清晰、愉快易行的旅行计划。
4、配置任务
修改这个 tasks.yaml文件。
# 个性化活动规划任务
personalized_activity_planning_task:# 任务描述:为旅行者寻找符合兴趣和年龄段的活动与事件description: >调研并发现适合在 {destination} 进行的有趣活动。重点关注符合旅行者兴趣和年龄段的活动和事件。利用互联网搜索工具和推荐引擎获取信息。旅行者信息如下:- 出发地: {origin}- 目的地: {destination}- 年龄: {age}- 酒店位置: {hotel_location}- 航班信息: {flight_information}- 旅行时长: {trip_duration}# 预期输出:旅行期间每天推荐的活动清单expected_output: >一份按天列出的活动与事件推荐清单。每一项应包含活动名称、地点、简要描述、适合旅行者的理由,并尽可能附上评论和评分信息。# 餐厅与风景地点探索任务
restaurant_scenic_location_scout_task:# 任务描述:寻找优质餐厅与适合游玩的风景地description: >在 {destination} 寻找高评分的餐厅和独特的用餐体验。推荐风景优美的地点和有趣的活动,符合旅行者偏好。使用互联网搜索工具、餐厅评论网站和旅行指南。提供多样化选择,满足不同口味与预算,并提供评分信息。旅行者信息如下:- 出发地: {origin}- 目的地: {destination}- 年龄: {age}- 酒店位置: {hotel_location}- 航班信息: {flight_information}- 旅行时长: {trip_duration}# 预期输出:每天推荐的餐厅与景点清单expected_output: >一份按天列出的推荐餐厅、风景地点和活动清单。每一项应包括名称、地址、菜系或活动类型、简要描述及评分信息。# 行程整合任务
itinerary_compilation_task:# 任务描述:整合所有信息为完整的行程规划文档description: >整合所有调研信息,编排出 {destination} 的完整日程安排。行程应包含航班、酒店信息、计划的每日活动与用餐安排。使用文本格式化与文档生成工具进行内容组织与美化。# 预期输出:结构化的日程表expected_output: >一份详细的旅行行程文档。内容应包含逐日安排,并整合航班、酒店、活动、餐厅和风景地点等信息。格式为 Markdown,不带“```”
5、配置团队
修改这个 crew.py文件
from crewai import Agent, Crew, Process, Task
from crewai.project import CrewBase, agent, crew, task# 如果你有自定义工具,可以取消以下注释导入自定义工具
# from surprise_travel.tools.custom_tool import MyCustomTool# 以下是 CrewAI 提供的内置工具,用于网页搜索与抓取
from crewai_tools import SerperDevTool, ScrapeWebsiteTool
from pydantic import BaseModel, Field
from typing import List, Optional# 活动模型类:表示一天中安排的某一项活动
class Activity(BaseModel):name: str = Field(..., description="活动名称")location: str = Field(..., description="活动地点")description: str = Field(..., description="活动描述")date: str = Field(..., description="活动日期")cousine: str = Field(..., description="餐厅的菜系类型")why_its_suitable: str = Field(..., description="为什么这项活动适合旅行者")reviews: Optional[List[str]] = Field(..., description="活动的评论列表")rating: Optional[float] = Field(..., description="活动评分")# 每日旅行计划模型类
class DayPlan(BaseModel):date: str = Field(..., description="当天的日期")activities: List[Activity] = Field(..., description="当天的活动列表")restaurants: List[str] = Field(..., description="当天推荐的餐厅列表")flight: Optional[str] = Field(None, description="当天的航班信息(如有)")# 整体行程模型类
class Itinerary(BaseModel):name: str = Field(..., description="行程名称,可以有趣一点")day_plans: List[DayPlan] = Field(..., description="每天的行程计划列表")hotel: str = Field(..., description="酒店信息")# 使用 CrewBase 装饰器标记为 Crew 项目的入口
@CrewBase
class SurpriseTravelCrew():"""SurpriseTravel 旅行策划团队(crew)"""# 代理配置文件路径(YAML 格式)agents_config = 'config/agents.yaml'# 任务配置文件路径(YAML 格式)tasks_config = 'config/tasks.yaml'# 个性化活动规划 agent@agentdef personalized_activity_planner(self) -> Agent:return Agent(config=self.agents_config['personalized_activity_planner'], # 从配置文件加载 agent 设置tools=[SerperDevTool(), ScrapeWebsiteTool()], # 使用搜索和网页抓取工具verbose=True, # 输出详细执行日志allow_delegation=False, # 禁止任务委托给其他代理)# 餐厅与景点推荐 agent@agentdef restaurant_scout(self) -> Agent:return Agent(config=self.agents_config['restaurant_scout'],tools=[SerperDevTool(), ScrapeWebsiteTool()],verbose=True,allow_delegation=False,)# 整合所有信息并输出最终行程的 agent@agentdef itinerary_compiler(self) -> Agent:return Agent(config=self.agents_config['itinerary_compiler'],tools=[SerperDevTool()],verbose=True,allow_delegation=False,)# 个性化活动规划任务@taskdef personalized_activity_planning_task(self) -> Task:return Task(config=self.tasks_config['personalized_activity_planning_task'],agent=self.personalized_activity_planner() # 指定任务负责的 agent)# 餐厅与风景位置探索任务@taskdef restaurant_scenic_location_scout_task(self) -> Task:return Task(config=self.tasks_config['restaurant_scenic_location_scout_task'],agent=self.restaurant_scout())# 编译最终行程任务,并指定输出格式为 Itinerary 数据模型@taskdef itinerary_compilation_task(self) -> Task:return Task(config=self.tasks_config['itinerary_compilation_task'],agent=self.itinerary_compiler(),output_json=Itinerary # 指定结构化输出格式)@taskdef reporting_task(self) -> Task:return Task(config=self.tasks_config['itinerary_compilation_task'], # type: ignore[index]agent=self.itinerary_compiler(),output_file='report-01.md')# 将 agents 与 tasks 组装成一个完整的 crew 执行流@crewdef crew(self) -> Crew:"""创建 SurpriseTravel 团队,定义其执行流程"""return Crew(agents=self.agents, # 所有注册的代理(通过 @agent 自动生成)tasks=self.tasks, # 所有注册的任务(通过 @task 自动生成)process=Process.sequential, # 顺序执行所有任务verbose=True,# 如需使用分层流程,也可使用以下配置:# process=Process.hierarchical, 参考:https://docs.crewai.com/how-to/Hierarchical/)
6、配置主函数
修改这个 main.py文件
# 指定使用 Python 解释器运行该脚本import sys
import warnings # 导入警告处理模块
from datetime import datetime # 导入处理日期和时间的模块from surprise_trip.crew import SurpriseTravelCrew # 从项目中导入 SurpriseTravelCrew 类# 关闭特定模块中的语法警告(此处为 pysbd 模块)
warnings.filterwarnings("ignore", category=SyntaxWarning, module="pysbd")# 此主程序文件是为了在本地运行 crew 而设计的,请勿在此文件中添加不必要的逻辑。
# 你可以替换下面的 inputs 变量,它会自动填充任务和代理的信息。def run():"""运行 crew 执行流程。"""# 设置输入参数,可以根据需要修改。它会自动被各个任务和 agent 使用。inputs = {'origin': '上海虹桥机场(SHA)', # 出发地'destination': '北京大兴机场(PKX)', # 目的地'age': 31, # 用户年龄'hotel_location': '北京朝阳区', # 希望住的酒店位置'flight_information': '国航 CA1234,起飞时间为 2025年6月30日 上午10:00', # 航班信息'trip_duration': '14 天' # 旅行时长}try:# 实例化 SurpriseTravelCrew 并运行 crew 的 kickoff 方法(启动执行流程)SurpriseTravelCrew().crew().kickoff(inputs=inputs)except Exception as e:# 捕获并抛出异常,便于调试raise Exception(f"运行 crew 时发生错误: {e}")def train():"""训练 crew,执行指定次数的迭代。"""inputs = {'origin': '上海虹桥机场(SHA)', # 出发地'destination': '北京大兴机场(PKX)', # 目的地'age': 31, # 用户年龄'hotel_location': '北京朝阳区', # 希望住的酒店位置'flight_information': '国航 CA1234,起飞时间为 2025年6月30日 上午10:00', # 航班信息'trip_duration': '14 天' # 旅行时长}try:# 通过命令行参数获取迭代次数和保存的模型文件名# 使用 crew 的 train 方法进行训练SurpriseTravelCrew().crew().train(n_iterations=int(sys.argv[1]), filename=sys.argv[2], inputs=inputs)except Exception as e:# 捕获并抛出异常,便于调试raise Exception(f"训练 crew 时发生错误: {e}")def replay():"""从指定的任务 ID 开始回放 crew 执行过程。"""try:# 从命令行参数中获取任务 ID,并调用 replay 方法回放SurpriseTravelCrew().crew().replay(task_id=sys.argv[1])except Exception as e:# 捕获并抛出异常,便于调试raise Exception(f"回放 crew 时发生错误: {e}")def test():"""测试 crew 的执行逻辑,并返回评估结果。"""# 设置测试输入inputs = {"topic": "AI LLMs", # 测试主题,例如大语言模型"current_year": str(datetime.now().year) # 当前年份}try:# 从命令行参数中获取迭代次数和用于评估的 LLM 名称,调用 test 方法进行测试SurpriseTravelCrew().crew().test(n_iterations=int(sys.argv[1]), eval_llm=sys.argv[2], inputs=inputs)except Exception as e:# 捕获并抛出异常,便于调试raise Exception(f"测试 crew 时发生错误: {e}")
7、运行crew 启动项目
7.1、项目初始化(可选)
crewai install
7.2、启动项目
#要到项目根目录下
crewai run
8、查看思考和执行过程
中间省略...