Day 13:行业分析 API Demo

学习目标

昨天你设计了后端的结构框架。今天要把这个框架跑通,做一个完整的、可演示的行业分析 API Demo。

这个 Demo 不只是一个技术验证。它要模拟一个真实的产品场景:用户输入一个行业名称,系统自动完成需求解析、Prompt 模板选择、模型调用、结构化输出、结果保存、报告生成,最终返回一份结构化的行业分析结果和可选的 Markdown 报告。

这是 Week 2 所有学习内容的综合实战。你要用到 Day 8 的 LLM Client、Day 9 的结构化输出、Day 10 的 Function Calling、Day 11 的 Prompt 模板、Day 12 的后端架构。把这些能力串起来,形成一个完整的调用链路。

完成今天的学习后,你应该拥有一个可以给别人演示的 AI 行业分析服务——输入行业名称,输出分析结果。这听起来简单,但把所有环节串通、处理各种异常情况、保证输出质量,需要综合运用你这一周学到的所有技能。

核心概念

一、输入行业名称

行业分析的第一步是接收用户输入。看似简单,但输入的规范化处理决定了后续流程的稳定性。

用户输入的行业名称可能千奇百怪:有人输入”半导体”,有人输入”芯片行业”,有人输入”IC 制造”,有人输入”semiconductor”。这些名称指向同一个行业,但模型可能把它们当作不同的行业来分析。

输入规范化的策略:

同义词映射。维护一个行业名称的映射表——“芯片行业”映射到”半导体”,“IC 制造”映射到”半导体”。在调用模型之前先做一次映射。这个映射表可以是一个简单的字典,也可以调用模型来判断两个名称是否指向同一行业。

输入校验。检查输入是否为空、是否过短(少于 2 个字可能不是有效的行业名称)、是否过长(超过 50 个字可能包含多余信息)。校验不通过时直接返回错误,不浪费模型调用。

输入清洗。去除多余的空白字符、特殊符号。用户输入” 半导体行业 “应该被清洗为”半导体”。

意图识别。用户可能不是在输入行业名称,而是在描述一个问题或需求。比如输入”我想了解制造业的 AI 机会”。这种情况下需要先提取关键信息(行业名称是”制造业”),再进行分析。

这些预处理步骤虽然不是 AI 的核心能力,但它们决定了系统的健壮性。一个不做输入规范化的系统,用户输入稍微不同就会得到不一致的结果。

二、任务解析

任务解析是把用户的输入转化为一组具体的分析任务。

用户说”分析半导体行业”,系统需要理解这个请求包含哪些分析维度。一个好的任务解析应该把一个模糊的请求拆解为具体的子任务:

行业概况分析。半导体行业的定义、范围、主要细分领域。

市场规模分析。全球和国内市场规模、增长趋势、预测数据。

竞争格局分析。主要玩家、市场份额、竞争壁垒。

技术趋势分析。技术发展方向、关键技术节点、创新机会。

AI 应用机会分析。半导体行业中哪些环节适合 AI 赋能、具体的 AI 场景。

风险分析。行业面临的主要风险、不确定性因素。

任务解析可以由 Prompt 来驱动。设计一个”任务解析 Prompt”,输入用户的原始请求,输出一个结构化的任务列表。每个任务包含任务类型、任务描述、优先级、依赖关系。

但任务解析不一定要单独调用模型。如果你的业务场景相对固定(行业分析的维度是确定的),可以直接在 Prompt 中硬编码分析维度,省去任务解析这一步。任务解析更适合需求灵活多变的场景。

对于今天的 Demo 来说,可以先用固定维度的分析——行业概况、市场数据、竞争格局、AI 机会、风险评估。这些维度对大多数行业都适用。后续可以根据用户反馈增加动态维度选择。

三、Prompt 模板选择

有了任务列表后,下一步是为每个任务选择合适的 Prompt 模板。

模板选择的逻辑:

根据任务类型匹配模板分类。分析类任务从分析类模板中选择,评估类任务从评估类模板中选择。

根据分析深度匹配模板变体。概览级别选择 overview 变体,深入级别选择 deep 变体。

根据输出需求匹配模板格式。需要 JSON 输出选择 JSON 格式模板,需要 Markdown 输出选择 Markdown 格式模板。

在今天的 Demo 中,模板选择相对简单——固定使用”行业分析标准版”模板。但在一个成熟的系统中,模板选择可以更智能:

根据行业特征动态调整模板。新兴行业的分析侧重”机会和前景”,成熟行业的分析侧重”竞争和效率”。

