ai
  • outline
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 1.面试问题
  • 2.参考答案
    • 1. 结构化输出的定义与常见形式
    • 1.1 数据格式
    • 1.2 结构化文本
    • 1.3 领域特定格式
    • 2. 为什么需要结构化输出?
      • 2.1 问题对比示例
      • 2.2 实际应用价值
    • 3. 实现结构化输出的核心技术
      • 3.1 提示工程(Prompt Engineering)
      • 3.2 JSON Schema约束
      • 3.3 工具辅助实现
    • 4. 处理不规范输出的策略
      • 4.1 后处理流程
      • 4.2 错误处理策略
    • 5. 实际应用案例
      • 5.1 电商产品信息提取
      • 5.2 客户服务工单分类
      • 5.3 数据分析报告生成
    • 6. 性能优化策略
      • 6.1 缓存机制
      • 6.2 批量处理
      • 6.3 异步处理
    • 7. 面试技巧提示

1.面试问题 #

请您详细阐述大模型的结构化输出(Structured Output)指的是什么?为什么在实际应用中需要结构化输出?并介绍实现结构化输出的核心技术和处理不规范输出的策略。

2.参考答案 #

1. 结构化输出的定义与常见形式 #

结构化输出是指让大型语言模型(LLM)生成符合特定格式(如JSON、XML、表格、SQL语句等)的数据,而非自由文本。这种输出能够被计算机程序直接解析和处理,例如存入数据库、生成API接口参数或驱动自动化流程。

常见形式包括:

1.1 数据格式 #

  • JSON:最常用的结构化格式,易于解析和传输
  • YAML:人类可读的配置格式
  • CSV:表格数据格式
  • XML:标记语言格式

1.2 结构化文本 #

  • Markdown表格:用于文档和报告
  • 键值对:简单的结构化数据
  • 固定字段段落:预定义格式的文本块

1.3 领域特定格式 #

  • SQL语句:用于数据库查询
  • HTML:用于网页生成
  • LaTeX:用于学术公式和文档

2. 为什么需要结构化输出? #

在许多实际应用场景中,模型生成的自由文本难以被程序直接利用,导致效率低下且易出错。结构化输出解决了这一痛点,使得AI系统能够无缝集成到现有业务流程中。

2.1 问题对比示例 #

非结构化输出的问题: 假设用户希望获取北京三个景点的介绍。

传统自由文本输出:

故宫:明清皇家宫殿,世界文化遗产。颐和园:古典园林,以昆明湖和万寿山为核心。长城:古代军事防御工程,象征中国文化。

存在的问题:

  • 程序需要手动从文本中提取景点名称和介绍
  • 效率低且易出错
  • 难以进行后续的数据处理和分析

结构化输出的优势:

[
  {
    "name": "故宫",
    "description": "明清皇家宫殿,世界文化遗产"
  },
  {
    "name": "颐和园", 
    "description": "古典园林,以昆明湖和万寿山为核心"
  },
  {
    "name": "长城",
    "description": "古代军事防御工程,象征中国文化"
  }
]

优势体现:

  • 程序可以直接使用JSON解析库读取数据
  • 无需人工处理,大大提高了自动化程度
  • 便于后续的数据存储、查询和分析

2.2 实际应用价值 #

API集成:

  • 直接生成API请求参数
  • 简化微服务间的数据交换
  • 提高系统集成效率

数据库操作:

  • 生成标准化的数据库记录
  • 支持批量数据导入
  • 便于数据验证和约束

自动化流程:

  • 驱动工作流引擎
  • 支持条件分支和循环
  • 提高业务流程自动化程度

3. 实现结构化输出的核心技术 #

3.1 提示工程(Prompt Engineering) #

核心思想:在输入提示中明确要求输出格式,并提供清晰的示例,帮助模型准确理解需求。

明确格式示例:

# 提示模板示例
prompt_template = """
请按以下JSON格式返回用户信息:
{
  "user_id": "用户ID",
  "username": "用户名", 
  "email": "邮箱地址"
}

输入: 用户ID是1000,用户名为mianshiya,邮箱是mianshiya@example.com
"""

分隔符辅助:

