Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

Python: [Python] structured_outputs_transform reuses ChatHistory across calls (prompt pollution)

オープン 初心者向け
#14,483 コメント 2 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 6 日以内に返信

@jiangjiang248 がすでに取り組んでいます。

2026年9月26日 から。

  • #14487 @jiangjiang248 による — オープン

評価

難易度
2/5
見積もり時間
1〜3時間
初心者へのやさしさ
88/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
活発
技術スタック
python
領域
ai

調査の方向性

semantic_kernel/agents/orchestration/tools.py を読み、structured_outputs_transform とその output_transform クロージャに注目してください。提供されたモックによる再現例を使って、繰り返し呼び出したときのチャット履歴の長さを確認してください。各呼び出しにシステムメッセージと現在のメッセージだけが含まれ、長さ [2, 2, 2] が生成されれば完了です。

索引モデルが issue の本文から書いたものです。

説明

python triage

Description

structured_outputs_transform creates a single ChatHistory in the factory and closes over it. Each output_transform call add_messages into that same history, so prior orchestration outputs leak into later structured-output prompts and the history grows without bound (lengths 2→3→4…).

Environment

  • semantic-kernel==1.44.1 (Python)
  • Python 3.13
  • Repro uses a mocked chat service (no API keys)

Minimal repro

import asyncio
from typing import Any
from pydantic import BaseModel, PrivateAttr
from semantic_kernel.agents.orchestration.tools import structured_outputs_transform
from semantic_kernel.connectors.ai.chat_completion_client_base import ChatCompletionClientBase
from semantic_kernel.connectors.ai.prompt_execution_settings import PromptExecutionSettings
from semantic_kernel.contents import ChatMessageContent
from semantic_kernel.contents.utils.author_role import AuthorRole

class Out(BaseModel):
    answer: str

class FakeSettings(PromptExecutionSettings):
    response_format: Any = None

class FakeService(ChatCompletionClientBase):
    _calls: list = PrivateAttr(default_factory=list)
    def __init__(self) -> None:
        super().__init__(service_id="fake", ai_model_id="fake")
    def get_prompt_execution_settings_class(self):
        return FakeSettings
    async def get_chat_message_contents(self, chat_history, settings, **kwargs):
        self._calls.append(len(chat_history.messages))
        return [ChatMessageContent(role=AuthorRole.ASSISTANT, content='{"answer":"x"}')]
    async def get_chat_message_content(self, chat_history, settings, **kwargs):
        self._calls.append(len(chat_history.messages))
        return ChatMessageContent(role=AuthorRole.ASSISTANT, content='{"answer":"x"}')

async def main():
    svc = FakeService()
    transform = structured_outputs_transform(Out, svc)
    await transform(ChatMessageContent(role=AuthorRole.USER, content="first"))
    await transform(ChatMessageContent(role=AuthorRole.USER, content="second"))
    await transform(ChatMessageContent(role=AuthorRole.USER, content="third"))
    print(svc._calls)  # ACTUAL: [2, 3, 4]  EXPECTED: [2, 2, 2]

asyncio.run(main())

Expected

Each transform invocation uses a fresh history (system + current message only), so independent orchestration steps do not pollute each other.

Actual

Shared history grows across calls; prior outputs leak into later structured-output prompts.

Root cause (pointer)

semantic_kernel/agents/orchestration/tools.py — structured_outputs_transform: chat_history = ChatHistory(...) created once in the factory and mutated inside output_transform.

Suggested fix direction

Construct a fresh ChatHistory (with the system message) inside output_transform on every call.

主要言語
C#
スター
28.7k
フォーク
4.8k
平均マージ
7日 5時間
マージ済み PR(30日)
59

環境構築

Codespaces で開く

このプロジェクトの開発コンテナを、あなたの GitHub アカウントでブラウザ上に起動します。

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

microsoft/semantic-kernel のほかの issue

microsoft/semantic-kernel の issue をすべて見る

似ている issue

C# の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。