Quando você precisa de controle total, seja para personalizar a autenticação, atender a requisitos de residência de dados, fazer a implantação em ambiente local ou adaptar a orquestração de agentes, pode executar o ChatKit na sua própria infraestrutura. Com a opção avançada de hospedagem própria da OpenAI, você pode usar seu próprio servidor e personalizar o ChatKit.
Os fluxos de trabalho do ChatKit hospedados no Agent Builder estão em um período de transição. Para novos aplicativos com o ChatKit, implemente o agente no seu próprio servidor usando os SDKs do ChatKit e o Agents SDK. Consulte as orientações para a transição do ChatKit →
Execute o ChatKit na sua própria infraestrutura
Em uma integração avançada com o ChatKit, você cria seu próprio servidor ChatKit e adiciona widgets à interface do chat. Com as APIs da OpenAI e seu servidor ChatKit, você cria um chat personalizado que usa modelos da OpenAI.

Configure seu servidor ChatKit
Siga o guia do servidor no GitHub para aprender a processar as requisições recebidas, executar ferramentas e transmitir os resultados ao cliente à medida que ficam disponíveis. Os exemplos de código a seguir mostram os principais componentes.
1. Instale o pacote do servidor
pip install openai-chatkit
2. Implemente uma classe de servidor
ChatKitServer gerencia a conversa. Sobrescreva respond para transmitir eventos sempre que o servidor receber uma mensagem do usuário ou o resultado de uma ferramenta do cliente. Funções auxiliares como stream_agent_response conectam o servidor ao Agents SDK.
class MyChatKitServer(ChatKitServer[RequestContext]):
async def respond(
self,
thread: ThreadMetadata,
input: UserMessageItem | ClientToolCallOutputItem | None,
context: RequestContext,
) -> AsyncIterator[Event]:
items_page = await self.store.load_thread_items(
thread.id,
after=None,
limit=20,
order="desc",
context=context,
)
input_items = await simple_to_agent_input(list(reversed(items_page.data)))
agent_context = AgentContext(
thread=thread,
store=self.store,
request_context=context,
)
result = Runner.run_streamed(
assistant_agent,
input_items,
context=agent_context,
)
async for event in stream_agent_response(agent_context, result):
yield event3. Exponha o endpoint
Use o framework de sua preferência para encaminhar as requisições HTTP à instância do servidor. O exemplo a seguir usa o FastAPI.
from fastapi import FastAPI, Request, Response
from fastapi.responses import StreamingResponse
app = FastAPI()
data_store = MemoryStore()
server = MyChatKitServer(data_store)
@app.post("/chatkit")
async def chatkit_endpoint(request: Request):
result = await server.process(await request.body(), {})
if isinstance(result, StreamingResult):
return StreamingResponse(result, media_type="text/event-stream")
return Response(content=result.json, media_type="application/json")4. Implemente o contrato de armazenamento de dados
Implemente chatkit.store.Store para persistir conversas, mensagens e arquivos no banco de dados de sua preferência. Para desenvolvimento local, você pode usar uma implementação de Store em memória. Em produção, use armazenamento durável e considere armazenar os modelos como blobs JSON para que as atualizações da biblioteca possam modificar o schema sem exigir migrações.
5. Implemente o contrato de armazenamento de arquivos
Forneça uma implementação de FileStore se o aplicativo aceitar uploads. O ChatKit aceita uploads diretos (o cliente envia o arquivo ao seu endpoint com uma requisição POST) ou em duas etapas (o cliente solicita uma URL assinada e depois envia o arquivo ao armazenamento em nuvem). Disponibilize prévias para exibir miniaturas na conversa e trate a exclusão de arquivos quando uma conversa for removida.
6. Acione ferramentas do cliente a partir do servidor
Registre as ferramentas do cliente tanto nas opções do cliente quanto no agente. Use ctx.context.client_tool_call para colocar uma chamada na fila a partir de uma ferramenta do Agents SDK.
@function_tool(description_override="Add an item to the user's todo list.")
async def add_to_todo_list(ctx: RunContextWrapper[AgentContext], item: str) -> None:
ctx.context.client_tool_call = ClientToolCall(
name="add_to_todo_list",
arguments={"item": item},
)
assistant_agent = Agent[AgentContext](
model="gpt-6-astra",
name="Assistant",
instructions="You are a helpful assistant",
tools=[add_to_todo_list],
tool_use_behavior=StopAtTools(stop_at_tool_names=[add_to_todo_list.name]),
)7. Use os metadados e o estado da conversa
Use thread.metadata para armazenar o estado no servidor, como o ID da execução anterior da Responses API ou rótulos personalizados. O cliente não tem acesso aos metadados, mas eles estão disponíveis em todas as chamadas ao método respond.
8. Receba atualizações de status das ferramentas
Ferramentas de execução prolongada podem transmitir atualizações de progresso à interface com ProgressUpdateEvent. O ChatKit substitui o evento de progresso pela próxima mensagem do assistente ou pela saída de um widget.
9. Use o contexto do servidor
Passe um objeto de contexto personalizado para server.process(body, context) para aplicar as regras de permissão ou propagar a identidade do usuário pelas implementações de armazenamento de dados e de arquivos.
Adicione widgets interativos à conversa
Com widgets, os agentes podem exibir elementos de interface diretamente no chat. Use widgets para criar cartões, formulários, blocos de texto, listas e outros layouts. A função auxiliar stream_widget pode renderizar um widget imediatamente ou transmitir atualizações à medida que chegam.
async def respond(
self,
thread: ThreadMetadata,
input: UserMessageItem | ClientToolCallOutputItem | None,
context: RequestContext,
) -> AsyncIterator[Event]:
widget = Card(
children=[
Text(
id="description",
value="Generated summary",
)
]
)
async for event in stream_widget(
thread,
widget,
generate_id=lambda item_type: self.store.generate_item_id(
item_type, thread, context
),
):
yield eventO ChatKit inclui diversos nodes de widget, como cartões, listas, formulários, textos e botões. Consulte o guia de widgets no GitHub para conhecer todos os componentes e suas propriedades e ver orientações sobre streaming.
Use o Widget Builder para explorar e criar widgets em uma interface interativa.
Use ações
Com as ações, a interface do ChatKit pode iniciar operações sem enviar uma mensagem do usuário. Associe um ActionConfig a qualquer node de widget compatível. Botões, seletores e outros controles podem transmitir novos itens para a conversa ou atualizar os widgets onde eles já aparecem. Quando um widget faz parte de um Form, o ChatKit inclui os valores coletados pelo formulário no payload da ação.
No servidor, implemente o método action de ChatKitServer para processar o payload e, se desejar, transmitir eventos adicionais. Você também pode tratar ações no cliente definindo handler="client" e respondendo em JavaScript antes de encaminhar as etapas seguintes ao servidor.
Consulte o guia de ações no GitHub para ver como encadear ações, criar payloads com tipagem forte e coordenar os manipuladores de ações do cliente e do servidor.
Recursos
Use os recursos e as referências a seguir para concluir sua integração.
Recursos de design
- Baixe a fonte OpenAI Sans Variable.
- Duplique o arquivo e personalize os componentes para o seu produto.
Referência de eventos
O componente Web do ChatKit emite instâncias de CustomEvent. Escute os eventos do ciclo de vida e leia os dados do payload em event.detail.
chatkit.addEventListener("chatkit.error", (event) => {
console.error(event.detail.error);
});
chatkit.addEventListener("chatkit.response.start", () => {
console.log("Response started");
});
chatkit.addEventListener("chatkit.response.end", () => {
console.log("Response ended");
});
chatkit.addEventListener("chatkit.thread.change", (event) => {
console.log("Active thread:", event.detail.threadId);
});
chatkit.addEventListener("chatkit.log", (event) => {
console.log(event.detail.name, event.detail.data);
});Referência de opções
| Opção | Tipo | Descrição | Padrão |
|---|---|---|---|
apiURL |
string |
Endpoint que implementa o protocolo do servidor ChatKit. | obrigatório |
fetch |
typeof fetch |
Substitui as chamadas a fetch para personalizar os cabeçalhos ou a autenticação. | window.fetch |
theme |
"light" | "dark" |
Tema da interface. | "light" |
initialThread |
string | null |
Conversa a abrir quando o componente é montado. Com null, a interface exibe a tela de nova conversa. |
null |
clientTools |
Record<string, Function> |
Ferramentas disponíveis para o modelo e executadas no cliente. | |
header |
object | boolean |
Configuração do cabeçalho ou false para ocultá-lo. |
true |
newThreadView |
object |
Personaliza o texto de saudação e os prompts iniciais. | |
messages |
object |
Configura recursos das mensagens, como feedback e anotações. | |
composer |
object |
Controla os anexos, as marcações de entidades e o texto exibido no campo vazio. | |
entities |
object |
Funções de callback para buscar entidades, tratar cliques e exibir prévias. |