语音激活航班搜索系统

一个支持语音和文本输入的多智能体航班搜索系统,集成了Amadeus API和Whisper AI,适用于需要无障碍访问的用户。

  • by fw2274
  • Jupyter Notebook
  • 本地部署
  • 更新于
在 GitHub 查看 fw2274/flight_agent

使用说明

多智能体语音激活航班搜索系统

一个全面的航班搜索代理,具有语音输入功能,使用Google ADK、Amadeus API、LangGraph和模型上下文协议(MCP)。

目录


概述

该项目实现了一个多代理系统,使用户能够使用语音命令或文本输入搜索航班。该应用程序旨在提高书写或与键盘交互有困难的用户的可访问性,包括有运动障碍、视觉障碍或喜欢语音交互的人。

系统流量

┌─────────────────┐
│  User speaks    │
│  flight query   │
└────────┬────────┘
         │
         ▼
┌─────────────────────────┐
│ Voice-to-Text MCP Server│  ← Rust-based, uses Whisper AI
│ (Rust + Whisper)        │
└────────┬────────────────┘
         │
         ▼ (JSON-RPC)
┌─────────────────────────┐
│ voice_mcp_client.py     │  ← Python MCP client
│ (Python MCP Client)     │
└────────┬────────────────┘
         │
         ▼
┌─────────────────────────┐
│ flight_search_vtt.py    │  ← Enhanced flight search
│ (Interpreter + Executor)│
└────────┬────────────────┘
         │
         ▼
┌─────────────────────────┐
│ LangGraph Flight Search │  ← Existing Amadeus integration
│ (agent_graph.py)        │
└─────────────────────────┘

关键能力

  • 🎤 语音输入:自然地说出你的航班要求
  • 💬 文本输入:传统文本查询支持
  • 🤖 双剂联用灭火系统:翻译代理+执行代理
  • ✈️ 真实飞行数据:Amadeus API集成
  • 🧠 智能解析:Gemini AI用于自然语言理解
  • 🎯 准确的结果:使用IATA代码和ISO日期进行结构化航班搜索

快速开始

文本输入模式

先决条件:

设置:

# 1. Setup environment
python -m venv .venv
source .venv/bin/activate  # On Windows: .venv\Scripts\activate
pip install -r requirements.txt

# 2. Configure credentials
echo "GOOGLE_API_KEY=your_key_here" >> .env
echo "AMADEUS_API_KEY=your_key_here" >> .env
echo "AMADEUS_API_SECRET=your_secret_here" >> .env

# 3. Run test search
python flight_search.py --query "Find a round-trip flight from ATL to JFK on Dec 02 returning Dec 15 for 2 adults in economy"

旗帜: --verbose (流工具调用), --debug (完整时间线)

语音输入模式

附加先决条件:

  • 锈
  • 麦克风
  • Whisper型号约200MB磁盘空间

设置:

# 1. Install Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source $HOME/.cargo/env

# 2. Build voice-to-text MCP server
cd voice-to-text-mcp
cargo build --release
./scripts/download-models.sh  # Choose ggml-base.en.bin
cd ..

# 3. Verify setup
./test_voice_setup.sh

# 4. Test voice input
python3 flight_search_vtt.py --voice

要说什么:

  • “查找从亚特兰大到纽约的往返机票,12月1日至12月15日,两名成人,经济舱”
  • “我需要1月10日从旧金山到芝加哥的航班,公务舱”

系统架构

三代理架构

代理1:语音识别代理

  • 捕获用户的语音输入并将其转换为文本
  • 技术:通过MCP服务器Whisper AI(基于Rust)
  • 硬件加速:Metal/CoreML(macOS)、CUDA(Linux/Windows)

Agent 2:信息提取Agent

  • 处理转录文本并提取结构化参数
  • 型号:Gemini 2.5 Flash Lite
  • 提取物:
    • 出发地和目的地城市/机场(IATA代码)
    • 出发和返回日期(ISO格式)
    • 乘客人数(成人、儿童、婴儿)
    • 客舱等级偏好
    • 特殊要求或偏好

代理3:航班搜索代理

  • 基于结构化信息执行航班搜索
  • 框架:LangGraph
  • API:Amadeus(真实飞行数据)
  • 输出:航班选项,包括价格、时间、航空公司、持续时间

组件详细信息

Amadeus工具来自 langgraph_travel_agent (根据 langgraph_travel_agent/backend).我们把它包起来 agent_graph.py 原语,因此Google ADK可以直接调用它们:

  • agent_graph_module.search_flights → 通过async暴露于ADK search_flights 包装器
  • agent_graph_module.amadeus 客户端→ 启动时验证

您关心的文件:


语音集成设置

第一步:安装Rust

# Install Rust via rustup
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

# Reload shell configuration
source $HOME/.cargo/env