根据用户角色调整模板深度。高管看概览版,技术人员看详细版。

根据历史数据调整模板。如果发现某个模板对某类行业的输出质量特别好,优先使用这个模板。

四、模型调用

模板选好后,填充参数,通过 LLM Client 调用模型。

这个环节在 Day 8 已经详细讲过。今天的关键是模型调用的编排——一个行业分析可能需要多次模型调用:

第一次调用:生成行业概览和市场规模。使用行业分析 Prompt 的第一部分。

第二次调用:生成竞争格局和技术趋势。使用行业分析 Prompt 的第二部分。

第三次调用:生成 AI 机会分析和风险评估。基于前两次的结果,生成针对性的 AI 应用建议。

为什么要分多次调用而不是一次搞定?因为一次输出所有内容的 Prompt 太长了,模型容易遗漏某些维度。分步调用可以确保每个维度都得到充分的关注。而且分步调用的中间结果可以被校验——如果市场规模分析不合格,可以单独重试这一步,不需要全部重来。

但多次调用也意味着更高的成本和更长的总耗时。一个折中方案是:先做一次完整调用,如果输出质量合格(通过结构化输出校验),就直接使用。如果发现某些维度缺失或质量不够,再针对这些维度做补充调用。

五、结构化输出

模型返回的结果需要通过结构化输出校验。

行业分析结果的数据结构设计:

顶层字段。industry_name(行业名称)、analysis_date(分析日期)、overall_assessment(整体评价,简短文字)。

market_analysis 子对象。market_size(市场规模,亿元)、growth_rate(增长率,百分比)、trend(趋势描述)、forecast(未来 3-5 年预测)。

competition_analysis 子对象。key_players(主要企业列表,每个包含名称、市场份额、优势)、barriers(进入壁垒列表)、competition_level(竞争激烈程度,枚举:低/中/高)。

ai_opportunities 数组。每个元素是一个 AI 机会对象,包含 opportunity_name(机会名称)、target_process(目标流程)、ai_type(AI 类型:Copilot/Agent/自动化)、potential_impact(预期影响)、implementation_difficulty(实施难度:低/中/高)。

risk_factors 数组。每个元素是一个风险因素,包含 risk_description(风险描述)、severity(严重程度:低/中/高)、mitigation(缓解措施)。

所有字段的约束要合理:市场规模的 growth_rate 在 -100 到 1000 之间,数组字段有最小和最大长度限制,枚举字段限定在预定义的选项内。

六、结果保存

分析结果需要持久化存储,方便后续查询、对比和引用。

保存的数据包括:

分析请求信息。谁发起的请求、什么时间发起、输入参数是什么。

分析结果。模型输出的完整 JSON 数据,以及解析后的结构化数据。

元信息。使用的模型、Prompt 版本、Token 消耗、总耗时、重试次数、分析质量评分。

保存的策略是”全量保存”——不丢弃任何信息。即使分析结果校验失败(格式不完全合规),也保存原始输出。因为你永远不知道什么时候需要回来看这些数据。

保存后需要生成一个唯一标识(analysis_id),后续查询和引用都通过这个 ID。

七、Markdown 报告生成

结构化的 JSON 数据对程序友好,对人不够友好。大多数用户(特别是非技术背景的决策者)更希望看到一份排版良好的报告。

Markdown 报告的生成有两种方式:

基于模板的生成。设计一个 Markdown 模板,把结构化数据填入对应位置。这种方式速度快、格式可控,但灵活性有限——模板写死了报告的结构和样式。

基于模型的生成。把结构化数据传给模型,让模型生成一份流畅的报告文本。这种方式生成的报告更自然、更有可读性,但消耗额外的 Token,且格式不可完全控制。

两种方式可以结合使用:先用模板生成骨架(章节标题、数据表格),再用模型润色文字描述。

一份行业分析报告的 Markdown 结构:

标题:XX 行业分析报告。副标题包含分析日期和版本信息。

摘要:200 字以内的核心发现概述。

行业概况:行业定义、范围、发展阶段。

市场分析:市场规模、增长率、趋势图表(用文字描述代替)。

竞争格局:主要企业、市场份额、竞争态势。

AI 应用机会:按优先级排列的 AI 场景列表,每个场景包含具体描述和预期效果。

风险与挑战:主要风险因素和应对建议。

结论与建议:总结性结论和行动建议。

八、API 文档

API 文档是让别人能使用你的服务的前提。

