{"meta":{"title":"변환된 사용자 프롬프트 훅","intro":"userPromptTransformed 후크는 런타임이 생성된 컨텍스트를 제출된 프롬프트에 추가한 후 실행되지만 결과 콘텐츠가 세션 기록에 유지되거나 모델로 전송되기 전에 실행됩니다.","product":"GitHub Copilot","breadcrumbs":[{"href":"/ko/copilot","title":"GitHub Copilot"},{"href":"/ko/copilot/how-tos","title":"방법"},{"href":"/ko/copilot/how-tos/copilot-sdk","title":"코필로트 SDK"},{"href":"/ko/copilot/how-tos/copilot-sdk/hooks","title":"후크 사용"},{"href":"/ko/copilot/how-tos/copilot-sdk/hooks/user-prompt-transformed","title":"변환된 사용자 프롬프트"}],"documentType":"article"},"body":"# 변환된 사용자 프롬프트 훅\n\nuserPromptTransformed 후크는 런타임이 생성된 컨텍스트를 제출된 프롬프트에 추가한 후 실행되지만 결과 콘텐츠가 세션 기록에 유지되거나 모델로 전송되기 전에 실행됩니다.\n\n<!-- markdownlint-disable GHD046 GHD005 -->\n<!-- Suppressed: GHD046 (outdated release terminology), GHD005 (hardcoded data variable) -->\n\n정확한 모델 연결 프롬프트를 검사하거나 교체해야 하는 경우 사용합니다. 입력에는 `prompt` 후크가 실행된 후 `userPromptSubmitted` 사용자 프롬프트가 포함되고 `transformedPrompt` 런타임에서 생성된 컨텍스트(예: `<current_datetime>`)도 포함됩니다.\n\n## 입력 및 출력\n\n| 입력 필드 | Type | Description |\n| --- | --- | --- |\n| `sessionId` | string | 런타임 세션 ID |\n| `timestamp` | 날짜/시간 | 후크가 호출된 시간 |\n| `cwd` / `workingDirectory` | string | 현재 작업 디렉터리 |\n| `prompt` | string | \n`userPromptSubmitted` 후크 뒤의 프롬프트 |\n| `transformedPrompt` | string | 런타임 변환 후 모델 대상 프롬프트 |\n\n값을 반환하지 않으면 변환된 프롬프트는 변경되지 않은 상태로 유지됩니다. 세션 기록에 저장되고 모델로 전송되는 콘텐츠를 대체하기 위해 `modifiedTransformedPrompt`를 반환합니다.\n\n## Examples\n\n<div class=\"ghd-codetabs\">\n<div class=\"ghd-codetab\" data-lang=\"typescript\" data-label=\"TypeScript\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">TypeScript</div>\n\n<!-- docs-validate: skip -->\n\n```typescript\nconst session = await client.createSession({\n  hooks: {\n    onUserPromptTransformed: async (input) => ({\n      modifiedTransformedPrompt: redact(input.transformedPrompt),\n    }),\n  },\n});\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"python\" data-label=\"Python\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Python</div>\n\n<!-- docs-validate: skip -->\n\n```python\nsession = await client.create_session(\n    hooks={\n        \"on_user_prompt_transformed\": lambda input_data, invocation: {\n            \"modifiedTransformedPrompt\": redact(input_data[\"transformedPrompt\"])\n        }\n    }\n)\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"go\" data-label=\"Go\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Go</div>\n\n<!-- docs-validate: skip -->\n\n```golang\nsession, err := client.CreateSession(ctx, &copilot.SessionConfig{\n    Hooks: &copilot.SessionHooks{\n        OnUserPromptTransformed: func(input copilot.UserPromptTransformedHookInput, invocation copilot.HookInvocation) (*copilot.UserPromptTransformedHookOutput, error) {\n            return &copilot.UserPromptTransformedHookOutput{\n                ModifiedTransformedPrompt: copilot.String(redact(input.TransformedPrompt)),\n            }, nil\n        },\n    },\n})\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"dotnet\" data-label=\".NET\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">.NET</div>\n\n<!-- docs-validate: skip -->\n\n```csharp\nvar session = await client.CreateSessionAsync(new SessionConfig\n{\n    Hooks = new SessionHooks\n    {\n        OnUserPromptTransformed = (input, invocation) =>\n            Task.FromResult<UserPromptTransformedHookOutput?>(new()\n            {\n                ModifiedTransformedPrompt = Redact(input.TransformedPrompt),\n            }),\n    },\n});\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"java\" data-label=\"Java\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Java</div>\n\n<!-- docs-validate: skip -->\n\n```java\nvar hooks = new SessionHooks().setOnUserPromptTransformed((input, invocation) ->\n    CompletableFuture.completedFuture(\n        new UserPromptTransformedHookOutput(redact(input.transformedPrompt()))));\n\nvar session = client.createSession(new SessionConfig().setHooks(hooks)).get();\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"rust\" data-label=\"Rust\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Rust</div>\n\n```rust\n#[async_trait]\nimpl SessionHooks for MyHooks {\n    async fn on_user_prompt_transformed(\n        &self,\n        input: UserPromptTransformedInput,\n        _ctx: HookContext,\n    ) -> Option<UserPromptTransformedOutput> {\n        Some(UserPromptTransformedOutput {\n            modified_transformed_prompt: Some(redact(&input.transformed_prompt)),\n        })\n    }\n}\n\nlet session = client\n    .create_session(SessionConfig::default().with_hooks(Arc::new(MyHooks)))\n    .await?;\n```\n\n</div>\n\n</div>\n\n대체는 사용자 메시지 콘텐츠로 유지되므로 다시 시작된 세션에서 수정된 콘텐츠를 변경하지 않고 재생합니다."}