Skip to content

Commit

Permalink
Merge pull request #22 from route06inc/reasoning-keywords
Browse files Browse the repository at this point in the history
Reasoning keywords on Search Node
  • Loading branch information
toyamarinyon authored Oct 18, 2024
2 parents 0b12c72 + 6f2660a commit 7a45a6e
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 115 deletions.
33 changes: 8 additions & 25 deletions app/(playground)/p/[agentId]/beta-proto/graph/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -637,34 +637,17 @@ ${instructionSources.map((source) => `<Source title="${source.title}" type="${so
}
case giselleNodeArchetypes.webSearch: {
const systemPrompt = `
You are an AI assistant specialized in generating effective keywords for Google Search based on user requests. Your task is to analyze the user's input and produce a concise, relevant keyword or short phrase that will yield the most useful search results.
You are an AI assistant specialized in web scraping and searching. Your task is to help users find specific information on websites and extract relevant data based on their requests. Follow these guidelines:
Follow these guidelines:
1. Identify the core topic or intent of the user's request.
2. Extract the most important words or concepts.
3. Consider synonyms or related terms that might be more commonly used.
4. Aim for specificity while avoiding overly niche terms.
5. Keep the keyword or phrase concise, typically 1-3 words.
6. Avoid branded terms unless specifically mentioned by the user.
7. Use common spelling and avoid abbreviations unless they are widely recognized.
8. You must suggest keywords at least 3 times.
9. If provided, incorporate relevant reference information to refine the keyword.
1. Understand the user's request:
- Identify the type of information they're looking for
- Determine any specific websites or domains they want to search
- Note any constraints or preferences in the data format
Examples:
User request: "I need information about the health benefits of eating apples."
Keyword: "apple health benefits"
2. Formulate a search strategy:
- Suggest appropriate search queries with relevant keywords at least 3-5 words long
- Use the current date as ${new Date().toLocaleDateString()}, in the search query if necessary
User request: "What are some good restaurants in New York City for Italian cuisine?"
Keyword: "best NYC Italian restaurants"
User request: "How do I fix a leaky faucet in my bathroom sink?"
Keyword: "fix leaky faucet"
User request: "Tell me about the impact of climate change on polar bears."
Reference info: Recent studies show declining sea ice affects hunting patterns.
Keyword: "polar bear sea ice impact"
Now, generate an appropriate keyword or short phrase for Google Search based on the user's request and any provided reference information.
--
${instructionSources.map((source) => `<Source title="${source.title}" type="${source.object}" id="${source.id}">${source.content}</Source>`).join("\n")}
Expand Down
75 changes: 1 addition & 74 deletions app/(playground)/p/[agentId]/beta-proto/graph/server-actions.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
"use server";

import { openai } from "@ai-sdk/openai";
import {
type CoreMessage,
jsonSchema,
streamText as sdkStreamText,
streamObject,
} from "ai";
import { streamObject } from "ai";
import { createStreamableValue } from "ai/rsc";
import { UnstructuredClient } from "unstructured-client";

Expand All @@ -20,26 +15,10 @@ import { Langfuse } from "langfuse";
import { Strategy } from "unstructured-client/sdk/models/shared";
import { schema as artifactSchema } from "../artifact/schema";
import type { FileId } from "../files/types";
import type { GiselleNodeArchetype } from "../giselle-node/blueprints";
import type { AgentId } from "../types";
import { elementsToMarkdown } from "../utils/unstructured";
import type { Graph } from "./types";

const webSearchSchema = jsonSchema<{ keywords: string[] }>({
$schema: "https://json-schema.org/draft/2020-12/schema",
title: "keyword schema",
type: "object",
properties: {
keywords: {
type: "array",
items: {
type: "string",
},
},
},
required: ["keywords"],
});

type GenerateArtifactStreamParams = {
userPrompt: string;
systemPrompt?: string;
Expand Down Expand Up @@ -92,58 +71,6 @@ export async function generateArtifactStream(
return { object: stream.value };
}

type GenerateWebSearchStreamInputs = {
userPrompt: string;
systemPrompt?: string;
};
export async function generateWebSearchStream(
inputs: GenerateWebSearchStreamInputs,
) {
const lf = new Langfuse();
const trace = lf.trace({
id: `giselle-${Date.now()}`,
});
const stream = createStreamableValue();

(async () => {
const model = "gpt-4o-mini";
const generation = trace.generation({
input: inputs.userPrompt,
model,
});
const { partialObjectStream } = await streamObject({
model: openai(model),
system: inputs.systemPrompt ?? "You generate an answer to a question. ",
prompt: inputs.userPrompt,
schema: artifactSchema,
onFinish: async (result) => {
const meter = metrics.getMeter("OpenAI");
const tokenCounter = meter.createCounter("token_consumed", {
description: "Number of OpenAI API tokens consumed by each request",
});
const subscriptionId = await getUserSubscriptionId();
const isR06User = await isRoute06User();
tokenCounter.add(result.usage.totalTokens, {
subscriptionId,
isR06User,
});
generation.end({
output: result,
});
await lf.shutdownAsync();
},
});

for await (const partialObject of partialObjectStream) {
stream.update(partialObject);
}

stream.done();
})();

return { object: stream.value };
}

export async function setGraphToDb(agentId: AgentId, graph: Graph) {
await db
.update(agents)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ export const WebSearchPropertyPanel: FC<WebSearchPropertyPanelProps> = ({
</div>
</div>
)}
<div>{(node.output as PartialGeneratedObject).thinking}</div>
<div>{(node.output as PartialGeneratedObject).plan}</div>
{(node.output as PartialGeneratedObject).webSearch && (
<div>
<WebSearchBlock
Expand Down
25 changes: 25 additions & 0 deletions app/(playground)/p/[agentId]/beta-proto/web-search/schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { jsonSchema } from "ai";

export const webSearchSchema = jsonSchema<{ plan: string; keywords: string[] }>(
{
$schema: "https://json-schema.org/draft/2020-12/schema",
title: "keyword schema",
type: "object",
properties: {
plan: {
type: "string",
description: "Describe the plan that you will archive user request",
},
keywords: {
type: "array",
items: {
type: "string",
description:
"Suggest appropriate search queries with relevant keywords at least 3-5 words long",
},
description: "The keywords to search for user request",
},
},
required: ["plan", "keywords"],
},
);
58 changes: 44 additions & 14 deletions app/(playground)/p/[agentId]/beta-proto/web-search/server-action.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
"use server";

import { getUserSubscriptionId, isRoute06User } from "@/app/(auth)/lib";
import { openai } from "@ai-sdk/openai";
import { metrics } from "@opentelemetry/api";
import { streamObject } from "ai";
import { createStreamableValue } from "ai/rsc";
import Langfuse from "langfuse";
import { webSearchSchema } from "./schema";

const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));

Expand All @@ -11,33 +17,57 @@ interface GenerateWebSearchStreamInputs {
export async function generateWebSearchStream(
inputs: GenerateWebSearchStreamInputs,
) {
const lf = new Langfuse();
const trace = lf.trace({
id: `giselle-${Date.now()}`,
});
const stream = createStreamableValue();

(async () => {
stream.update({});

await sleep(500);

stream.update({
thinking: "Search the web",
const model = "gpt-4o-mini";
const generation = trace.generation({
input: inputs.userPrompt,
model,
});

await sleep(500);
stream.update({
thinking: "Search the web to find information relevant to your request.",
const { partialObjectStream, object } = await streamObject({
model: openai(model),
system: inputs.systemPrompt ?? "You generate an answer to a question. ",
prompt: inputs.userPrompt,
schema: webSearchSchema,
onFinish: async (result) => {
const meter = metrics.getMeter("OpenAI");
const tokenCounter = meter.createCounter("token_consumed", {
description: "Number of OpenAI API tokens consumed by each request",
});
const subscriptionId = await getUserSubscriptionId();
const isR06User = await isRoute06User();
tokenCounter.add(result.usage.totalTokens, {
subscriptionId,
isR06User,
});
generation.end({
output: result,
});
await lf.shutdownAsync();
},
});
for await (const partialObject of partialObjectStream) {
stream.update(partialObject);
}

const result = await object;

await sleep(500);
stream.update({
thinking: "Search the web to find information relevant to your request.",
...result,
webSearch: {
name: "Why Deno is the best choice for biginner",
},
});

await sleep(1000);
stream.update({
thinking: "Search the web to find information relevant to your request.",
...result,
webSearch: {
name: "Why Deno is the best choice for biginner",
items: [
Expand All @@ -53,7 +83,7 @@ export async function generateWebSearchStream(

await sleep(1000);
stream.update({
thinking: "Search the web to find information relevant to your request.",
...result,
webSearch: {
name: "Why Deno is the best choice for biginner",
items: [
Expand All @@ -74,7 +104,7 @@ export async function generateWebSearchStream(
});
await sleep(1000);
stream.update({
thinking: "Search the web to find information relevant to your request.",
...result,
webSearch: {
name: "Why Deno is the best choice for biginner",
items: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ interface WebSearchItem {
}

export interface GeneratedObject {
thinking: string;
plan: string;
webSearch: WebSearch;
description: string;
}
Expand Down

0 comments on commit 7a45a6e

Please sign in to comment.