This commit is contained in:
liubiren 2026-09-18 20:10:07 +08:00
parent 8919d623bc
commit 6624427528
2 changed files with 54 additions and 46 deletions

View File

@ -4,6 +4,7 @@
""" """
from typing import Any, AsyncGenerator from typing import Any, AsyncGenerator
from asyncpg import Pool
from pydantic import BaseModel, Field from pydantic import BaseModel, Field
from pydantic_ai import ( from pydantic_ai import (
Agent, Agent,
@ -14,21 +15,13 @@ from pydantic_ai import (
RunUsage, RunUsage,
UsageLimits, UsageLimits,
) )
from pydantic_ai.messages import ( from pydantic_ai.messages import AgentStreamEvent
AgentStreamEvent, from pydantic_ai.run import AgentRunResultEvent
PartStartEvent,
ToolCallPart,
FunctionToolResultEvent,
ToolReturnPart,
)
from pydantic_ai.run import AgentRunResultEvent, AgentRunResult
from application.workshop.models import ( from application.workshop.models import (
DEEPSEEK_V4_FLASH_MODEL, DEEPSEEK_V4_FLASH_MODEL,
DEEPSEEK_V4_FLASH_MODEL_SETTINGS, DEEPSEEK_V4_FLASH_MODEL_SETTINGS,
) )
from asyncpg import Pool
from application.workshop.events import AgentRuntimeEvent
class Deps(BaseModel): class Deps(BaseModel):
@ -42,14 +35,6 @@ class Deps(BaseModel):
connection_pool: Pool = Field(..., description="连接池") connection_pool: Pool = Field(..., description="连接池")
class Output(BaseModel):
"""
输出类
"""
response: str = Field(..., description="客服应答")
# 账户上下文能力 # 账户上下文能力
account_context = Capability[Deps]( account_context = Capability[Deps](
id="account-context", id="account-context",
@ -89,15 +74,61 @@ async def query_account_balance(ctx: RunContext[Deps]) -> str:
# 智能体 # 智能体
agent = Agent[Deps, Output]( agent = Agent[Deps, str](
model=DEEPSEEK_V4_FLASH_MODEL, model=DEEPSEEK_V4_FLASH_MODEL,
model_settings=DEEPSEEK_V4_FLASH_MODEL_SETTINGS, model_settings=DEEPSEEK_V4_FLASH_MODEL_SETTINGS,
deps_type=Deps, deps_type=Deps,
output_type=Output, output_type=str, # 若输出类型为 str,则智能体输出结果时不进行输出类型校验。若定义输出类型,需考虑处理相应事件
instructions="你是我方银行的客服智能体,为客户提供客服应答。", instructions="你是我方银行的客服智能体,为客户提供客服应答。", # 优先使用 instructions
capabilities=[account_context], capabilities=[account_context],
) )
"""
此为设置输出类型为 Output,智能体输出结果时需校验输出类型,同工具调用:
PartStartEvent(index=0, part=ToolCallPart(tool_name='final_result', args='', tool_call_id='call_3ab0ed20b1114fa0be726723'))
FinalResultEvent(tool_name='final_result', tool_call_id='call_3ab0ed20b1114fa0be726723')
PartDeltaEvent(index=0, delta=ToolCallPartDelta(args_delta='', tool_call_id='call_3ab0ed20b1114fa0be726723'))
PartDeltaEvent(index=0, delta=ToolCallPartDelta(args_delta='{', tool_call_id='call_3ab0ed20b1114fa0be726723'))
PartDeltaEvent (index=0, delta=ToolCallPartDelta (args_delta='"response": " 您好 ', tool_call_id='call_3ab0ed20b1114fa0be726723'))
PartDeltaEvent (index=0, delta=ToolCallPartDelta (args_delta=',刘 ', tool_call_id='call_3ab0ed20b1114fa0be726723'))
PartDeltaEvent (index=0, delta=ToolCallPartDelta (args_delta=' 弼仁 ', tool_call_id='call_3ab0ed20b1114fa0be726723'))
PartDeltaEvent (index=0, delta=ToolCallPartDelta (args_delta=' 先生。', tool_call_id='call_3ab0ed20b1114fa0be726723'))
PartDeltaEvent (index=0, delta=ToolCallPartDelta (args_delta=' 您账户 ', tool_call_id='call_3ab0ed20b1114fa0be726723'))
PartDeltaEvent (index=0, delta=ToolCallPartDelta (args_delta=' 的 ', tool_call_id='call_3ab0ed20b1114fa0be726723'))
PartDeltaEvent (index=0, delta=ToolCallPartDelta (args_delta=' 当前余额 ', tool_call_id='call_3ab0ed20b1114fa0be726723'))
PartDeltaEvent (index=0, delta=ToolCallPartDelta (args_delta=' 为 **', tool_call_id='call_3ab0ed20b1114fa0be726723'))
PartDeltaEvent(index=0, delta=ToolCallPartDelta(args_delta='9.', tool_call_id='call_3ab0ed20b1114fa0be726723'))
PartDeltaEvent (index=0, delta=ToolCallPartDelta (args_delta='99 元 ', tool_call_id='call_3ab0ed20b1114fa0be726723'))
PartDeltaEvent(index=0, delta=ToolCallPartDelta(args_delta='**。', tool_call_id='call_3ab0ed20b1114fa0be726723'))
PartDeltaEvent (index=0, delta=ToolCallPartDelta (args_delta=' 请问还有什么 ', tool_call_id='call_3ab0ed20b1114fa0be726723'))
PartDeltaEvent (index=0, delta=ToolCallPartDelta (args_delta=' 可以帮 ', tool_call_id='call_3ab0ed20b1114fa0be726723'))
PartDeltaEvent (index=0, delta=ToolCallPartDelta (args_delta=' 您的 ', tool_call_id='call_3ab0ed20b1114fa0be726723'))
PartDeltaEvent (index=0, delta=ToolCallPartDelta (args_delta=' 吗?"}', tool_call_id='call_3ab0ed20b1114fa0be726723'))
PartEndEvent (index=0, part=ToolCallPart (tool_name='final_result', args='{"response": " 您好,刘弼仁先生。您账户的当前余额为 **9.99 元**。请问还有什么可以帮您的吗?"}', tool_call_id='call_3ab0ed20b1114fa0be726723'))
OutputToolCallEvent (part=ToolCallPart (tool_name='final_result', args='{"response": " 您好,刘弼仁先生。您账户的当前余额为 **9.99 元**。请问还有什么可以帮您的吗?"}', tool_call_id='call_3ab0ed20b1114fa0be726723'), args_valid=True)
OutputToolResultEvent(part=ToolReturnPart(tool_name='final_result', content='Final result processed.', tool_call_id='call_3ab0ed20b1114fa0be726723', timestamp=datetime.datetime(2026, 9, 17, 10, 34, 0, 799329, tzinfo=datetime.timezone.utc)))
此为设置输出类型为 str,智能体输出结果时不进行输出类型校验:
PartStartEvent(index=0, part=TextPart(content='您好'))
FinalResultEvent(tool_name=None, tool_call_id=None)
PartDeltaEvent(index=0, delta=TextPartDelta(content_delta=',刘'))
PartDeltaEvent(index=0, delta=TextPartDelta(content_delta='弼仁'))
PartDeltaEvent(index=0, delta=TextPartDelta(content_delta='先生。'))
PartDeltaEvent(index=0, delta=TextPartDelta(content_delta='您账户'))
PartDeltaEvent(index=0, delta=TextPartDelta(content_delta='的'))
PartDeltaEvent(index=0, delta=TextPartDelta(content_delta='当前余额'))
PartDeltaEvent(index=0, delta=TextPartDelta(content_delta='为 **'))
PartDeltaEvent(index=0, delta=TextPartDelta(content_delta='9.'))
PartDeltaEvent(index=0, delta=TextPartDelta(content_delta='99'))
PartDeltaEvent(index=0, delta=TextPartDelta(content_delta='元**'))
PartDeltaEvent(index=0, delta=TextPartDelta(content_delta='。请问'))
PartDeltaEvent(index=0, delta=TextPartDelta(content_delta='还有什么'))
PartDeltaEvent(index=0, delta=TextPartDelta(content_delta='可以帮'))
PartDeltaEvent(index=0, delta=TextPartDelta(content_delta='您的吗'))
PartDeltaEvent(index=0, delta=TextPartDelta(content_delta='?'))
PartEndEvent(index=0, part=TextPart(content='您好,刘弼仁先生。您账户的当前余额为 **9.99元**。请问还有什么可以帮您的吗?'))
"""
async def run_stream_events( async def run_stream_events(
deps: Any, deps: Any,
@ -106,7 +137,7 @@ async def run_stream_events(
usage: RunUsage, usage: RunUsage,
usage_limits: UsageLimits | None = None, usage_limits: UsageLimits | None = None,
deferred_tool_results: DeferredToolResults | None = None, deferred_tool_results: DeferredToolResults | None = None,
) -> AsyncGenerator[AgentStreamEvent | AgentRunResultEvent[Output] | None,]: ) -> AsyncGenerator[AgentStreamEvent | AgentRunResultEvent[str] | None,]:
""" """
运行并流式输出事件 运行并流式输出事件
""" """
@ -122,28 +153,5 @@ async def run_stream_events(
deferred_tool_results=deferred_tool_results, deferred_tool_results=deferred_tool_results,
) as events: ) as events:
async for event in events: async for event in events:
match event: print(event)
case PartStartEvent(
part=part,
):
match part:
case ToolCallPart(tool_name=tool_name):
if tool_name.startswith("final_result"):
continue
case FunctionToolResultEvent(part):
match part:
case ToolReturnPart(
tool_name=tool_name,
):
if tool_name.startswith("final_result"):
continue
case AgentRunResultEvent(result=result):
match result:
case AgentRunResult(output=output):
match output:
case Output(response=response):
yield AgentRuntimeEvent(content=response)
yield event yield event

Binary file not shown.