Prompt工程 入门 输出格式控制 结构化输出 JSON模式 Prompt工程

输出格式控制:让LLM输出精准的结构化内容

AIEng Hub
阅读约 15 分钟

输出格式控制:让LLM输出精准的结构化内容

LLM 的原生输出是自然语言文本,但在生产环境中,我们往往需要特定格式的输出——JSON 用于程序消费、Markdown 用于文档渲染、表格用于对比展示。格式控制是 Prompt 工程中最基础也最重要的技能之一。

一、为什么格式控制如此重要?

1.1 无格式的代价

无格式控制时的输出(不可靠):

"分析:这款产品很不错...
评分:我给它打8分...
价格方面呢...哦对,价格是...
"

有格式控制时的输出(可靠):

{
  "analysis": "产品设计精良,性能出色",
  "rating": 8,
  "price_tier": "中高端"
}

1.2 格式控制的收益

维度无控制有控制提升
解析成功率40-60%95-99%2x
下游处理需NLP解析直接消费10x
错误率20-30%1-3%10x
调试成本5x

二、基础格式控制技术

2.1 JSON 格式控制

# 方法1:示例驱动
json_prompt_1 = """
分析以下文本,以JSON格式返回:

文本:{text}

输出格式:
{
  "sentiment": "正面/负面/中性",
  "key_points": ["要点1", "要点2"],
  "summary": "一句话总结(20字以内)"
}
"""

# 方法2:Schema驱动
json_prompt_2 = """
{text}

从以上文本中提取信息,严格按照以下JSON Schema输出:

{
  "type": "object",
  "properties": {
    "title": {"type": "string", "description": "标题"},
    "author": {"type": "string"},
    "date": {"type": "string", "format": "date"},
    "tags": {"type": "array", "items": {"type": "string"}},
    "word_count": {"type": "integer"},
    "summary": {"type": "string", "maxLength": 100}
  },
  "required": ["title", "author", "date"]
}
"""

# 方法3:使用 Structured Output API(OpenAI/Anthropic)
from pydantic import BaseModel
from openai import OpenAI

class Analysis(BaseModel):
    sentiment: str
    score: float
    keywords: list[str]
    summary: str

client = OpenAI()
response = client.chat.completions.create(
    model="gpt-4o-mini",
    messages=[{"role": "user", "content": text}],
    response_format={"type": "json_object"}
)

2.2 Markdown 格式控制

# 表格输出
table_prompt = """
比较Python和JavaScript的特性,输出Markdown格式表格:

| 特性 | Python | JavaScript |
|------|--------|------------|
| 类型系统 | [填写] | [填写] |
| 执行方式 | [填写] | [填写] |
| 主要用途 | [填写] | [填写] |
| 学习难度 | [填写] | [填写] |

请填写上述表格中的空白处。
"""

# 结构化Markdown
markdown_prompt = """
请以Markdown格式生成一份API文档:

## {api_name}

### 接口说明
{描述}

### 请求方法
{method}

### 请求参数
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| ... | ... | ... | ... |

### 响应示例
```json
{
  "code": 0,
  "data": {}
}

错误码

错误码说明
"""

## 三、高级输出控制

### 3.1 约束条件

```python
# 数值约束
constraint_prompt_1 = """
只输出一个数字(0-100之间的整数),表示评分:
产品:{product_name}
评分:
"""

# 枚举约束
constraint_prompt_2 = """
分类结果只能是以下之一:
[A] 技术问题
[B] 账单问题
[C] 产品咨询
[D] 投诉建议

用户问题:{question}
分类:[只输出字母]
"""

# 长度约束
constraint_prompt_3 = """
用不超过50个字总结以下内容:

{text}

字数统计:___字
"""

3.2 链式格式控制

# 多轮格式控制
chain_prompt = """
第1步:提取信息
输出JSON:
{
  "entities": [],
  "relations": []
}

第2步:生成摘要
基于第1步的结果,生成一段100字以内的摘要。

第3步:翻译
将第2步的摘要翻译成英文。

请按顺序执行以上三步,每一步的执行结果都必须输出,
不要跳过任何步骤。
"""

四、格式控制实战

4.1 客户评论分析

review_prompt = """
分析以下客户评论,输出结构化结果:

评论:{review}

{
  "sentiment": "positive" | "negative" | "neutral",
  "rating": 1-5分,
  "aspects": {
    "product_quality": "good" | "average" | "poor" | "not_mentioned",
    "customer_service": "good" | "average" | "poor" | "not_mentioned",
    "price_value": "good" | "expensive" | "fair" | "not_mentioned",
    "delivery": "fast" | "slow" | "not_mentioned"
  },
  "key_quotes": ["引用原文中最关键的2-3句"],
  "actionable": true | false,
  "action_items": ["需要处理的改进点"]
}

要求:
1. 所有字段都必须填写
2. key_quotes必须引用原文
3. 如果某个aspect未提及,填写"not_mentioned"
"""

4.2 代码生成控制

code_prompt = """
请生成一个Python函数,要求:

功能:{description}

输出格式:
```python
def function_name(params):
    \"\"\"
    文档字符串
    \"\"\"
    # 实现
    return result

# 使用示例
example_result = function_name(...)
print(example_result)

约束:

  • 包含类型注解
  • 包含详细的文档字符串
  • 包含至少一个使用示例
  • 代码必须能直接运行 """

## 五、常见问题与解决方案

### 5.1 格式不一致

| 问题 | 表现 | 原因 | 解决方案 |
|------|------|------|---------|
| JSON 无效 | 缺少逗号、引号不匹配 | 模型对格式不够敏感 | 使用 Structured Output API |
| 字段缺失 | 部分字段没有输出 | 约束不够明确 | 添加 required 列表 |
| 额外内容 | 在JSON前后加了说明文字 | 模型习惯增加解释 | 明确"只输出JSON" |
| 类型错误 | 数字变成了字符串 | Schema 不够严格 | 使用 Pydantic 模型 |

### 5.2 调试技巧

```python
def validate_json_output(response):
    """验证JSON输出并给出反馈"""
    try:
        data = json.loads(response)
        print("✅ JSON有效")
        return data
    except json.JSONDecodeError as e:
        print(f"❌ JSON无效: {e}")
        print(f"   位置: 第{e.lineno}行, 第{e.colno}列")
        print(f"   附近文本: ...{response[max(0, e.pos-20):e.pos+20]}...")
        return None

六、最佳实践 Checklist

  • 提供明确的输出模板/示例
  • 使用 Schema 定义约束(JSON Schema, Pydantic)
  • 指定缺失字段的默认值
  • 添加”只输出指定格式”的硬约束
  • 验证输出格式并反馈修正
  • 考虑使用 Structured Output / Function Calling
  • 对关键输出做格式校验

总结

输出格式控制是 Prompt 从”能用”到”好用”的关键一跃。掌握 JSON Schema、Structured Output、长度/枚举约束等技巧,能让 LLM 输出从”自然语言”变为”机器可消费的数据”。