FastAPI 自动生成的文档是一个好的起点,但它只包含接口的技术规格。一份完整的 API 文档还应该包含:

概述。这个服务是什么、解决什么问题、面向什么用户。

快速开始。怎么启动服务、怎么调用第一个接口。

接口详细说明。每个接口的 URL、方法、参数、返回值、错误码、示例请求和响应。

数据模型说明。请求和响应中使用的所有数据结构的定义。

使用限制。速率限制、输入约束、输出长度限制。

常见问题。常见错误的解决方法。

API 文档不仅是给别人看的,也是给你自己看的。三个月后你回来改代码,文档能帮你快速回忆起接口设计。

概念关系图

用户输入 "半导体"
        |
        v
+------------------+     +------------------+
| 输入规范化       |---->| 任务解析         |
| - 同义词映射     |     | - 概况分析       |
| - 格式校验       |     | - 市场分析       |
| - 意图识别       |     | - 竞争分析       |
+------------------+     | - AI 机会        |
                         | - 风险评估       |
                         +--------+---------+
                                  |
                                  v
                    +--------------------------+
                    |     Prompt 模板选择       |
                    | analyze_industry_standard |
                    +------------+-------------+
                                 |
                                 v
                    +--------------------------+
                    |     模型调用(LLMClient) |
                    |  Prompt + 参数 -> 模型    |
                    +------------+-------------+
                                 |
                                 v
                    +--------------------------+
                    |     结构化输出校验        |
                    | Pydantic 校验 + 格式修复  |
                    +------------+-------------+
                                 |
                     合规? --Yes--+--No--> 重试 (带反馈)
                       |                         |
                       v                         v
              +----------------+       +----------------+
              | 结果保存       |       | 降级处理       |
              | - JSON 原文    |       | - 格式修复     |
              | - 解析后数据   |       | - 默认值填充   |
              | - 元信息       |       +----------------+
              +-------+--------+
                      |
              +-------+--------+
              | Markdown 报告  |
              | 模板填充 +     |
              | 模型润色       |
              +-------+--------+
                      |
                      v
              +------------------+
              | API 响应返回     |
              | - JSON 结果     |
              | - Markdown 报告  |
              | - analysis_id   |
              +------------------+

实战分析

整体流程设计

行业分析 API 的完整流程是一个从输入到输出的流水线。每一环的输出是下一环的输入,任何一环出错都会影响最终结果。

流水线的关键控制点:

输入校验关卡。在任务解析之前拦截无效输入。空输入、非行业名称的输入、过长的输入直接返回错误,不浪费后续环节的资源。

质量检查关卡。在模型输出后、保存结果之前做质量检查。检查结构化输出的完整性(所有必填字段是否存在)、合理性(市场规模是否为正数、增长率是否在合理范围)。检查不通过则触发重试。

超时保护关卡。整个分析流程设定总超时时间(比如 120 秒)。如果某个环节耗时过长,直接返回已完成的部分结果,避免用户无限等待。

降级关卡。当重试次数耗尽或超时后,不要返回空结果,而是返回已有的最佳结果——可能只完成了部分分析维度,但比什么都不返回要好。

五个行业的测试策略

指南要求测试 5 个行业。选择测试行业时要考虑多样性:

热门行业。比如”人工智能”或”新能源”。这些行业信息丰富,模型训练数据中有很多相关信息,应该能输出高质量的分析。

传统行业。比如”制造业”或”建筑业”。这些行业的数据相对稳定,分析结果应该偏重效率和成本优化。

小众行业。比如”殡葬服务”或”工业气体”。测试系统对信息稀少的行业的处理能力。模型可能对这些行业了解有限,看看它怎么应对。

新兴行业。比如”低空经济”或”具身智能”。测试系统对快速变化的行业的适应能力。

国际行业。比如”全球半导体”或”跨境电商”。测试系统对跨国维度的分析能力。

每个行业的测试要记录:输入(行业名称和参数)、模型输出质量(格式合规、内容准确、信息完整)、耗时、Token 消耗、重试次数。这些数据形成一份测试报告,反映系统的整体表现。

错误输入处理

除了正常的行业输入,还要测试错误输入的处理:

空输入。用户没有输入任何内容就提交。

无效输入。用户输入”的”或”12345”这种明显不是行业名称的内容。

超长输入。用户输入了 500 个字的描述。

特殊字符输入。用户输入包含 HTML 标签或 SQL 注入字符串。

