团队项目第一次作业
「随行条件」旅游攻略 Agent —— 团队展示 · 选题报告 · 需求分析
一二三队 | 软件工程课程设计 · 第一次作业
一句话:把几十篇长攻略,压成一份带着你的条件、走得动、下雨也有 Plan B、每句话都有出处的行程。
0. 作业信息
| 项目 | 内容 |
|---|---|
| 作业所属课程 | https://edu.cnblogs.com/campus/gdgy/Class78-Grade2024-CS |
| 作业要求 | https://edu.cnblogs.com/campus/gdgy/Class78-Grade2024-CS/homework/16767 |
| 文档 | https://docs.qq.com/doc/DZU5GWEF2eW1qcG5z?rtkey=116e055b96faa16756a6c9931tURx1&appletId=14b730a4-4f67-47fe-acaf-8431b93afab5 |
| 团队名称 | 一二三队 |
| 团队成员 | 3124004224 宋浩霖 | 3124004203 程源 |
我理解的作业目标
这次作业不是交一个能跑的软件,而是立项:把“为谁做、解决什么问题、凭什么由我们做、做成什么样算完成”讲清楚,并且经得起追问。
但“立项”不等于“画大饼”。作业里写了两条硬约束:最终所有应用要上线运行,供老师、助教和其他同学检查;最终验收会参考需求文档。所以我们给自己定的标准是:
- 选题要来自真实需求,不能是“我们觉得这个很酷”;
- 功能要能验收,每条需求都要有对应的验收方式;
- 技术方案要能落地,这一版就按“能上线”的形态来设计,而不是先画一个以后再说的饼。
1. 团队展示
1.1 队名
一二三队。
名字很朴素,我们的解释也很朴素:一次只推进一步,但每一步都算数。做这个项目的过程基本也是这样——先把攻略读明白,再把条件说清楚,最后才谈生成。
1.2 团队项目的具体规划与描述
「随行条件」旅游攻略 Agent 是一个面向多代同游场景的 Web 应用。它不生产攻略,而是把团队手动收集的 50–100 篇长篇攻略,预处理成带条件标签的结构化片段;用户用自然语言或多条件组合描述自己的出行约束,后端检索相关片段并调用 DeepSeek,生成:
- 分时段可执行行程(几点去哪、走多久、在哪吃);
- 雨天备选方案(下雨那天换哪套,而不是把行程删一半);
- 每条建议的原文出处(点开就能看到是哪篇攻略的哪一段);
- 条件标签(步行强度 / 母婴设施 / 无障碍情况)。
规划上分三步走:11 月把需求和 50 篇攻略的数据底座做完;12 月打通“检索 → 生成 → 前端”整条链路,内网可演示;1 月部署到公网,按验收脚本能复现。范围只覆盖杭州、苏州、成都三城,只做单 Agent,不做 UGC 社区、不做用户体系。
1.3 队员风采
| 学号 | 姓名 | 性格 | 擅长的技术 | 兴趣爱好 | 希望的软工角色 |
|---|---|---|---|---|---|
| 3124004224 | 宋浩霖 | 沉稳,乐观 | 需求分析、HTML/JS、SSE 前端渲染 | 写代码,学习 | PM / 需求 · 前端 |
| 3124004203 | 程源 | 善于思考,急性子 | Node.js、检索与 Prompt 设计、数据处理 | 唱歌,运动 | 后端 / 数据 |
1.4 团队的首次合照

