adjusts prompt transform to discourage Gemini from speaking for user

This commit is contained in:
nai-degen 2023-12-13 23:03:57 -06:00
parent 8a135a960d
commit c5cd90dcef
3 changed files with 33 additions and 12 deletions

View File

@ -79,10 +79,12 @@ const googleAIResponseHandler: ProxyResHandlerWithBody = async (
}; };
function transformGoogleAIResponse( function transformGoogleAIResponse(
googleAIResp: Record<string, any>, resBody: Record<string, any>,
req: Request req: Request
): Record<string, any> { ): Record<string, any> {
const totalTokens = (req.promptTokens ?? 0) + (req.outputTokens ?? 0); const totalTokens = (req.promptTokens ?? 0) + (req.outputTokens ?? 0);
const parts = resBody.candidates[0].content?.parts ?? [{ text: "" }];
const content = parts[0].text.replace(/^(.{0,50}?): /, () => "");
return { return {
id: "goo-" + v4(), id: "goo-" + v4(),
object: "chat.completion", object: "chat.completion",
@ -95,11 +97,8 @@ function transformGoogleAIResponse(
}, },
choices: [ choices: [
{ {
message: { message: { role: "assistant", content },
role: "assistant", finish_reason: resBody.candidates[0].finishReason,
content: googleAIResp.candidates[0].content.parts[0].text,
},
finish_reason: googleAIResp.candidates[0].finishReason,
index: 0, index: 0,
}, },
], ],

View File

@ -346,14 +346,29 @@ function openaiToGoogleAI(
const foundNames = new Set<string>(); const foundNames = new Set<string>();
const contents = messages const contents = messages
.map((m) => { .map((m) => {
const role = m.role === "assistant" ? "model" : "user";
// Detects character names so we can set stop sequences for them as Gemini // Detects character names so we can set stop sequences for them as Gemini
// is prone to continuing as the next character. // is prone to continuing as the next character.
// If names are not available, we'll still try to prefix the message
// with generic names so we can set stops for them but they don't work
// as well as real names.
const text = flattenOpenAIMessageContent(m.content); const text = flattenOpenAIMessageContent(m.content);
const name = m.name?.trim() || text.match(/^(.*?): /)?.[1]?.trim(); const propName = m.name?.trim();
if (name) foundNames.add(name); const textName = text.match(/^(.*?): /)?.[1]?.trim();
const name =
propName || textName || (role === "model" ? "Character" : "User");
foundNames.add(name);
// Prefixing messages with their character name seems to help avoid
// Gemini trying to continue as the next character, or at the very least
// ensures it will hit the stop sequence. Otherwise it will start a new
// paragraph and switch perspectives.
// The response will be very likely to include this prefix so frontends
// will need to strip it out.
const textPrefix = propName ? `${propName}: ` : "";
return { return {
parts: [{ text }], parts: [{ text: textPrefix + text }],
role: m.role === "assistant" ? ("model" as const) : ("user" as const), role: m.role === "assistant" ? ("model" as const) : ("user" as const),
}; };
}) })

View File

@ -22,7 +22,7 @@ type GoogleAIStreamEvent = {
* chat.completion.chunk SSE. * chat.completion.chunk SSE.
*/ */
export const googleAIToOpenAI: StreamingCompletionTransformer = (params) => { export const googleAIToOpenAI: StreamingCompletionTransformer = (params) => {
const { data } = params; const { data, index } = params;
const rawEvent = parseEvent(data); const rawEvent = parseEvent(data);
if (!rawEvent.data || rawEvent.data === "[DONE]") { if (!rawEvent.data || rawEvent.data === "[DONE]") {
@ -35,7 +35,14 @@ export const googleAIToOpenAI: StreamingCompletionTransformer = (params) => {
} }
const parts = completionEvent.candidates[0].content.parts; const parts = completionEvent.candidates[0].content.parts;
const text = parts[0]?.text ?? ""; let content = parts[0]?.text ?? "";
// If this is the first chunk, try stripping speaker names from the response
// e.g. "John: Hello" -> "Hello"
if (index === 0) {
content = content.replace(/^(.*?): /, "").trim();
}
const newEvent = { const newEvent = {
id: "goo-" + params.fallbackId, id: "goo-" + params.fallbackId,
object: "chat.completion.chunk" as const, object: "chat.completion.chunk" as const,
@ -44,7 +51,7 @@ export const googleAIToOpenAI: StreamingCompletionTransformer = (params) => {
choices: [ choices: [
{ {
index: 0, index: 0,
delta: { content: text }, delta: { content },
finish_reason: completionEvent.candidates[0].finishReason ?? null, finish_reason: completionEvent.candidates[0].finishReason ?? null,
}, },
], ],