[项目实训博客-TravelMind途灵]3.将旅行规划Agent接入home中的输入框和交互页面中的聊天框
·
在上一周的工作中我们实现了TravelAgent的设计与实现,并且进行了测试,成功实现了结合实时信息的旅行推荐Agent。
在此之后我们将TravelAgent与TravelMind中需要交互的功能进行结合,主要完成了三个任务:
- 实现home页面输入搜索框的功能实现和跳转
- 将用户在home中输入的数据传进交互页面中并进行显示
- 在聊天框中设计等待Agent回复的提示
- 将Agent根据实时信息作出的回复接入聊天页面中,实现与用户的交互
实现上述功能主要用到的技术有:Agent、路由、函数调用与信息传递、按键监听、消息展示钩子、useEffect的设计
主要实现代码如下:
Home.js
const handleInputSubmit = () => {
if (!inputValue.trim()) return;
// 直接跳转到chat页面,将输入值传递过去
navigate('/chat', {
state: {
userInput: inputValue
}
});
};
<div style={{ display: "flex", justifyContent: "center", alignItems: "center", padding: "20px", marginTop: "100px" }}>
<Input
placeholder="Ask me anything..."
prefix={<AudioFilled style={{ fontSize: "18px", color: "#888", marginRight: "8px", cursor: 'pointer' }} />}
suffix={
<Button
color="blue"
variant="text"
icon={<RocketFilled />}
style={{ fontSize: '24px', padding: '0 16px' }}
onClick={() => {
console.log('Button clicked directly'); // 直接检查按钮点击
handleInputSubmit();
}}
/>
}
value={inputValue}
onChange={(e) => setInputValue(e.target.value)} // 更新输入值
style={{
width: "70%",
maxWidth: "600px",
height: "60px",
fontSize: "16px",
borderRadius: "24px",
padding: "0 16px",
boxShadow: "0 4px 10px rgba(0,0,0,0.1)",
border: "1px solid #ddd",
}}
/>
</div>
Agent.js
async function testChats(input) {
try {
// 调用第一个 Chat
const firstOutput = await firstChat(input);
console.log('First Chat Output:', firstOutput);
// 使用第一个 Chat 的输出作为车票查询的输入
const ticketInfo = queryTrainTickets(firstOutput);
console.log('Ticket Information:', ticketInfo);
// 使用车票信息作为第二个 Chat 的输入
const secondInput = ticketInfo;
console.log('Second Chat Input:', secondInput);
// 调用第二个 Chat
const secondOutput = await secondChat(secondInput);
// 输出最终结果
console.log('Final Output:', secondOutput);
// 返回最终结果
return secondOutput;
} catch (error) {
console.error('Error in testChats:', error.message);
return 'An error occurred in testChats. Please try again.';
}
}
Chat_layout.js
const [input, setInput] = useState("");
const initialProcessed = useRef(false);
// 修改 useEffect 处理逻辑
useEffect(() => {
const processUserInput = async () => {
// 使用 useRef 检查是否已处理过初始输入
if (userInput && !initialProcessed.current) {
initialProcessed.current = true; // 标记为已处理
try {
setIsLoading(true);
// 先显示用户输入
setMessages(prev => [...prev, { sender: "user", text: userInput }]);
// 调用API获取响应
const result = await testChats(userInput);
// 只添加机器人响应
setMessages(prev => [...prev, { sender: "bot", text: result }]);
} catch (error) {
console.error('Error:', error);
setMessages(prev => [...prev,
{ sender: "bot", text: "抱歉,处理您的请求时出现了错误。" }
]);
} finally {
setIsLoading(false);
}
}
};
processUserInput();
}, [userInput]); // 移除 initialMessageProcessed 依赖
const handleSend = async () => {
if (!input.trim()) return;
setMessages(prev => [...prev, { sender: "user", text: input }]);
setInput("");
setIsLoading(true);
try {
const result = await testChats(input);
setMessages(prev => [...prev, { sender: "bot", text: result }]);
} catch (error) {
console.error('Error:', error);
setMessages(prev => [...prev,
{ sender: "bot", text: "抱歉,处理您的请求时出现了错误。" }
]);
} finally {
setIsLoading(false);
}
};
{/* 中间聊天区域 */}
<Content style={{ display: "flex" }}>
<div className="chat-panel">
<div className="chat-header">🧭 TripBot</div>
<div className="chat-history">
{messages.map((msg, idx) => (
<div key={idx} className={`chat-message ${msg.sender}`}>
{msg.text}
</div>
))}
{isLoading && (
<div className="chat-message bot loading">
<span>正在为您规划行程...</span>
</div>
)}
</div>
<div className="chat-input">
<input
type="text"
value={input}
placeholder="Describe your outing"
onChange={(e) => setInput(e.target.value)}
onKeyDown={(e) => e.key === "Enter" && handleSend()}
/>
<button onClick={handleSend}>➤</button>
</div>
</div>
实际效果图如下:


openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。
更多推荐


所有评论(0)