# 使用分隔符明确区分输入和格式要求
prompt_with_delimiter = """
请分析这段评论的情感,并以JSON返回结果,包含情感(sentiment)和理由(reason):

评论:```这款手机续航太差了,充电速度也慢,体验很不好。

输出格式: {"sentiment": "负面", "reason": "续航差,充电慢"} """


**Few-shot学习**:
```python
# 提供多个示例帮助模型学习格式
few_shot_prompt = """
示例1:
输入: 今天天气很好
输出: {"weather": "晴天", "mood": "积极"}

示例2:
输入: 这个产品太贵了
输出: {"price": "昂贵", "mood": "消极"}

现在请分析: 这个服务很专业
输出:
"""

3.2 JSON Schema约束 #

核心思想:通过定义严格的JSON Schema来约束模型输出格式,减少格式错误。

Schema定义示例:

{
  "type": "object",
  "properties": {
    "name": {
      "type": "string",
      "description": "用户姓名"
    },
    "age": {
      "type": "number",
      "minimum": 0,
      "maximum": 150
    },
    "is_student": {
      "type": "boolean"
    },
    "hobbies": {
      "type": "array",
      "items": {
        "type": "string"
      }
    }
  },
  "required": ["name", "age"],
  "additionalProperties": false
}

OpenAI API使用示例:

import openai

response = openai.ChatCompletion.create(
    model="gpt-3.5-turbo",
    messages=[
        {"role": "user", "content": "请生成一个用户信息"}
    ],
    response_format={
        "type": "json_schema",
        "json_schema": {
            "name": "user_info",
            "schema": schema_definition
        }
    }
)

3.3 工具辅助实现 #

LangChain结构化输出解析器:

from langchain.output_parsers import PydanticOutputParser
from pydantic import BaseModel, Field

# 定义输出模型
class UserInfo(BaseModel):
    name: str = Field(description="用户姓名")
    age: int = Field(description="用户年龄")
    email: str = Field(description="用户邮箱")

# 创建解析器
parser = PydanticOutputParser(pydantic_object=UserInfo)

# 在提示中使用
prompt = f"""
请根据用户输入生成用户信息。
{parser.get_format_instructions()}

用户输入: 张三,25岁,zhangsan@example.com
"""

# 解析输出
result = parser.parse(llm_output)

自定义解析器:

class CustomOutputParser:
    def __init__(self, schema):
        self.schema = schema

    def parse(self, text):
        # 提取JSON部分
        import re
        json_match = re.search(r'\{.*\}', text, re.DOTALL)
        if json_match:
            json_str = json_match.group()
            return json.loads(json_str)
        else:
            raise ValueError("未找到有效的JSON格式")

4. 处理不规范输出的策略 #

即使提示明确,模型仍可能生成格式错误(如引号缺失、逗号遗漏)的输出。此时,需要通过代码进行后处理修复。

4.1 后处理流程 #

步骤1:提取候选文本

import re
import json

def extract_json_candidates(text):
    """提取文本中可能的JSON内容"""
    # 使用正则表达式匹配JSON格式
    json_pattern = r'\{[^{}]*(?:\{[^{}]*\}[^{}]*)*\}'
    candidates = re.findall(json_pattern, text, re.DOTALL)
    return candidates

步骤2:格式验证与修复

def validate_and_fix_json(json_str):
    """验证并修复JSON格式"""
    try:
        # 尝试直接解析
        return json.loads(json_str)
    except json.JSONDecodeError as e:
        # 尝试修复常见错误
        fixed_json = fix_common_errors(json_str)
        try:
            return json.loads(fixed_json)
        except json.JSONDecodeError:
            # 如果修复失败,返回默认值
            return get_default_response()

def fix_common_errors(json_str):
    """修复常见的JSON格式错误"""
    # 修复缺失的引号
    json_str = re.sub(r'(\w+):', r'"\1":', json_str)
    # 修复缺失的逗号
    json_str = re.sub(r'"\s*\n\s*"', '",\n"', json_str)
    # 修复缺失的括号
    if json_str.count('{') > json_str.count('}'):
        json_str += '}'
    return json_str

步骤3:默认补全

def complete_missing_fields(data, schema):
    """补全缺失的必填字段"""
    for field in schema.get('required', []):
        if field not in data:
            data[field] = get_default_value(field, schema)
    return data

def get_default_value(field, schema):
    """根据字段类型返回默认值"""
    field_schema = schema['properties'].get(field, {})
    field_type = field_schema.get('type', 'string')

    defaults = {
        'string': '',
        'number': 0,
        'boolean': False,
        'array': [],
        'object': {}
    }
    return defaults.get(field_type, None)

4.2 错误处理策略 #

重试机制:

def generate_with_retry(prompt, max_retries=3):
    """带重试的结构化输出生成"""
    for attempt in range(max_retries):
        try:
            response = llm.generate(prompt)
            parsed = parser.parse(response)
            return parsed
        except Exception as e:
            if attempt == max_retries - 1:
                # 最后一次尝试失败,返回默认值
                return get_default_response()
            else:
                # 调整提示后重试
                prompt = adjust_prompt_for_retry(prompt, e)
                continue

人工干预机制:

def handle_parsing_failure(response, error):
    """处理解析失败的情况"""
    # 记录错误日志
    logger.error(f"JSON解析失败: {error}, 原始输出: {response}")

    # 发送到人工审核队列
    send_to_human_review(response, error)

    # 返回默认响应
    return get_default_response()

5. 实际应用案例 #

5.1 电商产品信息提取 #

# 应用场景:从产品描述中提取结构化信息
product_schema = {
    "type": "object",
    "properties": {
        "name": {"type": "string"},
        "price": {"type": "number"},
        "category": {"type": "string"},
        "features": {"type": "array", "items": {"type": "string"}},
        "rating": {"type": "number", "minimum": 0, "maximum": 5}
    },
    "required": ["name", "price", "category"]
}

# 使用示例
product_description = "iPhone 15 Pro,售价9999元,属于智能手机类别,具有A17芯片、48MP摄像头等特性,用户评分4.8分"
structured_output = extract_product_info(product_description, product_schema)

5.2 客户服务工单分类 #

# 应用场景:自动分类客户服务工单
ticket_schema = {
    "type": "object", 
    "properties": {
        "category": {"type": "string", "enum": ["技术问题", "账单问题", "账户问题", "其他"]},
        "priority": {"type": "string", "enum": ["高", "中", "低"]},
        "summary": {"type": "string"},
        "tags": {"type": "array", "items": {"type": "string"}}
    },
    "required": ["category", "priority", "summary"]
}

5.3 数据分析报告生成 #

# 应用场景:生成结构化的数据分析报告
report_schema = {
    "type": "object",
    "properties": {
        "summary": {"type": "string"},
        "key_metrics": {
            "type": "object",
            "properties": {
                "total_users": {"type": "number"},
                "conversion_rate": {"type": "number"},
                "revenue": {"type": "number"}
            }
        },
        "recommendations": {"type": "array", "items": {"type": "string"}}
    }
}

6. 性能优化策略 #

6.1 缓存机制 #

# 缓存常见查询的结构化输出
from functools import lru_cache

@lru_cache(maxsize=1000)
def get_cached_structured_output(query, schema_hash):
    """缓存结构化输出结果"""
    return generate_structured_output(query, schema)

6.2 批量处理 #

# 批量处理多个查询
def batch_structured_output(queries, schema):
    """批量生成结构化输出"""
    batch_prompt = create_batch_prompt(queries, schema)
    batch_response = llm.generate(batch_prompt)
    return parse_batch_response(batch_response)

6.3 异步处理 #

import asyncio

async def async_structured_output(query, schema):
    """异步生成结构化输出"""
    response = await llm.agenerate(query)
    return parser.parse(response)

7. 面试技巧提示 #

在回答此类问题时,建议:

  1. 系统性回答:按照定义、必要性、技术实现、错误处理的逻辑组织答案
  2. 具体示例:提供实际的代码示例和应用场景
  3. 技术深度:展现对提示工程、Schema设计、错误处理的深入理解
  4. 实际经验:结合具体项目经验说明技术选型
  5. 问题导向:重点说明如何解决实际应用中的结构化输出问题

这样的回答既展现了技术广度,又体现了对实际应用场景的深入理解,能够给面试官留下专业且实用的印象。

访问验证

请输入访问令牌

Token不正确,请重新输入