使用说明
多智能体语音激活航班搜索系统
一个全面的航班搜索代理,具有语音输入功能,使用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日期进行结构化航班搜索
快速开始
文本输入模式
先决条件:
- Python 3.10+
- Amadeus API证书(把他们带到这儿来)
- Google API密钥
设置:
# 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暴露于ADKsearch_flights包装器agent_graph_module.amadeus客户端→ 启动时验证
您关心的文件:
- flight_search.py --主入口;将Gemini连接到LangGraph工具(仅限文本输入)
- flight_search_vtt.py --语音转文本集成的航班搜索
- voice_mcp_client.py --用于语音转文本MCP服务器的Python客户端
- langgraph_travel_agent/后端/agent_graph.py --search_flights LangChain工具和Amadeus管道
voice-to-text-mcp/--基于Rust的MCP语音识别服务器
语音集成设置
第一步:安装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
预期流量:
🎤 Listening... (max 30s, silence timeout 2s)- 说出您的航班要求
- 沉默2秒后录音停止
- 出现转录
- 解释器解析参数
- 执行者搜索航班
- 显示结果
使用指南
命令参考
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
语音输入最佳实践
为了获得最佳转录结果:
- 环境:在安静的房间里说话,减少背景噪音
- 说话风格:以正常语速清晰地说话,使用完整的句子
- 日期:明确注明日期(“12月15日”而非“12/15”)
- 停顿:在思考之间短暂停顿(静音检测有助于)
良好输入示例:
"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
“转录质量差”
尝试:
- 使用更好的型号(ggml small.en.bin)
- 说得更清楚、更慢
- 降低背景噪音
- 增加静音超时时间以延长暂停时间
航班搜索问题
“未返回任何结果”
检查表:
- 日期在未来
- 出发地/目的地是有效的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型号:
飞行愉快! ✈️🎤