fix ch4 to ch8

This commit is contained in:
mayo
2025-02-10 06:45:38 +00:00
parent 9499a9eba0
commit 50c5aa39ce
11 changed files with 105 additions and 83 deletions
+7 -6
View File
@@ -3,9 +3,10 @@ import {
Annotation,
messagesStateReducer,
START,
} from "@langchain/langgraph";
import { ChatOpenAI } from "@langchain/openai";
import { HumanMessage } from "@langchain/core/messages";
END,
} from '@langchain/langgraph';
import { ChatOpenAI } from '@langchain/openai';
import { HumanMessage } from '@langchain/core/messages';
const State = {
messages: Annotation({
@@ -23,14 +24,14 @@ async function chatbot(state) {
return { messages: answer };
}
builder = builder.addNode("chatbot", chatbot);
builder = builder.addNode('chatbot', chatbot);
builder = builder.addEdge(START, "chatbot").addEdge("chatbot", END);
builder = builder.addEdge(START, 'chatbot').addEdge('chatbot', END);
let graph = builder.compile();
// Run the graph
const input = { messages: [new HumanMessage("hi!")] };
const input = { messages: [new HumanMessage('hi!')] };
for await (const chunk of await graph.stream(input)) {
console.log(chunk);
}
+24 -12
View File
@@ -3,27 +3,39 @@ import {
SystemMessage,
AIMessage,
filterMessages,
} from "@langchain/core/messages";
} from '@langchain/core/messages';
const messages = [
new SystemMessage({ content: "you are a good assistant", id: "1" }),
new HumanMessage({ content: "example input", id: "2", name: "example_user" }),
new SystemMessage({ content: 'you are a good assistant', id: '1' }),
new HumanMessage({ content: 'example input', id: '2', name: 'example_user' }),
new AIMessage({
content: "example output",
id: "3",
name: "example_assistant",
content: 'example output',
id: '3',
name: 'example_assistant',
}),
new HumanMessage({ content: "real input", id: "4", name: "bob" }),
new AIMessage({ content: "real output", id: "5", name: "alice" }),
new HumanMessage({ content: 'real input', id: '4', name: 'bob' }),
new AIMessage({ content: 'real output', id: '5', name: 'alice' }),
];
// Filter for human messages
filterMessages(messages, { includeTypes: ["human"] });
const filterByHumanMessages = filterMessages(messages, {
includeTypes: ['human'],
});
console.log(`Human messages: ${JSON.stringify(filterByHumanMessages)}`);
// Filter to exclude names
filterMessages(messages, {
excludeNames: ["example_user", "example_assistant"],
const filterByExcludedNames = filterMessages(messages, {
excludeNames: ['example_user', 'example_assistant'],
});
console.log(
`\nExcluding example names: ${JSON.stringify(filterByExcludedNames)}`
);
// Filter by types and IDs
filterMessages(messages, { includeTypes: ["human", "ai"], excludeIds: ["3"] });
const filterByTypesAndIDs = filterMessages(messages, {
includeTypes: ['human', 'ai'],
excludeIds: ['3'],
});
console.log(
`\nFiltered by types and IDs: ${JSON.stringify(filterByTypesAndIDs)}`
);
+8 -7
View File
@@ -3,22 +3,23 @@ import {
SystemMessage,
AIMessage,
mergeMessageRuns,
} from "@langchain/core/messages";
} from '@langchain/core/messages';
const messages = [
new SystemMessage("you're a good assistant."),
new SystemMessage("you always respond with a joke."),
new SystemMessage('you always respond with a joke.'),
new HumanMessage({
content: [{ type: "text", text: "i wonder why it's called langchain" }],
content: [{ type: 'text', text: "i wonder why it's called langchain" }],
}),
new HumanMessage("and who is harrison chasing anyways"),
new HumanMessage('and who is harrison chasing anyways'),
new AIMessage(
'Well, I guess they thought "WordRope" and "SentenceString" just didn\'t have the same ring to it!',
'Well, I guess they thought "WordRope" and "SentenceString" just didn\'t have the same ring to it!'
),
new AIMessage(
"Why, he's probably chasing after the last cup of coffee in the office!",
"Why, he's probably chasing after the last cup of coffee in the office!"
),
];
// Merge consecutive messages
mergeMessageRuns(messages);
const mergedMessages = mergeMessageRuns(messages);
console.log(mergedMessages);
+8 -8
View File
@@ -1,13 +1,13 @@
import {
StateGraph,
StateType,
Annotation,
messagesStateReducer,
START,
} from "@langchain/langgraph";
END,
} from '@langchain/langgraph';
import { ChatOpenAI } from "@langchain/openai";
import { HumanMessage } from "@langchain/core/messages";
import { ChatOpenAI } from '@langchain/openai';
import { HumanMessage } from '@langchain/core/messages';
const model = new ChatOpenAI();
@@ -28,14 +28,14 @@ async function chatbot(state) {
}
const builder = new StateGraph(State)
.addNode("chatbot", chatbot)
.addEdge(START, "chatbot")
.addEdge("chatbot", END);
.addNode('chatbot', chatbot)
.addEdge(START, 'chatbot')
.addEdge('chatbot', END);
const graph = builder.compile();
// Example usage
const input = { messages: [new HumanMessage("hi!")] };
const input = { messages: [new HumanMessage('hi!')] };
for await (const chunk of await graph.stream(input)) {
console.log(chunk);
}
+20 -20
View File
@@ -1,17 +1,17 @@
import { DuckDuckGoSearch } from "@langchain/community/tools/duckduckgo_search";
import { Calculator } from "@langchain/community/tools/calculator";
import { ChatOpenAI } from "@langchain/openai";
import { OpenAIEmbeddings } from "@langchain/openai";
import { Document } from "@langchain/core/documents";
import { MemoryVectorStore } from "@langchain/community/vectorstores/memory";
import { DuckDuckGoSearch } from '@langchain/community/tools/duckduckgo_search';
import { Calculator } from '@langchain/community/tools/calculator';
import { ChatOpenAI } from '@langchain/openai';
import { OpenAIEmbeddings } from '@langchain/openai';
import { Document } from '@langchain/core/documents';
import { MemoryVectorStore } from 'langchain/vectorstores/memory';
import {
StateGraph,
Annotation,
messagesStateReducer,
START,
} from "@langchain/langgraph";
import { ToolNode, toolsCondition } from "@langchain/langgraph/prebuilt";
import { HumanMessage } from "@langchain/core/messages";
} from '@langchain/langgraph';
import { ToolNode, toolsCondition } from '@langchain/langgraph/prebuilt';
import { HumanMessage } from '@langchain/core/messages';
const search = new DuckDuckGoSearch();
const calculator = new Calculator();
@@ -27,9 +27,9 @@ const toolsStore = await MemoryVectorStore.fromDocuments(
new Document({
pageContent: tool.description,
metadata: { name: tool.constructor.name },
}),
})
),
embeddings,
embeddings
);
const toolsRetriever = toolsStore.asRetriever();
@@ -40,7 +40,7 @@ const annotation = Annotation.Root({
async function modelNode(state) {
const selectedTools = tools.filter((tool) =>
state.selected_tools.includes(tool.constructor.name),
state.selected_tools.includes(tool.constructor.name)
);
const res = await model.bindTools(selectedTools).invoke(state.messages);
return { messages: res };
@@ -55,13 +55,13 @@ async function selectTools(state) {
}
const builder = new StateGraph(annotation)
.addNode("select_tools", selectTools)
.addNode("model", modelNode)
.addNode("tools", new ToolNode(tools))
.addEdge(START, "select_tools")
.addEdge("select_tools", "model")
.addConditionalEdges("model", toolsCondition)
.addEdge("tools", "model");
.addNode('select_tools', selectTools)
.addNode('model', modelNode)
.addNode('tools', new ToolNode(tools))
.addEdge(START, 'select_tools')
.addEdge('select_tools', 'model')
.addConditionalEdges('model', toolsCondition)
.addEdge('tools', 'model');
const graph = builder.compile();
@@ -69,7 +69,7 @@ const graph = builder.compile();
const input = {
messages: [
new HumanMessage(
"How old was the 30th president of the United States when he died?",
'How old was the 30th president of the United States when he died?'
),
],
};
+19 -16
View File
@@ -2,15 +2,15 @@ import {
AIMessage,
SystemMessage,
HumanMessage,
} from "@langchain/core/messages";
import { ChatOpenAI } from "@langchain/openai";
} from '@langchain/core/messages';
import { ChatOpenAI } from '@langchain/openai';
import {
StateGraph,
Annotation,
messagesStateReducer,
START,
END,
} from "@langchain/langgraph";
} from '@langchain/langgraph';
const model = new ChatOpenAI();
@@ -21,7 +21,7 @@ const annotation = Annotation.Root({
const generatePrompt = new SystemMessage(
`You are an essay assistant tasked with writing excellent 3-paragraph essays.
Generate the best essay possible for the user's request.
If the user provides critique, respond with a revised version of your previous attempts.`,
If the user provides critique, respond with a revised version of your previous attempts.`
);
async function generate(state) {
@@ -31,7 +31,7 @@ async function generate(state) {
const reflectionPrompt = new SystemMessage(
`You are a teacher grading an essay submission. Generate critique and recommendations for the user's submission.
Provide detailed recommendations, including requests for length, depth, style, etc.`,
Provide detailed recommendations, including requests for length, depth, style, etc.`
);
async function reflect(state) {
@@ -58,16 +58,16 @@ function shouldContinue(state) {
// End after 3 iterations, each with 2 messages
return END;
} else {
return "reflect";
return 'reflect';
}
}
const builder = new StateGraph(annotation)
.addNode("generate", generate)
.addNode("reflect", reflect)
.addEdge(START, "generate")
.addConditionalEdges("generate", shouldContinue)
.addEdge("reflect", "generate");
.addNode('generate', generate)
.addNode('reflect', reflect)
.addEdge(START, 'generate')
.addConditionalEdges('generate', shouldContinue)
.addEdge('reflect', 'generate');
const graph = builder.compile();
@@ -75,15 +75,18 @@ const graph = builder.compile();
const initialState = {
messages: [
new HumanMessage(
"Write an essay about the relevance of 'The Little Prince' today.",
"Write an essay about the relevance of 'The Little Prince' today."
),
],
};
for await (const output of graph.stream(initialState)) {
for await (const output of await graph.stream(initialState)) {
const messageType = output.generate ? 'generate' : 'reflect';
console.log(
"\nNew message:",
output.messages[output.messages.length - 1].content.slice(0, 100),
"...",
'\nNew message:',
output[messageType].messages[
output[messageType].messages.length - 1
].content.slice(0, 100),
'...'
);
}
+7 -6
View File
@@ -1,4 +1,4 @@
import { StateGraph, START, Annotation } from "@langchain/langgraph";
import { StateGraph, START, Annotation } from '@langchain/langgraph';
const StateAnnotation = Annotation.Root({
foo: Annotation(), // string type
@@ -13,22 +13,23 @@ const SubgraphStateAnnotation = Annotation.Root({
const subgraphNode = async (state) => {
// note that this subgraph node can communicate with
// the parent graph via the shared "foo" key
return { foo: state.foo + "bar" };
return { foo: state.foo + 'bar' };
};
const subgraph = new StateGraph(SubgraphStateAnnotation)
.addNode("subgraph", subgraphNode)
.addNode('subgraph', subgraphNode)
.addEdge(START, 'subgraph')
// Additional subgraph setup would go here
.compile();
// Define parent graph
const parentGraph = new StateGraph(StateAnnotation)
.addNode("subgraph", subgraph)
.addEdge(START, "subgraph")
.addNode('subgraph', subgraph)
.addEdge(START, 'subgraph')
// Additional parent graph setup would go here
.compile();
// Example usage
const initialState = { foo: "hello" };
const initialState = { foo: 'hello' };
const result = await parentGraph.invoke(initialState);
console.log(`Result: ${JSON.stringify(result)}`); // Should append "bar" to the foo value
+7 -6
View File
@@ -1,4 +1,4 @@
import { StateGraph, START, Annotation } from "@langchain/langgraph";
import { StateGraph, START, Annotation } from '@langchain/langgraph';
const StateAnnotation = Annotation.Root({
foo: Annotation(),
@@ -12,11 +12,12 @@ const SubgraphStateAnnotation = Annotation.Root({
// Define subgraph
const subgraphNode = async (state) => {
return { bar: state.bar + "baz" };
return { bar: state.bar + 'baz' };
};
const subgraph = new StateGraph(SubgraphStateAnnotation)
.addNode("subgraph", subgraphNode)
.addNode('subgraph', subgraphNode)
.addEdge(START, 'subgraph')
// Additional subgraph setup would go here
.compile();
@@ -33,13 +34,13 @@ const subgraphWrapperNode = async (state) => {
};
const parentGraph = new StateGraph(StateAnnotation)
.addNode("subgraph", subgraphWrapperNode)
.addEdge(START, "subgraph")
.addNode('subgraph', subgraphWrapperNode)
.addEdge(START, 'subgraph')
// Additional parent graph setup would go here
.compile();
// Example usage
const initialState = { foo: "hello" };
const initialState = { foo: 'hello' };
const result = await parentGraph.invoke(initialState);
console.log(`Result: ${JSON.stringify(result)}`); // Should transform foo->bar, append "baz", then transform bar->foo
+3 -1
View File
@@ -78,4 +78,6 @@ initial_state = {
# Run the graph
for output in graph.stream(initial_state):
print("\nNew message:", output["messages"][-1].content[:100], "...")
message_type = "generate" if "generate" in output else "reflect"
print("\nNew message:", output[message_type]
["messages"][-1].content[:100], "...")
+1
View File
@@ -19,6 +19,7 @@ def subgraph_node(state: SubgraphState):
subgraph_builder = StateGraph(SubgraphState)
subgraph_builder.add_node("subgraph_node", subgraph_node)
subgraph_builder.add_edge(START, "subgraph_node")
# Additional subgraph setup would go here
subgraph = subgraph_builder.compile()
+1 -1
View File
@@ -7,7 +7,7 @@ class Joke(BaseModel):
punchline: str = Field(description="The punchline to the joke")
model = ChatOpenAI(model="gpt-3.5-turbo-0125", temperature=0)
model = ChatOpenAI(model="gpt-4o", temperature=0)
model = model.with_structured_output(Joke)
result = model.invoke("Tell me a joke about cats")