0Pricing
AI Prompt Engineering · 课时

输出到输入模式

从第 1 步提取结构化数据,并将其注入第 2 步

输出到输入模式 是 CoddyKit 上的免费 AI Prompt Engineering 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 AI Prompt Engineering 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 AI Prompt Engineering 课程共包含 4 节课。

核心挑战:提取与注入

在提示词链中,第 1 步会生成文本。第 2 步需要将其中的特定片段作为输入。难点在于可靠地从第 1 步的输出中准确提取所需字段,并将其干净地注入第 2 步的提示词中。

如果第 1 步返回的是无结构的散文,提取就会很脆弱。解决方案是设计第 1 步的提示词,使其返回结构化输出——通常是 JSON——这样就可以通过程序解析并注入。

面向机器处理设计步骤 1

用于向链提供输入的提示应始终输出结构化数据。请在提示中指定确切的 JSON 模式:

import anthropic
import json

client = anthropic.Anthropic(api_key='YOUR_API_KEY')

step1_prompt = '''
<task>
Analyze the customer review below.
</task>

<review>
The onboarding was confusing and took 3 hours. The core feature works great though.
</review>

<output_format>
Return ONLY a JSON object. No other text.
{
  "sentiment": "positive|negative|mixed",
  "issues": ["string"],
  "positives": ["string"],
  "priority": "high|medium|low"
}
</output_format>
'''

response = client.messages.create(
    model='claude-opus-4-5',
    max_tokens=300,
    messages=[{'role': 'user', 'content': step1_prompt}]
)
print(response.content[0].text)

解析步骤 1 输出

步骤 1 返回 JSON 后,请在 Python 中解析它,并提取步骤 2 所需的字段:

import json

def parse_step1_output(raw_text):
    # Models sometimes wrap JSON in extra text -- strip it
    text = raw_text.strip()
    # Find the first { and last } to extract JSON object
    start = text.find("{")
    end = text.rfind("}")
    if start != -1 and end != -1 and end > start:
        text = text[start:end+1]
    try:
        return json.loads(text)
    except json.JSONDecodeError as e:
        raise ValueError("Step 1 output is not valid JSON: " + str(e))

# Example usage
raw = '{"sentiment": "mixed", "issues": ["confusing onboarding"], "positives": ["core feature"], "priority": "high"}'
parsed = parse_step1_output(raw)
print(parsed['issues'])
print(parsed['priority'])

将提取的字段注入步骤 2

解析后,将特定字段注入步骤 2 的提示模板。请使用 Python f 字符串或模板变量:

def build_step2_prompt(parsed_step1):
    issues = '\n'.join(f'- {issue}' for issue in parsed_step1['issues'])
    priority = parsed_step1['priority']
    sentiment = parsed_step1['sentiment']

    return f'''
<context>
A customer review was analyzed. Overall sentiment: {sentiment}. Priority: {priority}.
</context>

<task>
Write a customer support response addressing these specific issues:
{issues}
Acknowledge the positives before addressing the issues.
</task>

<output_format>
Plain text response, 3 sentences maximum, professional tone.
</output_format>
'''

parsed = {'sentiment': 'mixed', 'issues': ['confusing onboarding'], 'priority': 'high', 'positives': ['core feature']}
print(build_step2_prompt(parsed))

完整的两步骤链

将解析和注入组合成完整的两步骤流水线:

import anthropic, json

client = anthropic.Anthropic(api_key='YOUR_API_KEY')

def call(prompt, max_tokens=500):
    r = client.messages.create(
        model='claude-opus-4-5', max_tokens=max_tokens,
        messages=[{'role': 'user', 'content': prompt}]
    )
    return r.content[0].text

def review_response_chain(review_text):
    # Step 1: Analyze
    step1 = call(f'Analyze this review. Return JSON: {{"sentiment": str, "issues": [str], "priority": str}}\n\nReview: {review_text}')
    parsed = json.loads(step1.strip())

    # Inject into Step 2
    issues_str = ', '.join(parsed['issues'])
    step2_prompt = f'Write a 2-sentence support reply. Issues to address: {issues_str}. Priority: {parsed["priority"]}.'

    # Step 2: Draft response
    reply = call(step2_prompt)
    return reply

print(review_response_chain('Login is broken. App crashes on startup.'))

处理嵌套 JSON 注入

当步骤 1 返回嵌套对象时,仅提取步骤 2 所需的内容,以保持注入提示简洁:

step1_output = {
    'document': {
        'title': 'Q3 Report',
        'sections': [
            {'name': 'Revenue', 'value': '$4.2M', 'change': '+12%'},
            {'name': 'Users', 'value': '85,000', 'change': '+5%'},
            {'name': 'Churn', 'value': '3.2%', 'change': '-0.8%'}
        ]
    },
    'summary': 'Strong revenue quarter with moderate user growth.'
}

# Extract only what Step 2 needs — not the full nested object
def extract_for_step2(data):
    sections = data['document']['sections']
    metrics = '\n'.join(f"{s['name']}: {s['value']} ({s['change']})" for s in sections)
    return {
        'metrics': metrics,
        'summary': data['summary']
    }

step2_input = extract_for_step2(step1_output)
print(step2_input)

避免过度注入