系统对每种错误输入都应该返回友好的错误信息,而不是抛出异常或返回 500 错误。

当日产物说明

行业分析 API Demo

一个可以运行的完整 API 服务。包含:行业分析接口(POST /api/v1/analyze/industry)、报告生成接口(POST /api/v1/reports/generate)、结果查询接口(GET /api/v1/analyses/{id})、健康检查接口(GET /health)。

所有接口都能正常工作——不是只有”happy path”能用,常见的错误场景也能正确处理。

5 个行业测试结果

一份测试报告,包含 5 个不同行业的完整测试结果。每个行业的测试记录包括:

输入信息。行业名称、分析参数。

输出质量评估。格式合规(是否是合法 JSON)、字段完整性(必填字段是否齐全)、内容准确性(信息是否合理)、信息丰富度(每个维度的分析是否充实)。

性能数据。总耗时、模型调用次数、Token 消耗。

问题记录。输出中发现的任何问题——遗漏的维度、不够准确的数据、格式异常。

Markdown 报告模板

一个标准的 Markdown 报告模板文件。包含报告的完整结构定义:章节标题、每个章节应该包含什么内容、数据展示的格式规范、样式约定(标题层级、列表格式、表格格式)。

模板应该足够通用,能适用于不同行业的分析结果。

补充:从 Demo 到产品的差距清单

今天的 Demo 跑通了核心链路,但如果要把它变成一个真正的产品,还有哪些工作要做?这里列一份完整的差距清单。

数据可信度提升。当前的分析完全依赖模型的自身知识,市场数据(规模、增长率)可能不准确。产品级系统需要接入真实数据源——行业报告数据库、统计局公开数据、第三方市场研究机构的数据。通过 RAG 把这些真实数据注入分析过程,让结论有据可查。

多轮交互支持。当前的分析是一次性的——用户输入行业名称,系统返回结果。产品级系统应该支持多轮交互——用户看了分析结果后可以追问”竞争格局能再详细一点吗”或”AI 机会中哪个最适合优先落地”。系统需要记住之前的分析结果,在对话中做增量分析。

个性化适配。不同的用户角色关注不同的分析维度。CEO 关心市场机会和投资回报,CTO 关心技术可行性和实施路径,COO 关心运营效率提升。产品级系统应该根据用户角色自动调整分析的侧重点和报告的呈现方式。

持续更新机制。行业信息在不断变化。今天的分析三个月后可能就过时了。产品级系统应该有定期更新的机制——自动检测行业新闻、定期刷新市场数据、对比历史分析结果的变化趋势。

多行业对比。用户经常需要对比多个行业——“半导体和新能源哪个 AI 机会更大”。产品级系统应该支持横向对比,把多个行业的分析结果放在同一维度上做比较。

报告导出。用户不只是在线看报告,还需要导出为 PDF、Word 或 PPT 格式,方便在会议中分享。这需要增加格式转换和排版优化的功能。

用户管理和权限。产品级系统需要用户认证、权限管理、用量计费。不同的用户有不同的调用配额和数据访问权限。

把这些差距列出来不是为了让你焦虑,而是给你一个清晰的路线图。今天的 Demo 验证了核心技术的可行性,后续的每一项改进都是在这个基础上的增量开发。

补充:Demo 演示的关键技巧

当你拿着这个 Demo 去给客户或团队演示时,有几个技巧能让演示效果更好。

准备三到五个确定能跑通的案例。不要现场随机输入行业名称——万一模型那天状态不好输出质量差,演示就翻车了。提前测试好几个行业,确保这些案例能稳定输出高质量结果。演示时可以用这些案例,但要让观众觉得你是随机选的。

准备一个失败案例的应对话术。即使准备好了案例,也可能出意外。准备一段话术:“这次输出格式有些偏差,这正是我们在工程化阶段要解决的问题——通过结构化输出校验和自动重试来保证质量。“把意外变成展示你工程能力的机会。

展示完整的调用链路。不要只展示最终的输出结果。打开日志,让观众看到从请求发起到结果返回的全过程——调用了哪个 Prompt 模板、用了多少 Token、耗时多少。这比一个漂亮的输出结果更能体现你的工程水平。

提前准备好对比数据。如果有条件,展示优化前后的对比——同一个行业,优化前的 Prompt 输出什么,优化后输出什么。量化的改进比定性的描述更有说服力。