# Verify installation
cargo --version
# Expected: cargo 1.91.1 (or later)

步骤2:构建MCP服务器

cd voice-to-text-mcp

# Build release version (takes 2-3 minutes first time)
cargo build --release

# Verify binary was created
ls -lh target/release/voice-to-text-mcp
# Expected: ~4.5MB binary

cd ..

步骤3:下载Whisper模型

根据您的需求选择合适的型号:

型号 尺寸 速度 精度 用例
ggml-tiny.en.bin 75MB 非常快 良好 测试、原型制作
ggml-base.en.bin 142MB 快 更好 一般用途(推荐) ⭐
ggml-small.en.bin 466MB 较慢 最佳 需要高精度

交互式下载:

cd voice-to-text-mcp
./scripts/download-models.sh
# Choose: ggml-base.en.bin
cd ..

手动下载:

cd voice-to-text-mcp/models/
wget https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-base.en.bin
cd ../..

步骤4:验证设置

./test_voice_setup.sh

它检查什么:

  • ✓ 防锈安装(货物)
  • ✓ MCP存储库存在
  • ✓ 二进制构建状态
  • ✓ Whisper型号可用性
  • ✓ Python集成文件
  • ✓ 环境变量

步骤5:测试语音输入

# Basic voice input test
python3 flight_search_vtt.py --voice

# Voice with debug output
python3 flight_search_vtt.py --voice --debug --verbose

预期流量:

  1. 🎤 Listening... (max 30s, silence timeout 2s)
  2. 说出您的航班要求
  3. 沉默2秒后录音停止
  4. 出现转录
  5. 解释器解析参数
  6. 执行者搜索航班
  7. 显示结果

使用指南

命令参考

flight_search_vtt.py选项:

--voice                     Enable voice input
--voice-timeout N           Recording timeout in milliseconds (default: 30000)
--voice-silence-timeout N   Silence timeout in milliseconds (default: 2000)
--mcp-server PATH          Path to MCP server binary
--mcp-model PATH           Path to Whisper model
--query TEXT               Use text query instead of voice
--debug                    Show debug timeline
--verbose                  Show tool calls/responses

语音输入最佳实践

为了获得最佳转录结果:

  1. 环境:在安静的房间里说话,减少背景噪音
  2. 说话风格:以正常语速清晰地说话,使用完整的句子
  3. 日期:明确注明日期(“12月15日”而非“12/15”)
  4. 停顿:在思考之间短暂停顿(静音检测有助于)

良好输入示例:

"Find a round trip from Atlanta to New York,
 departing December 1st, returning December 15th,
 for 2 adults in economy"

"I need a flight from San Francisco to Chicago
 on January 10th, one way, business class"

"Search for flights from LAX to JFK,
 leaving next Friday, returning the following Monday"

超时配置

# Quick commands (10 seconds)
python3 flight_search_vtt.py --voice --voice-timeout 10000 --voice-silence-timeout 1000

# Normal use (30 seconds) - DEFAULT
python3 flight_search_vtt.py --voice --voice-timeout 30000 --voice-silence-timeout 2000

# Detailed descriptions (60 seconds)
python3 flight_search_vtt.py --voice --voice-timeout 60000 --voice-silence-timeout 3000

示例会话

$ python3 flight_search_vtt.py --voice

🎤 Listening... (max 30s, silence timeout 2s)
   Speak your flight requirement now!

# User says: "Find a round trip from Atlanta to New York,
#             departing December 1st, returning December 15th,
#             for 2 adults in economy"

✓ Transcribed: 'Find a round trip from Atlanta to New York,
departing December 1st, returning December 15th,
for 2 adults in economy'

🧭 Interpreter Agent

✓ Interpreter output:
{
  "originLocationCode": "ATL",
  "destinationLocationCode": "JFK",
  "departureDate": "2025-12-01",
  "returnDate": "2025-12-15",
  "adults": 2,
  "travelClass": "ECONOMY"
}

🛠️  Executor Agent

→ Flight search: ATL → JFK
  Departure: 2025-12-01, Return: 2025-12-15, Adults: 2, Class: ECONOMY

✓ Received 3 flight results

📋 FLIGHT SEARCH RESULTS
[Flight options listed here...]

✅ Search complete!

技术细节

MCP(模型上下文协议)架构

什么是MCP?

  • 语言无关的通信协议
  • 基于JSON-RPC 2.0
  • 使工具能够跨不同语言工作

沟通:

  • 传输:stdio(stdin/stdout)
  • 协议:JSON-RPC 2.0
  • 暴露的工具: listen, transcribe_file

优点:

  • 语言无关(Rust服务器,Python客户端)
  • 标准化协议
  • 独立问题(音频处理与业务逻辑分离)
  • 可再用元件

语音处理

