docs: 添加 ag-ui 和 crewai 项目 skills 及更新文档

This commit is contained in:
qzl
2026-03-02 17:02:09 +08:00
parent 6fdbc34526
commit ca1ce3d84a
43 changed files with 56074 additions and 3 deletions
@@ -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 }