feat: 改进计划生成体验与 AI 提示词

- 生成中状态改为滚动日志列表,底部新增消息自动滚动
- 返回想法池不再清空计划,pool 页面保留"待确认计划"横幅
- 换方案时才清空旧计划
- 提示词补充午餐/晚餐时间窗口约束(午餐11:30-13:00,晚餐17:30-19:30)
- get_travel_time 从驾车改为公共交通,阈值从30分钟调整为45分钟
This commit is contained in:
2026-03-02 11:26:20 +08:00
parent b78063739b
commit df2e373beb
3 changed files with 80 additions and 35 deletions
+7 -6
View File
@@ -34,12 +34,13 @@ const SCHEDULE_SYSTEM_PROMPT = `你是一个周末行程规划师。根据用户
规划原则:
1. 选择地理位置相近的 POI,最小化总移动距离
2. 尊重活动的时间偏好(公园上午、正餐在饭点、电影灵活)
3. 活动之间留出合理的交通时间(15-30分钟
4. 如果有"category"类型的活动,选择离其他已确定地点最近的候选
5. 高低强度活动交替安排,避免连续高体力活动
6. 费用平衡,避免连续安排 premium 级别活动
7. 需要预约(needsBooking)的活动,在 reason 中提醒用户提前预约
2. 严格遵守用餐时间窗口:午餐安排在 11:30-13:00,晚餐安排在 17:30-19:30,不得超出此范围
3. 尊重活动的时间偏好(morning 的活动放 9:00-12:00afternoon 的活动放 13:00-17:00evening 的活动放 19:00 以后
4. 活动之间留出合理的交通时间(15-30分钟)
5. 如果有"category"类型的活动,选择离其他已确定地点最近的候选
6. 高低强度活动交替安排,避免连续高体力活动
7. 费用平衡,避免连续安排 premium 级别活动
8. 需要预约(needsBooking)的活动,在 reason 中提醒用户提前预约
返回 JSON 格式:
{
+18 -15
View File
@@ -195,7 +195,7 @@ export interface PlanGenResult {
const AGENT_SYSTEM_PROMPT = `你是一个周末行程规划 Agent。你有以下工具可以使用:
- list_ideas: 查看想法池中的所有活动
- search_poi: 在地图上搜索地点(支持品牌名、地名、品类搜索)
- get_travel_time: 查询两点间驾车时间和距离
- get_travel_time: 查询两点间公共交通(地铁/公交)时间和距离
- finalize_plan: 提交最终行程方案
规划流程:
@@ -203,13 +203,14 @@ const AGENT_SYSTEM_PROMPT = `你是一个周末行程规划 Agent。你有以下
2. 根据时间、多样性、强度平衡选出合适的活动组合
3. 为每个活动 search_poi 找到具体地点
4. 如果搜索结果不理想(0结果或不相关),尝试换关键词重搜
5. 用 get_travel_time 检查关键路段的交通时间,如果某段超过 30 分钟考虑换更近的地点
5. 用 get_travel_time 检查关键路段的公共交通时间,如果某段超过 45 分钟考虑换更近的地点
6. 综合地理位置、时间安排、活动特点,规划最优路线
7. 确认无误后 finalize_plan 提交
规划原则:
- 地理位置相近,最小化移动距离
- 尊重时间偏好(morning 的活动放上午,dining 在饭点)
- 严格遵守用餐时间窗口:午餐安排在 11:30-13:00,晚餐安排在 17:30-19:30,不得超出此范围
- 尊重时间偏好(morning 的活动放 9:00-12:00afternoon 的活动放 13:00-17:00evening 的活动放 19:00 以后)
- 活动间留 15-30 分钟交通时间
- 高低强度交替,避免连续高体力活动
- 费用均衡,不连续安排 premium 活动
@@ -236,6 +237,7 @@ function buildAgentTools(
taggedIdeas: TaggedIdea[],
lat: number,
lng: number,
city: string,
): AgentTool[] {
const listIdeasTool: AgentTool = {
name: "list_ideas",
@@ -301,7 +303,7 @@ function buildAgentTools(
const getTravelTimeTool: AgentTool = {
name: "get_travel_time",
description: "查询两点之间的驾车预估时间和距离。用于验证活动之间的交通是否合理",
description: "查询两点之间的公共交通(地铁/公交)预估时间和距离。用于验证活动之间的交通是否合理",
parameters: {
type: "object",
properties: {
@@ -318,31 +320,32 @@ function buildAgentTools(
const dLat = Number(args.dest_lat);
const dLng = Number(args.dest_lng);
const apiKey = requireAmapApiKey();
const url = new URL("https://restapi.amap.com/v5/direction/driving");
const url = new URL("https://restapi.amap.com/v5/direction/transit/integrated");
url.searchParams.set("key", apiKey);
url.searchParams.set("origin", `${oLng},${oLat}`);
url.searchParams.set("destination", `${dLng},${dLat}`);
url.searchParams.set("city", city);
url.searchParams.set("show_fields", "cost");
try {
const res = await fetch(url.toString());
const data = await res.json();
if (data.status !== "1" || !data.route?.paths?.length) {
return JSON.stringify({ error: "未找到路线" });
if (data.status !== "1" || !data.route?.transits?.length) {
return JSON.stringify({ error: "未找到公交路线" });
}
const path = data.route.paths[0];
const transit = data.route.transits[0];
return JSON.stringify({
distanceKm: Math.round(Number(path.distance) / 100) / 10,
durationMin: Math.ceil(Number(path.duration) / 60),
distanceKm: Math.round(Number(data.route.distance) / 100) / 10,
durationMin: Math.ceil(Number(transit.duration) / 60),
});
} catch {
return JSON.stringify({ error: "路线查询失败" });
}
},
progressBefore: () => "正在查询交通时间...",
progressBefore: () => "正在查询公共交通时间...",
progressAfter: (_args, result) => {
const r = JSON.parse(result);
if (r.error) return `路线查询失败`;
return `驾车${r.durationMin} 分钟(${r.distanceKm}km`;
return `公共交通${r.durationMin} 分钟(${r.distanceKm}km`;
},
};
@@ -394,13 +397,13 @@ function buildAgentTools(
}
async function runAgentPlanGeneration(
room: { lat: number; lng: number },
room: { lat: number; lng: number; city: string },
taggedIdeas: TaggedIdea[],
availableTime: PlanGenAvailableTime,
onProgress?: (message: string) => void,
): Promise<{ days: FinalizePlanDay[] }> {
const at = availableTime;
const tools = buildAgentTools(taggedIdeas, room.lat, room.lng);
const tools = buildAgentTools(taggedIdeas, room.lat, room.lng, room.city ?? "");
const userPrompt = `帮我规划行程。
可用时间:${at.date}${at.startHour}:00 - ${at.endHour}:00
@@ -632,7 +635,7 @@ export async function runPlanGeneration(
try {
const agentResult = await runAgentPlanGeneration(
{ lat: room.lat, lng: room.lng },
{ lat: room.lat, lng: room.lng, city: room.city ?? "" },
taggedIdeas,
availableTime,
onProgress,