出力から入力へ渡すパターン
ステップ 1 で構造化データを抽出し、ステップ 2 に入力する方法を学びます。
「出力から入力へ渡すパターン」はCoddyKit上の無料AI Prompt Engineeringレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応の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-stringまたはテンプレート変数を使用します:
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))2段階チェーン全体
解析と埋め込みを組み合わせた、完全な2段階パイプラインは次のとおりです:
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"}'))出力から入力へのパターンをテストする
出力から入力へのパイプラインには、2段階のテストが必要です:
- 各ステップを単体テストする: ステップ1は解析可能なJSONを安定して返しますか?ステップ2は、抽出した入力に対して正しい出力を生成しますか?
- チェーンを統合テストする: エンドツーエンドのパイプラインは、代表的な入力に対して正しい結果を生成しますか?
一貫性が重要な分類や抽出のステップでは、temperature=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')クイックチェック
結果をプログラムで抽出してステップ2に埋め込む場合、プロンプトチェーンのステップ1にはどのような出力形式が推奨されますか?
出力から入力へ — 重要ポイント
信頼性の高い出力から入力へのパターンが、プロンプトチェーンを本番環境で利用可能にします:
- ステップ1のプロンプトは、文章ではなく、明示的なスキーマを持つJSONを返すように設計します
- ステップ1の出力を埋め込む前に解析します。Markdownフェンスを除去し、JSONDecodeErrorを処理します
- ステップ2に必要な特定のフィールドだけを埋め込み、過剰な埋め込みを避けます
- 状態ディクショナリを使用して、長いチェーン全体でデータを蓄積し、引き渡します
- 解析した出力によって条件分岐を行い、用途に特化したステップ2のプロンプトへ振り分けられます
- モデル出力の一貫性のなさに対応する、再利用可能なJSON抽出ユーティリティを構築します
- 各ステップを個別に単体テストした後、パイプライン全体を統合テストします
AI チューターと学ぶ AI Prompt Engineering — 無料
ブラウザでリアルコードを書いて実行し、24/7 の AI チューターから瞬時にサポートを受け、ウェブまたはアプリで続きから学習できます。
- コース
- 53
- レッスン
- 199
よくある質問
「出力から入力へ渡すパターン」レッスンは無料ですか?
はい。「出力から入力へ渡すパターン」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、AI Prompt Engineeringコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 AI Prompt Engineeringコースには全4レッスンが含まれています。
「出力から入力へ渡すパターン」で何を学びますか?
ステップ 1 で構造化データを抽出し、ステップ 2 に入力する方法を学びます。 ブラウザで直接実行するハンズオンコードでAI Prompt Engineeringを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
AI Prompt Engineeringを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのAI Prompt Engineeringは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。
「出力から入力へ渡すパターン」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このAI Prompt Engineeringレッスンでコードを書いて実行できますか?
はい。すべてのAI Prompt Engineeringレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- プロンプトチェーンとは
- 出力から入力へ渡すパターン
- 逐次変換チェーン
- プロンプトチェーンのエラー処理