一个常见错误是将步骤 1 的完整输出注入步骤 2。这样会使步骤 2 的提示变得臃肿,还可能让模型被无关字段干扰。

  • 错误: f'Here is the analysis: {str(all_of_step1_output)}'
  • 正确: 仅提取步骤 2 所需的特定字段,并使用清晰的标签注入

步骤 2 应恰好接收其所需的信息——不多也不少。

基于输出进行条件分支

解析后的步骤 1 输出可以控制运行哪个步骤 2 提示,从而将线性链转为分支流水线:

def route_chain(user_message):
    # Step 1: Classify intent
    classification = json.loads(call(
        f'Classify this message as billing, technical, or general. Return JSON: {{"intent": str}}\n\nMessage: {user_message}'
    ))

    intent = classification['intent']

    # Route to specialized Step 2 prompt
    if intent == 'billing':
        prompt = f'You are a billing specialist. Address: {user_message}'
    elif intent == 'technical':
        prompt = f'You are a senior engineer. Provide technical guidance for: {user_message}'
    else:
        prompt = f'You are a general support agent. Respond to: {user_message}'

    return call(prompt)

print(route_chain('My invoice shows a wrong amount.'))

在步骤间累积状态

对于较长的链,请维护一个状态字典,累积每个步骤的输出:

def run_pipeline(initial_input):
    state = {'input': initial_input}

    # Step 1
    state['entities'] = json.loads(call(
        f'Extract entities as JSON: {{"people": [], "companies": []}}\n\n{state["input"]}'
    ))

    # Step 2 uses entities from Step 1
    companies_str = ', '.join(state['entities'].get('companies', []))
    state['company_types'] = call(
        f'Classify these companies as startup/enterprise: {companies_str}'
    )

    # Step 3 uses output from Steps 1 and 2
    state['summary'] = call(
        f'Write a 2-sentence summary.\nEntities: {state["entities"]}\nClassifications: {state["company_types"]}'
    )

    return state

result = run_pipeline('Apple and OpenAI announced a partnership with Elon Musk.')
print(result['summary'])

JSON 提取工具

为链基础设施构建可复用的提取工具:

import re, json

def extract_json(text):
    "Extract JSON from model output, handling extra text around the object."
    # Try direct parse first
    try:
        return json.loads(text.strip())
    except json.JSONDecodeError:
        pass
    # Try finding JSON object by bracket matching
    start = text.find("{")
    end = text.rfind("}")
    if start != -1 and end != -1 and end > start:
        try:
            return json.loads(text[start:end+1])
        except json.JSONDecodeError:
            pass
    # Try finding JSON array
    start = text.find("[")
    end = text.rfind("]")
    if start != -1 and end != -1 and end > start:
        try:
            return json.loads(text[start:end+1])
        except json.JSONDecodeError:
            pass
    raise ValueError("Could not extract JSON from: " + text[:200])

print(extract_json('{"key": "value"}'))

测试输出到输入模式

输出到输入流水线需要两层测试:

  • 对每个步骤进行单元测试:步骤 1 是否能可靠返回可解析的 JSON?对于给定的提取输入,步骤 2 是否会生成正确的输出?
  • 对整条链进行集成测试:端到端流水线对于具有代表性的输入是否会生成正确的结果?

对于一致性很重要的分类和提取步骤,请将温度设为 0,使步骤提示保持确定性。

def test_step1(review_text, expected_sentiment):
    raw = call(f'Analyze review. Return JSON: {{"sentiment": str}}\n\n{review_text}')
    parsed = extract_json(raw)
    assert parsed['sentiment'] == expected_sentiment, f'Expected {expected_sentiment}, got {parsed["sentiment"]}'
    print(f'PASS: sentiment={parsed["sentiment"]}')

# Run unit test for Step 1
test_step1('The product is excellent!', 'positive')
test_step1('This is terrible.', 'negative')

快速检查

当步骤 1 的结果将被以编程方式提取并注入步骤 2 时,推荐的步骤 1 输出格式是什么?

输出到输入——要点

可靠的输出到输入模式是让提示链达到生产可用水平的关键:

  • 设计步骤 1 提示,使其按明确的模式返回 JSON,而不是散文
  • 注入前解析步骤 1 的输出:去除 Markdown 代码围栏,处理 JSON 解码错误
  • 仅注入步骤 2 所需的特定字段——避免过度注入
  • 使用状态字典在较长的链中累积和传递数据
  • 解析后的输出可以驱动条件分支,将请求路由到专门的步骤 2 提示
  • 构建可处理模型输出不一致性的可复用 JSON 提取工具
  • 分别对每个步骤进行单元测试,然后对完整流水线进行集成测试

常见问题解答

「输出到输入模式」课时是免费的吗?

是的 — 「输出到输入模式」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 AI Prompt Engineering 课程的其余内容,请升级到 CoddyKit PRO。 AI Prompt Engineering 课程共包含 4 节课。

「输出到输入模式」这节课中我会学到什么?

从第 1 步提取结构化数据,并将其注入第 2 步 你通过在浏览器中直接运行的动手代码来练习 AI Prompt Engineering,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 AI Prompt Engineering 需要有经验吗?

无需任何先前经验。CoddyKit 上的 AI Prompt Engineering 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。

「输出到输入模式」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 AI Prompt Engineering 课中编写并运行代码吗?

能。每节 AI Prompt Engineering 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 什么是提示链
  2. 输出到输入模式
  3. 顺序转换链
  4. 提示链中的错误处理
← 返回 AI Prompt Engineering