控制演示节奏。一次演示控制在 10 分钟以内。展示三个行业(一个热门、一个传统、一个特殊),每个行业展示输入、输出和报告,最后展示一下日志和文档。不要试图展示所有功能,重点突出”输入行业名称,输出结构化分析”这个核心价值。

常见误区与避坑

误区一:不做输入规范化直接丢给模型

用户输入什么就原封不动地传给模型。用户输入”芯片”,模型可能分析的是”芯片零食行业”而不是”半导体芯片行业”。输入规范化是必须的,至少要做基本的清洗和校验。

误区二:一次调用试图搞定所有分析维度

在一个 Prompt 里要求模型分析行业概况、市场规模、竞争格局、技术趋势、AI 机会、风险,输出 20 个字段。模型面对这么复杂的要求很容易遗漏或敷衍。如果输出质量不稳定,考虑拆成多次调用。

误区三:测试只挑简单的行业

只测”人工智能”、“新能源”这些热门行业,不测冷门行业。冷门行业才是考验系统能力的地方——模型训练数据有限,输出质量可能下降。如果你的系统只在热门行业上能用,那它就不是一个可靠的产品。

误区四:报告生成后不校验

生成的 Markdown 报告可能有格式问题——表格没有对齐、标题层级混乱、数据前后矛盾。报告生成后应该做基本的格式校验和一致性检查。

误区五:不记录失败案例

只记录成功的测试结果,失败的案例被丢弃。失败案例才是最有价值的数据——它们告诉你系统的边界在哪里、哪些场景需要特殊处理。建议把所有测试结果(包括失败的)都保留下来。

延伸思考

今天的行业分析 Demo 是一个”最小可行产品”。它能工作,但离”产品”还有距离。距离在哪里?

用户界面。现在只有 API,普通用户没法用。需要一个前端页面,让用户能输入行业名称、查看分析结果、下载报告。这在 Week 8 的综合项目中会实现。

数据可信度。模型生成的市场数据(市场规模、增长率)不一定准确。在实际产品中,需要接入真实的数据源(行业报告、统计局数据),用 RAG 来增强数据的可信度。这在 Week 3 的 RAG 系统中会学习。

个性化。不同用户关注不同的维度。高管关心市场机会和 ROI,技术人员关心技术可行性,财务人员关心成本和回报周期。系统能根据用户角色调整分析重点。

持续更新。行业信息在不断变化。今天的分析结果三个月后可能就过时了。成熟的系统应该有定期更新的机制。

但从学习路径的角度看,今天的 Demo 已经足够了。它让你体验了从输入到输出的完整闭环,验证了你这一周学到的所有技能。Week 2 的目标是”掌握大模型工程调用方式”,这个 Demo 证明了你确实掌握了。

自测问题

  1. 行业名称的输入规范化包括哪些步骤?为什么不能跳过这些步骤?
  2. 任务解析的作用是什么?什么情况下可以省略任务解析?
  3. 行业分析的 Prompt 模板选择逻辑是什么?固定模板和动态模板选择各有什么优缺点?
  4. 为什么建议把一个完整的行业分析拆成多次模型调用?拆分和一次调用的权衡是什么?
  5. 结构化输出校验失败后,重试策略应该怎么设计?为什么不建议无限重试?
  6. 结果保存时为什么要”全量保存”?只保存解析后的结构化数据有什么风险?
  7. Markdown 报告生成的两种方式(模板填充和模型生成)各有什么优缺点?
  8. 测试行业分析 Demo 时,为什么要选择不同类型的行业(热门、传统、小众、新兴)?
  9. 如果模型对某个小众行业的分析结果质量很差(信息很少、数据不准),你应该怎么改进?
  10. 这个行业分析 Demo 和一个”真正的产品”之间还有哪些差距?

关键词

  • 输入规范化:对用户输入进行清洗、校验、同义词映射等预处理
  • 任务解析:将用户请求拆解为具体的分析子任务列表
  • Prompt 模板选择:根据任务类型和参数匹配最合适的 Prompt 模板
  • 模型调用编排:规划多次模型调用的顺序、参数传递和结果整合
  • 结构化输出校验:验证模型输出的 JSON 是否符合预定义的 Schema
  • 结果持久化:将分析结果和元信息保存到数据库,方便查询和追溯
  • Markdown 报告:将结构化数据转化为人类可读的排版良好的文本报告
  • 降级处理:当重试耗尽或超时时返回已有的最佳部分结果
  • API 文档:描述接口使用方法的完整文档,包含示例和错误说明
  • 测试多样性:选择不同类型的行业进行测试,验证系统的适应能力