Whisper AI集成:

  • OpenAI Whisper(语音识别)
  • 量化模型(ggml格式)
  • 仅限英语变体(.en后缀)

硬件加速:

  • macOS:金属GPU+CoreML(苹果神经引擎)
  • Linux/Windows:CUDA(英伟达GPU)
  • 回退:仅CPU

录制格式:

  • 采样率:16kHz
  • 频道:单声道
  • 格式:WAV(PCM)

自动停止逻辑:

  • 记录最多 timeout_ms 毫秒
  • 如果出现以下情况,请提前停止 silence_timeout_ms 检测到沉默
  • 静音阈值:-30dB

谷歌ADK集成

代理配置:

# Interpreter Agent
model = "gemini-2.5-flash-lite"
temperature = 0.3  # Low for consistent parsing

# Executor Agent
model = "gemini-2.5-flash-lite"
tools = [search_flights]

LangGraph集成

密钥文件: langgraph_travel_agent/后端/agent_graph.py

增强的错误处理:

except ResponseError as error:
    error_code = getattr(error, 'code', 'UNKNOWN')
    error_description = getattr(error, 'description', str(error))

    # Extract from response body
    if hasattr(error, 'response') and error.response:
        error_body = error.response.body
        if isinstance(error_body, dict):
            errors = error_body.get('errors', [])
            if errors:
                first_error = errors[0]
                error_code = first_error.get('code', error_code)
                error_description = first_error.get('detail', error_description)

故障排除

设置问题

“cargo:找不到命令”

# Install Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source $HOME/.cargo/env

“找不到MCP服务器二进制文件”

cd voice-to-text-mcp && cargo build --release

“未找到Whisper型号”

cd voice-to-text-mcp && ./scripts/download-models.sh

缺少API密钥

# Check .env file exists
cat .env

# Verify all keys are set
grep GOOGLE_API_KEY .env
grep AMADEUS_API_KEY .env
grep AMADEUS_API_SECRET .env

语音输入问题

“没有可用的输入设备”

检查表:

  • 麦克风已连接并正常工作
  • 麦克风未被其他应用程序使用
  • 系统具有麦克风权限

macOS:

System Settings → Privacy & Security → Microphone
Ensure Terminal has access

Linux:

# Check audio devices
arecord -l

# Test microphone
arecord -d 5 test.wav
aplay test.wav

“录制过早中断”

# Increase silence timeout
python3 flight_search_vtt.py --voice --voice-silence-timeout 5000

# Increase overall timeout
python3 flight_search_vtt.py --voice --voice-timeout 45000

“转录质量差”

尝试:

  1. 使用更好的型号(ggml small.en.bin)
  2. 说得更清楚、更慢
  3. 降低背景噪音
  4. 增加静音超时时间以延长暂停时间

航班搜索问题

“未返回任何结果”

检查表:

  • 日期在未来
  • 出发地/目的地是有效的IATA代码或城市名称
  • 旅行日期是现实的

调试:

python3 flight_search_vtt.py --query "Your query" --debug --verbose

常见的Amadeus API错误代码:

  • 38194:来源/目的地无效→ 使用有效的IATA代码(例如。, ATL, JFK)
  • 477:日期格式无效→ Use YYYY-MM-DD 格式
  • 4926:无可用航班→ 尝试不同的日期或路线
  • 38187:乘客人数无效→ 检查成人/儿童/婴儿计数

集成示例

在其他项目中使用MCP客户端

这 voice_mcp_client.py 可以在任何Python项目中使用:

from voice_mcp_client import VoiceToTextMCPClient

# Initialize client
client = VoiceToTextMCPClient(
    mcp_server_path="voice-to-text-mcp/target/release/voice-to-text-mcp",
    model_path="voice-to-text-mcp/models/ggml-base.en.bin"
)

# Listen for voice input
user_input = client.listen(
    timeout_ms=30000,         # 30 seconds max
    silence_timeout_ms=2000,  # Stop after 2s silence
    auto_stop=True            # Enable auto-stop
)

print(f"User said: {user_input}")

# Transcribe existing audio file
transcript = client.transcribe_file("audio.wav")
print(f"Transcription: {transcript}")

自定义航班搜索工作流程

from voice_mcp_client import VoiceToTextMCPClient
import os
from dotenv import load_dotenv

# Load environment
load_dotenv()

# Initialize voice client
voice_client = VoiceToTextMCPClient(
    "voice-to-text-mcp/target/release/voice-to-text-mcp",
    "voice-to-text-mcp/models/ggml-base.en.bin"
)

# Get voice input
print("🎤 Speak your flight requirement...")
query = voice_client.listen(timeout_ms=30000)
print(f"✓ Heard: {query}")

# Process with your custom agent
# ... your code here ...

参考文献

官方文件:

相关项目:

Whisper型号:


飞行愉快! ✈️🎤