docs: 添加 ag-ui 和 crewai 项目 skills 及更新文档
This commit is contained in:
@@ -0,0 +1,201 @@
|
||||
/**
|
||||
* AG-UI 工具调用示例
|
||||
*
|
||||
* 展示 Agent 如何调用工具并流式传输参数和结果
|
||||
*
|
||||
* 参考文档: modules/events.md (行 938-1066)
|
||||
*
|
||||
* 事件流:
|
||||
* 1. ToolCallStart - 工具调用开始
|
||||
* 2. ToolCallArgs (多次) - 流式传输参数
|
||||
* 3. ToolCallEnd - 参数传输完成
|
||||
* 4. ToolCallResult - 工具执行结果
|
||||
*/
|
||||
|
||||
import {
|
||||
AbstractAgent,
|
||||
RunAgent,
|
||||
RunAgentInput,
|
||||
EventType,
|
||||
BaseEvent,
|
||||
} from "@ag-ui/client"
|
||||
import { Observable } from "rxjs"
|
||||
|
||||
/**
|
||||
* 工具定义示例
|
||||
*/
|
||||
interface Tool {
|
||||
name: string
|
||||
description: string
|
||||
parameters: Record<string, unknown>
|
||||
}
|
||||
|
||||
const weatherTool: Tool = {
|
||||
name: "get_weather",
|
||||
description: "Get current weather for a location",
|
||||
parameters: {
|
||||
type: "object",
|
||||
properties: {
|
||||
location: {
|
||||
type: "string",
|
||||
description: "City name",
|
||||
},
|
||||
unit: {
|
||||
type: "string",
|
||||
enum: ["celsius", "fahrenheit"],
|
||||
},
|
||||
},
|
||||
required: ["location"],
|
||||
},
|
||||
}
|
||||
|
||||
class ToolCallingAgent extends AbstractAgent {
|
||||
run(input: RunAgentInput): RunAgent {
|
||||
const { threadId, runId } = input
|
||||
|
||||
return () =>
|
||||
new Observable<BaseEvent>((observer) => {
|
||||
observer.next({
|
||||
type: EventType.RUN_STARTED,
|
||||
threadId,
|
||||
runId,
|
||||
})
|
||||
|
||||
// 模拟 Agent 分析用户请求后决定调用工具
|
||||
const toolCallId = `tool_${Date.now()}`
|
||||
const messageId = `msg_${Date.now()}`
|
||||
|
||||
// 1. 发送文本消息说明
|
||||
observer.next({
|
||||
type: EventType.TEXT_MESSAGE_START,
|
||||
messageId,
|
||||
role: "assistant",
|
||||
})
|
||||
|
||||
observer.next({
|
||||
type: EventType.TEXT_MESSAGE_CONTENT,
|
||||
messageId,
|
||||
delta: "Let me check the weather for you.",
|
||||
})
|
||||
|
||||
observer.next({
|
||||
type: EventType.TEXT_MESSAGE_END,
|
||||
messageId,
|
||||
})
|
||||
|
||||
// 2. 开始工具调用
|
||||
observer.next({
|
||||
type: EventType.TOOL_CALL_START,
|
||||
toolCallId,
|
||||
toolCallName: "get_weather",
|
||||
parentMessageId: messageId,
|
||||
})
|
||||
|
||||
// 3. 流式传输参数(分块发送)
|
||||
observer.next({
|
||||
type: EventType.TOOL_CALL_ARGS,
|
||||
toolCallId,
|
||||
delta: '{"loc', // 参数片段 1
|
||||
})
|
||||
|
||||
observer.next({
|
||||
type: EventType.TOOL_CALL_ARGS,
|
||||
toolCallId,
|
||||
delta: 'ation":', // 参数片段 2
|
||||
})
|
||||
|
||||
observer.next({
|
||||
type: EventType.TOOL_CALL_ARGS,
|
||||
toolCallId,
|
||||
delta: ' "San Francisco"}', // 参数片段 3
|
||||
})
|
||||
|
||||
// 4. 参数传输完成
|
||||
observer.next({
|
||||
type: EventType.TOOL_CALL_END,
|
||||
toolCallId,
|
||||
})
|
||||
|
||||
// 5. 工具执行结果(模拟)
|
||||
setTimeout(() => {
|
||||
observer.next({
|
||||
type: EventType.TOOL_CALL_RESULT,
|
||||
toolCallId,
|
||||
content: JSON.stringify({
|
||||
location: "San Francisco",
|
||||
temperature: "18°C",
|
||||
condition: "Partly cloudy",
|
||||
}),
|
||||
})
|
||||
|
||||
// 6. 基于工具结果的响应
|
||||
const responseMsgId = `msg_${Date.now()}_response`
|
||||
observer.next({
|
||||
type: EventType.TEXT_MESSAGE_START,
|
||||
messageId: responseMsgId,
|
||||
role: "assistant",
|
||||
})
|
||||
|
||||
observer.next({
|
||||
type: EventType.TEXT_MESSAGE_CONTENT,
|
||||
messageId: responseMsgId,
|
||||
delta: "The current weather in San Francisco is 18°C and partly cloudy.",
|
||||
})
|
||||
|
||||
observer.next({
|
||||
type: EventType.TEXT_MESSAGE_END,
|
||||
messageId: responseMsgId,
|
||||
})
|
||||
|
||||
observer.next({
|
||||
type: EventType.RUN_FINISHED,
|
||||
threadId,
|
||||
runId,
|
||||
})
|
||||
|
||||
observer.complete()
|
||||
}, 1000)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 使用示例
|
||||
const agent = new ToolCallingAgent()
|
||||
|
||||
agent
|
||||
.runAgent({
|
||||
runId: "run_tool_example",
|
||||
threadId: "thread_123",
|
||||
messages: [
|
||||
{
|
||||
id: "user_1",
|
||||
role: "user",
|
||||
content: "What's the weather in San Francisco?",
|
||||
},
|
||||
],
|
||||
tools: [weatherTool as any],
|
||||
context: [],
|
||||
})
|
||||
.subscribe({
|
||||
next: (event) => {
|
||||
switch (event.type) {
|
||||
case EventType.TOOL_CALL_START:
|
||||
console.log(`[Tool Call] Starting: ${(event as any).toolCallName}`)
|
||||
break
|
||||
case EventType.TOOL_CALL_ARGS:
|
||||
process.stdout.write((event as any).delta)
|
||||
break
|
||||
case EventType.TOOL_CALL_END:
|
||||
console.log("\n[Tool Call] Arguments complete")
|
||||
break
|
||||
case EventType.TOOL_CALL_RESULT:
|
||||
console.log("[Tool Result]", (event as any).content)
|
||||
break
|
||||
default:
|
||||
console.log(`[${event.type}]`)
|
||||
}
|
||||
},
|
||||
complete: () => console.log("Tool call flow completed"),
|
||||
})
|
||||
|
||||
export { ToolCallingAgent, weatherTool }
|
||||
Reference in New Issue
Block a user