1.5 团队项目的愿景(约 100 字)
我们希望「随行条件」成为家庭出游时那个“先问一句”的助手:不问你想去哪,而问你和谁去、走不走得动、下雨怎么办。让每一个带着条件出发的家庭,都能在十分钟内拿到一份走得动、有备选、说得清依据的行程;也让攻略里的每一句话,都能找到它的出处。
2. 选题报告
2.1 需求从哪来:三次“走不动”的出行
这个选题不是拍脑袋,是从身边三次很具体的出行里长出来的。
场景一:带 3 岁孩子。 推车能不能走?哪一层有母婴室?厕所在几楼?
攻略里写了景点和美食,却没写这段路有没有台阶。
场景二:带腿脚不便的老人。 这段有没有坡?走多久能坐下?
“风景很好”对老人不是信息,“全程缓坡、每 300 米有座椅”才是。
场景三:第二天下雨。 Plan B 在哪?临时改会不会白跑?
天气一变,前一天排好的路线基本作废,用户只能现场打开手机硬扛。
三次场景指向同一个结论:攻略不是没写,是写在了 8000 字的第 5 屏。 用户要的不是更多攻略,是被“按我的条件筛过”的答案。
2.2 现有产品差在哪
| 对比维度 | 攻略平台(马蜂窝 / 小红书) | 通用 AI 助手 | 「随行条件」 |
|---|---|---|---|
| 按复合条件筛 | ◐ 只能按“亲子/周边”这类标签筛 | ◐ 能听懂,但会自由发挥 | ● 人员 / 天气 / 步行上限 / 设施等 8 个条件组合后检索 |
| 雨天 / 闭馆备选 | ○ 基本没有 | ◐ 有时会给 | ● 必备,且每条备选带出处 |
| 每条建议的出处 | ○ 靠自己翻原文 | ○ 无法核验 | ● 每条建议后有 [n],点开是原文那一段 |
| 体力 / 设施标签 | ○ 无 | ○ 无 | ● 步行强度 · 母婴设施 · 无障碍 |
不是要再做一个攻略平台,而是补上“决策”这一层。
2.3 一句话定位
面向多代同游的条件化攻略决策助手:输入是条件,输出是走得动、有备选、可溯源的行程。
2.4 杀手级功能
这是整个项目最想让老师记住的一个功能,所以用用户语言说,而不是用技术语言说:
用户说一句:“杭州 2 天,带 3 岁小孩和腿脚不便的老人,第二天可能下雨,步行别太多。”
系统从大量长攻略里抽出适合的景点、餐饮、交通和避坑点,给出——
① 分时段可执行行程;② 雨天备选方案;③ 每条建议的攻略出处;④ 步行强度 / 母婴 / 无障碍标签。
它的关键在于三件事同时成立:
- 有条件的:不是通用行程,是按“谁去、什么天气、能走多少”筛过的;
- 可执行的:落到几点、走多久、在哪吃,而不是罗列景点;
- 可核验的:每条建议都能点回原文,说不清出处的会标“出处待核对”,不编。
“预处理长文本”“RAG”“Prompt 组装”是支撑它的手段,不是它本身。这一点我们在选题时反复纠正过自己:老师问“杀手级功能”,想听的是用户得到了什么,而不是我们用了什么技术。
2.5 创新点
| # | 创新点 | 具体是什么 | 现有产品的空白 |
|---|---|---|---|
| 1 | 条件组合,而不是单标签 | 同行人员、天气、步行上限、母婴、无障碍、天数、城市同时生效,冲突时主动提示冲突 | 最多做到“亲子”一个标签 |
| 2 | 每条建议可回溯到原文 | 建议 → 片段 → 原文段落,三级可查;编号缺失就标“出处待核对” | 通用 AI 无法核验,平台靠用户自己翻 |
| 3 | 备选方案是必选项 | 下雨、闭馆、孩子闹情绪都有对应 Plan B | 这是现有产品最普遍的空白 |
单看每一条都不算石破天惊,但“可溯源 + 备选”这两条叠在一起,就要求整条数据链路(预处理字段、检索、生成、展示)都重做一遍。这也是我们认为它比“又一个 AI 行程生成器”更难被抄的原因。
2.6 适用范围与边界
- 适用:多代同游、亲子出行、有无障碍需求的家庭;2–3 天的城市短途(杭州 / 苏州 / 成都)。
- 暂不覆盖:出境长线、自驾、实时票务与价格。V1.0 只验证“条件 → 行程”这一条链路。
- 明确不做:完整 UGC 社区、复杂用户系统与权限、移动端原生 App / 小程序、自动爬虫与大规模采集、多智能体协商。
2.7 技术可行性:为什么做得出来
- 数据可控:50–100 篇手动收集,来源公开可引用,规模小但每一篇都能被预处理成结构化字段,演示够用。
- 模型够用:DeepSeek API 兼容 OpenAI SDK,
stream: true支持流式输出,接进 Web 后端是最短路径。 - 链路清晰:预处理与检索是我们自己写的确定性代码,模型只负责“组织”,不负责“发现”,所以可测、可降级。
- 风险已知:长链路任何一环超时都会影响演示,所以从设计之初就写了降级策略(检索为空不调用生成、超时返回片段摘要)。
3. 需求分析
本节只写骨架和关键判断;完整的功能字段、接口报文、数据字典和逐条验收对照表见需求规格说明书。
3.1 迭代记录
| 版本 | 日期 | 修改人 | 修改内容 | 评审 |
|---|---|---|---|---|
| V0.1 | 2026-11-01 | 宋浩霖 | 初稿:项目范围、用户角色、功能结构 | 全组 |
| V0.2 | 2026-11-03 | 程源 | 补充预处理字段、检索与 Prompt 方案 | 宋浩霖 |
| V0.3 | 2026-11-05 | 宋浩霖 | 补充前端页面、SSE 事件与交互状态 | 全组 |
| V1.0 | 2026-11-07 | 全组 | 补齐接口、类图、验收对照表,定稿 | 全组 |
3.2 项目标志
- 项目编号:TC-Agent-2026
- 标识元素:一条蜿蜒的路线 + 一枚定位点,代表“按条件走出来的路”;配色取西湖的墨绿与米白,点缀陶土橙。
- 文档封面与 PPT 使用同一套文字标识,不做复杂图形,保证在不同设备上都清晰。
3.3 功能结构(思维导图)
「随行条件」旅游攻略 Agent
├── 1 攻略数据管理(3)
│ ├── 1.1 攻略长文本导入
│ ├── 1.2 原文存储与来源标识
│ └── 1.3 攻略列表查看
├── 2 预处理与结构化(5)
│ ├── 2.1 长文本分块
│ ├── 2.2 结构化字段抽取
│ ├── 2.3 条件标签标注(步行/母婴/无障碍/雨天备选)
│ ├── 2.4 抽取结果查看与人工修正
│ └── 2.5 结构化片段入库
├── 3 条件查询(3)
│ ├── 3.1 自然语言条件输入
│ ├── 3.2 多条件组合选择
│ └── 3.3 条件解析与检索参数生成
├── 4 Agent 生成(6)
│ ├── 4.1 攻略片段检索
│ ├── 4.2 Prompt 组装与上下文构造
│ ├── 4.3 DeepSeek API 调用(流式)
│ ├── 4.4 分时段行程生成
│ ├── 4.5 雨天备选方案生成
│ └── 4.6 出处溯源与条件标签附着
├── 5 结果展示(4)
│ ├── 5.1 行程流式展示
│ ├── 5.2 备选方案展示
│ ├── 5.3 出处引用展示
│ └── 5.4 条件标签展示
└── 6 异常与降级(4)
├── 6.1 Agent 超时提示
├── 6.2 检索为空处理
├── 6.3 接口异常提示与重试
└── 6.4 调用日志记录
6 大模块、25 项子功能。前三个模块解决“数据从哪来、怎么读懂”,4 和 5 是核心链路,6 是兜底——它不是附属功能,而是这个产品敢不敢让人用的前提。
3.4 核心类图
系统共 8 个类,其中 7 个是核心领域类,1 个是降级日志:
这张图里最重要的不是字段,是从 AgentResponse 到 Citation 再到 GuideChunk 这条回路:它保证了“每条建议都能回到原文”,也让“可溯源”从一句口号变成了一个可以被检查的数据结构。
3.5 功能描述(挑三条讲透)
完整的功能表在需求文档第 6 章,这里挑三条最能说明问题的。
FR-PRE-02 结构化字段抽取
| 项 | 内容 |
|---|---|
| 使用角色 | 系统(由团队成员触发) |
| 优先级 | 高 |
| 前置条件 | 攻略原文已完成分块 |
| 输入 | 一个 GuideChunk 文本片段 |
| 处理逻辑 | 按数据字典抽取:地点、适合人群、步行强度、母婴设施、无障碍情况、雨天备选、建议时长、交通方式、注意事项、来源位置 → 写入片段 |
| 输出 | 带条件标签的结构化片段 |
| 异常与边界 | 抽不到就填“未知”,不留空;低置信度片段标“待人工复核”;不得编造原文不存在的信息 |
| 关联 | INT-01;GuideChunk;附录 A 数据字典 |
这一条是整条链路的“地基”。如果字段定义不清,后面的检索和生成全是黑盒,验收时也没法判断做没做对。
FR-AGENT-01 条件化行程生成与出处溯源
| 项 | 内容 |
|---|---|
| 使用角色 | 普通用户 |
| 优先级 | 高 |
| 输入 | 用户条件 + 检索到的片段(已按相关度编号) |
| 处理逻辑 | 后端组装 system prompt(角色、输出结构、引用规则)与 user 内容(条件 + 带编号片段)→ 调用 DeepSeek 流式接口 → 按“分时段行程 / 雨天备选 / 每条建议附编号与标签”输出 → 后端把编号映射成 Citation → SSE 推送 |
| 输出 | 行程 + 备选 + 出处 + 标签 |
| 异常与边界 | 首字超过 5 秒提示“生成较慢”;60 秒未完成返回已生成部分;模型漏标编号时标“出处待核对”;不得输出检索片段之外的地点作为主推荐 |
| 关联 | API-02、INT-03;AgentRequest / AgentResponse / Citation |
FR-FALLBACK-01 Agent 调用降级
| 项 | 内容 |
|---|---|
| 触发 | 超时、限流、5xx 或网络错误 |
| 处理 | 网络错误 / 5xx 重试 1 次(4xx 不重试)→ 仍失败写 FallbackLog → 返回标准化错误码 → 前端展示“智能生成暂不可用”+ 检索片段摘要 |
| 边界 | 不向前端泄露 Key、内部地址、原始堆栈;降级内容必须明确标注“非智能生成”,不能伪装成模型输出 |
3.6 前端与后端
前端只要三个页面,够用就行:条件输入页、结果展示页、出处详情浮层。真正的难点不在页面,而在流式渲染的状态管理:收到 meta 显示加载、收到 chunk 增量渲染、收到 citation 插入出处标记、收到 done 关闭连接、收到 error 给出重试入口,中间断流要保留已展示内容。
后端是“代理 + 编排”:接收条件 → 解析成检索参数 → 检索片段 → 组装 Prompt → 调 DeepSeek → 转发 SSE → 记录日志。前后端只认 5 个接口:
| 编号 | 方法 | 路径 | 用途 |
|---|---|---|---|
| API-01 | POST | /api/query |
创建查询,返回 queryId 与片段数 |
| API-02 | GET | /api/query/{id}/stream |
SSE 流式获取生成结果 |
| API-03 | GET | /api/query/{id}/result |
非流式兜底,取完整结果 |
| API-04 | GET | /api/citation/{id} |
出处:原文摘录、标题、来源、位置 |
| API-09 | GET | /api/health |
服务与 DeepSeek 连通状态 |
SSE 有 5 类事件:meta / chunk / citation / done / error,连接超时 60 秒。
3.7 智能体如何嵌入(这块是重点)
作业要求“智能体要能嵌入到你开发的软件系统中”,我们的做法是后端代理 + 流式返回:
三个关键点:
- Key 只在后端:
DEEPSEEK_API_KEY放在后端环境变量,前端代码、网络面板、日志、版本库里都不出现; - 上下文我们说了算:检索片段按相关度排序、编号、按 token 上限截断,模型只看到我们给的材料;
- 失败有退路:超时/5xx 降级为片段摘要,检索为空直接不调用模型。
接口层面:POST https://api.deepseek.com/chat/completions,模型 deepseek-chat,stream: true,连接超时 10s、首字期望 ≤5s、整体 60s。
3.8 验收标准
需求写了多少,就要能验多少。我们的验收方式是可复现的七步演示脚本:
| 步骤 | 操作 | 预期结果 |
|---|---|---|
| 1 | 导入 1 篇杭州长攻略 | 返回 textId,原文完整保存 |
| 2 | 触发预处理 | 生成多个片段,字段含位置与条件标签 |
| 3 | 输入“杭州 / 2 天 / 3 岁小孩 / 老人腿脚不便 / 第二天雨” | 返回 queryId 与检索片段数 |
| 4 | 观察流式生成 | 5 秒内出现首字,内容逐步出现,不白屏 |
| 5 | 检查结果 | 分时段行程 + 雨天备选 + 每条建议带 [n] 与标签 |
| 6 | 点开 2 条出处 | 浮层展示原文摘录、标题、来源、片段位置 |
| 7 | 断网 / 模拟超时,再查“北京” | 降级提示 + 片段摘要;未覆盖城市返回空结果,不编造 |
三条硬指标:首字 ≤5s、整体 ≤60s、抽查 10 条建议出处 100% 可映射。
3.9 非功能指标
| 维度 | 指标 |
|---|---|
| 性能 | 普通接口 P95 ≤ 2s;Agent 首字 ≤5s、整体 ≤60s |
| 可用性 | Agent 失败时页面不白屏,必须有降级提示与重试入口 |
| 安全 | Key 仅后端持有;用户输入转义防 XSS;日志不含 Key 与隐私文本 |
| 兼容 | Chrome / Edge / Firefox 最新两个主要版本,支持 SSE |
| 可维护 | 抽取字段、Prompt 模板、模型名全部配置化 |
4. 上线计划
老师明确要求“最终需要上线运行”,所以这一块不是可选项:
| 阶段 | 时间 | 交付 |
|---|---|---|
| 数据与需求 | 2026.11 | 需求定稿;50 篇攻略入库;预处理跑通,抽检 10 条 |
| 链路打通 | 2026.12 | 检索 + Agent + 前端联调;SSE 与降级可用;内网演示 |
| 公网部署 | 2027.01 | 前端 Vercel / 后端 Render(或校园服务器);HTTPS 域名可访问;按验收脚本复现 |
上线形态:一个公网可访问的 https 地址 + 一套只含杭州的演示数据,其余城市同理。
5. 分工与下一步
| 成员 | 主要负责 | 本轮产出 |
|---|---|---|
| 宋浩霖 | 需求、前端、答辩 | 需求文档、条件表单与 SSE 渲染、PPT 与验收脚本 |
| 程源 | 后端、数据 | 预处理、检索、Prompt、接口 |
下一步:先把 50 篇攻略的字段抽检做完(这是效果的天花板),再调 Prompt 的输出结构稳定性,最后做流式与降级的前端联调。
浙公网安备 33010602011771号