当前位置: 首页 > news >正文

A2A Python 教程 - 综合指南

目录

  • • 介绍
  • • 设置环境
  • • 创建项目
  • • 代理技能
  • • 代理卡片
  • • A2A服务器
  • • 与A2A服务器交互
  • • 添加代理功能
  • • 使用本地Ollama模型
  • • 后续步骤

介绍

在本教程中,您将使用Python构建一个简单的echo A2A服务器。这个基础实现将向您展示A2A提供的所有功能。完成本教程后,您将能够使用Ollama或Google的Agent Development Kit添加代理功能。

您将学习:

  • • A2A背后的基本概念
  • • 如何用Python创建A2A服务器
  • • 与A2A服务器交互
  • • 添加训练模型作为代理

设置环境

您需要的工具

  • • 代码编辑器,如Visual Studio Code (VS Code)
  • • 命令提示符,如Terminal (Linux)、iTerm (Mac) 或VS Code中的Terminal

Python环境

我们将使用uv作为包管理器并设置项目。

我们将使用的A2A库需要python >= 3.12,如果您还没有匹配的版本,uv可以安装。我们将使用python 3.12。

检查

运行以下命令,确保您已准备好进入下一步:

echo 'import sys; print(sys.version)' | uv run -

如果您看到类似以下内容,说明您已准备就绪!

3.12.3 (main, Feb 4 2025, 14:48:35) [GCC 13.3.0]

创建项目

首先使用uv创建一个项目。我们将添加--package标志,以便您以后可以添加测试或发布项目:

uv init --package my-project
cd my-project

使用虚拟环境

我们为这个项目创建一个虚拟环境。这只需要做一次:

uv venv .venv

对于这个和将来打开的任何终端窗口,您需要激活这个虚拟环境:

source .venv/bin/activate

如果您使用的是VS Code等代码编辑器,您需要设置Python解释器以便代码补全。在VS Code中,按下Ctrl-Shift-P并选择Python: Select Interpreter。然后选择您的项目my-project,接着选择正确的Python解释器Python 3.12.3 ('.venv':venv) ./.venv/bin/python

现在源代码结构应该类似于:

tree .
.
├── pyproject.toml
├── README.md
├── src
│   └── my-project
│       ├── __init__.py

添加Google-A2A Python库

接下来我们将添加来自Google的A2A Python示例库:

uv add git+https://github.com/google/A2A#subdirectory=samples/python

设置项目结构

现在创建一些我们稍后将使用的文件:

touch src/my_project/agent.py
touch src/my_project/task_manager.py

测试运行

如果一切设置正确,您现在应该能够运行您的应用程序:

uv run my-project

输出应该类似于:

Hello from my-project!

代理技能

代理技能是代理可以执行的一组功能。下面是我们echo代理的技能示例:

{id: "my-project-echo-skill"name: "Echo Tool",description: "Echos the input given",tags: ["echo", "repeater"],examples: ["I will see this echoed back to me"],inputModes: ["text"],outputModes: ["text"]
}

这符合代理卡片的技能部分:

{id: string; // 代理技能的唯一标识符name: string; // 技能的人类可读名称// 技能描述 - 将被客户端或人类用作提示,以理解这个技能的作用description: string;// 描述这个特定技能功能类别的标签词集合// (例如"cooking"、"customer support"、"billing")tags: string[];// 该技能可以执行的示例场景集合// 将被客户端用作提示,以了解如何使用该技能// (例如"I need a recipe for bread")examples?: string[]; // 任务提示示例// 该技能支持的交互模式集合// (如果与默认值不同)inputModes?: string[]; // 支持的输入MIME类型outputModes?: string[]; // 支持的输出MIME类型
}

实现

让我们用代码创建这个代理技能。打开src/my-project/__init__.py并用以下代码替换内容:

import google_a2a
from google_a2a.common.types import AgentSkilldef main():skill = AgentSkill(id="my-project-echo-skill",name="Echo Tool",description="Echos the input given",tags=["echo", "repeater"],examples=["I will see this echoed back to me"],inputModes=["text"],outputModes=["text"],)print(skill)if __name__ == "__main__":main()

测试运行

让我们运行一下:

uv run my-project

输出应该类似于:

id='my-project-echo-skill' name='Echo Tool' description='Echos the input given' tags=['echo', 'repeater'] examples=['I will see this echoed back to me'] inputModes=['text'] outputModes=['text']

代理卡片

现在我们已经定义了技能,可以创建代理卡片了。

远程代理需要以JSON格式发布代理卡片,描述代理的能力和技能,以及认证机制。换句话说,这让世界了解您的代理及如何与之交互。

实现

首先添加一些解析命令行参数的辅助工具。这对稍后启动服务器很有帮助:

uv add click

然后更新我们的代码:

import loggingimport click
from dotenv import load_dotenv
import google_a2a
from google_a2a.common.types import AgentSkill, AgentCapabilities, AgentCardlogging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)@click.command()
@click.option("--host", default="localhost")
@click.option("--port", default=10002)
def main(host, port):skill = AgentSkill(id="my-project-echo-skill",name="Echo Tool",description="Echos the input given",tags=["echo", "repeater"],examples=["I will see this echoed back to me"],inputModes=["text"],outputModes=["text"],)logging.info(skill)if __name__ == "__main__":main()

接下来添加我们的代理卡片:

# ...
def main(host, port):# ...capabilities = AgentCapabilities()agent_card = AgentCard(name="Echo Agent",description="This agent echos the input given",url=f"http://{host}:{port}/",version="0.1.0",defaultInputModes=["text"],defaultOutputModes=["text"],capabilities=capabilities,skills=[skill])logging.info(agent_card)if __name__ == "__main__":main()

测试运行

让我们运行一下:

uv run my-project

输出应该类似于:

INFO:root:name='Echo Agent' description='This agent echos the input given' url='http://localhost:10002/' provider=None version='0.1.0' documentationUrl=None capabilities=AgentCapabilities(streaming=False, pushNotifications=False, stateTransitionHistory=False) authentication=None defaultInputModes=['text'] defaultOutputModes=['text'] skills=[AgentSkill(id='my-project-echo-skill', name='Echo Tool', description='Echos the input given', tags=['echo', 'repeater'], examples=['I will see this echoed back to me'], inputModes=['text'], outputModes=['text'])]

A2A服务器

我们几乎准备好启动服务器了!我们将使用Google-A2A中的A2AServer类,它在底层启动一个uvicorn服务器。

任务管理器

在创建服务器之前,我们需要一个任务管理器来处理传入的请求。

我们将实现InMemoryTaskManager接口,需要实现两个方法:

async def on_send_task(self,request: SendTaskRequest
) -> SendTaskResponse:"""该方法查询或创建代理的任务。调用者将收到恰好一个响应。"""passasync def on_send_task_subscribe(self,request: SendTaskStreamingRequest
) -> AsyncIterable[SendTaskStreamingResponse] | JSONRPCResponse:"""该方法使调用者订阅有关任务的未来更新。调用者将收到一个响应,并通过客户端和服务器之间建立的会话接收订阅更新"""pass

打开src/my_project/task_manager.py并添加以下代码。我们将简单地返回直接回显响应,并立即将任务标记为完成,不需要任何会话或订阅:

from typing import AsyncIterableimport google_a2a
from google_a2a.common.server.task_manager import InMemoryTaskManager
from google_a2a.common.types import (Artifact,JSONRPCResponse,Message,SendTaskRequest,SendTaskResponse,SendTaskStreamingRequest,SendTaskStreamingResponse,Task,TaskState,TaskStatus,TaskStatusUpdateEvent,
)class MyAgentTaskManager(InMemoryTaskManager):def __init__(self):super().__init__()async def on_send_task(self, request: SendTaskRequest) -> SendTaskResponse:# 更新由InMemoryTaskManager存储的任务await self.upsert_task(request.params)task_id = request.params.id# 我们的自定义逻辑,简单地将任务标记为完成# 并返回echo文本received_text = request.params.message.parts[0].texttask = await self._update_task(task_id=task_id,task_state=TaskState.COMPLETED,response_text=f"on_send_task received: {received_text}")# 发送响应return SendTaskResponse(id=request.id, result=task)async def on_send_task_subscribe(self,request: SendTaskStreamingRequest) -> AsyncIterable[SendTaskStreamingResponse] | JSONRPCResponse:passasync def _update_task(self,task_id: str,task_state: TaskState,response_text: str,) -> Task:task = self.tasks[task_id]agent_response_parts = [{"type": "text","text": response_text,}]task.status = TaskStatus(state=task_state,message=Message(role="agent",parts=agent_response_parts,))task.artifacts = [Artifact(parts=agent_response_parts,)]return task

A2A服务器

有了任务管理器,我们现在可以创建服务器了。

打开src/my_project/__init__.py并添加以下代码:

# ...
from google_a2a.common.server import A2AServer
from my_project.task_manager import MyAgentTaskManager
# ...
def main(host, port):# ...task_manager = MyAgentTaskManager()server = A2AServer(agent_card=agent_card,task_manager=task_manager,host=host,port=port,)server.start()

测试运行

让我们运行一下:

uv run my-project

输出应该类似于:

INFO:     Started server process [20506]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://localhost:10002 (Press CTRL+C to quit)

恭喜!您的A2A服务器现在正在运行!

与A2A服务器交互

首先我们将使用Google-A2A的命令行工具向我们的A2A服务器发送请求。尝试之后,我们将编写自己的基本客户端,了解底层工作原理。

使用Google-A2A的命令行工具

在上一步中,您的A2A服务器已经在运行:

# 这应该已经在您的终端中运行
$ uv run my-project
INFO:     Started server process [20538]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://localhost:10002 (Press CTRL+C to quit)

在同一目录中打开新终端:

source .venv/bin/activate
uv run google-a2a-cli --agent http://localhost:10002

注意:这只有在您安装了来自此PR的google-a2a时才有效,因为之前CLI并未公开。

否则,您必须直接检出Google/A2A仓库,导航到samples/python目录并直接运行CLI。

然后通过输入并按Enter发送消息到服务器:

=========  starting a new task ========What do you want to send to the agent? (:q or quit to exit): Hello!

如果一切正常,您将在响应中看到:

"message":{"role":"agent","parts":[{"type":"text","text":"on_send_task received: Hello!"}]}

要退出,输入:q并按Enter。

添加代理功能

现在我们有了一个基本的A2A服务器,让我们添加更多功能。我们将探索A2A如何异步工作和流式响应。

流式传输

这允许客户端订阅服务器并接收多个更新,而不是单个响应。这对于长时间运行的代理任务或需要向客户端流式传输多个Artifacts的情况很有用。

首先声明我们的代理已准备好流式传输。打开src/my_project/__init__.py并更新AgentCapabilities:

# ...
def main(host, port):# ...capabilities = AgentCapabilities(streaming=True)# ...

现在在src/my_project/task_manager.py中,我们需要实现on_send_task_subscribe

import asyncio
# ...
class MyAgentTaskManager(InMemoryTaskManager):# ...async def _stream_3_messages(self, request: SendTaskStreamingRequest):task_id = request.params.idreceived_text = request.params.message.parts[0].texttext_messages = ["one", "two", "three"]for text in text_messages:parts = [{"type": "text","text": f"{received_text}: {text}",}]message = Message(role="agent", parts=parts)is_last = text == text_messages[-1]task_state = TaskState.COMPLETED if is_last else TaskState.WORKINGtask_status = TaskStatus(state=task_state,message=message)task_update_event = TaskStatusUpdateEvent(id=request.params.id,status=task_status,final=is_last,)await self.enqueue_events_for_sse(request.params.id,task_update_event)async def on_send_task_subscribe(self,request: SendTaskStreamingRequest) -> AsyncIterable[SendTaskStreamingResponse] | JSONRPCResponse:# 更新由InMemoryTaskManager存储的任务await self.upsert_task(request.params)task_id = request.params.id# 为此任务创建工作队列sse_event_queue = await self.setup_sse_consumer(task_id=task_id)# 开始为此任务异步工作asyncio.create_task(self._stream_3_messages(request))# 告诉客户端期待未来的流式响应return self.dequeue_events_for_sse(request_id=request.id,task_id=task_id,sse_event_queue=sse_event_queue,)

重启A2A服务器以应用新更改,然后重新运行CLI:

$ uv run google-a2a-cli --agent http://localhost:10002
=========  starting a new task ========What do you want to send to the agent? (:q or quit to exit): Streaming?"status":{"state":"working","message":{"role":"agent","parts":[{"type":"text","text":"Streaming?: one"}]}
"status":{"state":"working","message":{"role":"agent","parts":[{"type":"text","text":"Streaming?: two"}]}
"status":{"state":"completed","message":{"role":"agent","parts":[{"type":"text","text":"Streaming?: three"}]}

有时代理可能需要额外输入。例如,代理可能会询问客户是否希望继续重复3条消息。在这种情况下,代理将以TaskState.INPUT_REQUIRED响应,客户端然后会用相同的task_idsession_id但更新的消息重新发送send_task_streaming,提供代理所需的输入。在服务器端,我们将更新on_send_task_subscribe以处理这种情况:

# ...class MyAgentTaskManager(InMemoryTaskManager):# ...async def _stream_3_messages(self, request: SendTaskStreamingRequest):# ...async for message in messages:# ...# is_last = message == messages[-1] # 删除此行task_state = TaskState.WORKING# ...task_update_event = TaskStatusUpdateEvent(id=request.params.id,status=task_status,final=False,)# ...ask_message = Message(role="agent",parts=[{"type": "text","text": "Would you like more messages? (Y/N)"}])task_update_event = TaskStatusUpdateEvent(id=request.params.id,status=TaskStatus(state=TaskState.INPUT_REQUIRED,message=ask_message),final=True,)await self.enqueue_events_for_sse(request.params.id,task_update_event)# ...async def on_send_task_subscribe(self,request: SendTaskStreamingRequest) -> AsyncIterable[SendTaskStreamingResponse] | JSONRPCResponse:task_id = request.params.idis_new_task = task_id in self.tasks# 更新由InMemoryTaskManager存储的任务await self.upsert_task(request.params)received_text = request.params.message.parts[0].textsse_event_queue = await self.setup_sse_consumer(task_id=task_id)if not is_new_task and received_text == "N":task_update_event = TaskStatusUpdateEvent(id=request.params.id,status=TaskStatus(state=TaskState.COMPLETED,message=Message(role="agent",parts=[{"type": "text","text": "All done!"}])),final=True,)await self.enqueue_events_for_sse(request.params.id,task_update_event,)else:asyncio.create_task(self._stream_3_messages(request))return self.dequeue_events_for_sse(request_id=request.id,task_id=task_id,sse_event_queue=sse_event_queue,)

重启服务器并运行CLI后,我们可以看到任务将继续运行,直到我们告诉代理N

$ uv run google-a2a-cli --agent http://localhost:10002
=========  starting a new task ========What do you want to send to the agent? (:q or quit to exit): Streaming?"status":{"state":"working","message":{"role":"agent","parts":[{"type":"text","text":"Streaming?: one"}]}
"status":{"state":"working","message":{"role":"agent","parts":[{"type":"text","text":"Streaming?: two"}]}
"status":{"state":"working","message":{"role":"agent","parts":[{"type":"text","text":"Streaming?: three"}]}
"status":{"state":"input-required","message":{"role":"agent","parts":[{"type":"text","text":"Would you like more messages? (Y/N)"}]}What do you want to send to the agent? (:q or quit to exit): N"status":{"state":"completed","message":{"role":"agent","parts":[{"type":"text","text":"All done!"}]}

恭喜!您现在有了一个能够异步执行工作并在需要时向用户请求输入的代理。

使用本地Ollama模型

现在到了激动人心的部分。我们将为A2A服务器添加AI功能。

在本教程中,我们将设置本地Ollama模型并将其与A2A服务器集成。

要求

我们将安装ollamalangchain,并下载支持MCP工具的ollama模型(用于未来教程)。

  1. 1. 下载ollama
  2. 2. 运行ollama服务器:
# 注意:如果ollama已在运行,您可能会收到错误,如
# Error: listen tcp 127.0.0.1:11434: bind: address already in use
# 在Linux上可以运行systemctl stop ollama停止ollama
ollama serve
  1. 3. 从此列表下载模型。我们将使用qwq,因为它支持tools(如其标签所示)并在24GB显卡上运行:
ollama pull qwq
  1. 4. 安装langchain
uv add langchain langchain-ollama langgraph

现在ollama设置好了,我们可以开始将其集成到A2A服务器中。

将Ollama集成到A2A服务器

首先打开src/my_project/__init__.py

# ...@click.command()
@click.option("--host", default="localhost")
@click.option("--port", default=10002)
@click.option("--ollama-host", default="http://127.0.0.1:11434")
@click.option("--ollama-model", default=None)
def main(host, port, ollama_host, ollama_model):# ...capabilities = AgentCapabilities(streaming=False # 我们将流式功能作为读者的练习)# ...task_manager = MyAgentTaskManager(ollama_host=ollama_host,ollama_model=ollama_model,)# ..

现在在src/my_project/agent.py中添加AI功能:

from langchain_ollama import ChatOllama
from langgraph.prebuilt import create_react_agent
from langgraph.graph.graph import CompiledGraphdef create_ollama_agent(ollama_base_url: str, ollama_model: str):ollama_chat_llm = ChatOllama(base_url=ollama_base_url,model=ollama_model,temperature=0.2)agent = create_react_agent(ollama_chat_llm, tools=[])return agentasync def run_ollama(ollama_agent: CompiledGraph, prompt: str):agent_response = await ollama_agent.ainvoke({"messages": prompt })message = agent_response["messages"][-1].contentreturn str(message)

最后从src/my_project/task_manager.py调用我们的ollama代理:

# ...
from my_project.agent import create_ollama_agent, run_ollamaclass MyAgentTaskManager(InMemoryTaskManager):def __init__(self,ollama_host: str,ollama_model: typing.Union[None, str]):super().__init__()if ollama_model is not None:self.ollama_agent = create_ollama_agent(ollama_base_url=ollama_host,ollama_model=ollama_model)else:self.ollama_agent = Noneasync def on_send_task(self, request: SendTaskRequest) -> SendTaskResponse:# ...received_text = request.params.message.parts[0].textresponse_text = f"on_send_task received: {received_text}"if self.ollama_agent is not None:response_text = await run_ollama(ollama_agent=self.ollama_agent, prompt=received_text)task = await self._update_task(task_id=task_id,task_state=TaskState.COMPLETED,response_text=response_text)# 发送响应return SendTaskResponse(id=request.id, result=task)# ...

让我们测试一下!

首先重新运行A2A服务器,将qwq替换为您下载的ollama模型:

uv run my-project --ollama-host http://127.0.0.1:11434 --ollama-model qwq

然后重新运行CLI:

uv run google-a2a-cli --agent http://localhost:10002

注意,如果您使用大模型,加载可能需要一段时间。CLI可能会超时。在这种情况下,一旦ollama服务器完成模型加载,请重新运行CLI。

您应该看到类似于以下内容:

=========  starting a new task ========What do you want to send to the agent? (:q or quit to exit): hey"message":{"role":"agent","parts":[{"type":"text","text":"<think>\nOkay, the user said \"hey\". That's pretty casual. I should respond in a friendly way. Maybe ask how I can help them today. Keep it open-ended so they feel comfortable sharing what they need. Let me make sure my tone is positive and approachable. Alright, something like, \"Hey there! How can I assist you today?\" Yeah, that sounds good.\n</think>\n\nHey there! How can I assist you today? 😊"}]}

恭喜!您现在有了一个使用AI模型生成响应的A2A服务器!

了解更多:https://a2aprotocol.ai/blog/python-a2a-tutorial

相关文章:

A2A Python 教程 - 综合指南

目录 • 介绍• 设置环境• 创建项目• 代理技能• 代理卡片• A2A服务器• 与A2A服务器交互• 添加代理功能• 使用本地Ollama模型• 后续步骤 介绍 在本教程中&#xff0c;您将使用Python构建一个简单的echo A2A服务器。这个基础实现将向您展示A2A提供的所有功能。完成本教…...

Linux:信号(一)

1. 信号是什么 信号的概念 Linux中信号(Signal)是进程间通信的一种基本机制&#xff0c;用于通知进程发生了某种事件或异常。信号是异步的&#xff0c;可能由操作系统、其他进程或进程自身触发。 kill -l 指令查看所有的信号 上面的SIGHUP、SIGINT本质就是define宏定义&…...

数据中台笔记01

一、数据中台大纲 1.1、 课程概述 1)数据中台诞生的背景和历史 核心价值:解决企业"重复造轮子"问题,通过统一平台实现多业务数据关联。典型问题:数据质量监控、血缘关系管理等场景的标准化处理。行业需求:阿里等企业实践验证了中台模式在数据治理中的必要性。2…...

[面试]SoC验证工程师面试常见问题(四)

SoC验证工程师面试常见问题(四) 摘要:作为 SoC 验证工程师,面试中可能会被问及与片内互联技术和具体协议(如 PCIe)相关的问题。这些问题通常旨在评估你对 SoC 架构、互联协议的理解以及验证这些技术的实践经验。以下是针对片内互联技术和 PCIe 协议可能提出的问题…...

流水线相关计算【计算机组成与体系结构】

一些概念 流水线周期 &#xff08;T_cycle&#xff09; 最长操作阶段耗时&#xff0c;决定整体节奏。若取指2ns&#xff0c;分析3ns&#xff0c;执行1ns&#xff0c;则流水线周期3ns&#xff08;取最大值&#xff09;如《笑傲江湖》中“独孤九剑”的九式&#xff0c;最慢一式&a…...

学习笔记:Qlib 量化投资平台框架 — OTHER COMPONENTS/FEATURES/TOPICS

学习笔记&#xff1a;Qlib 量化投资平台框架 — OTHER COMPONENTS/FEATURES/TOPICS Qlib 是微软亚洲研究院开源的一个面向人工智能的量化投资平台&#xff0c;旨在实现人工智能技术在量化投资中的潜力&#xff0c;赋能研究&#xff0c;并创造价值&#xff0c;从探索想法到实施生…...

值此五一劳动节来临之际,

值此五一劳动节来临之际&#xff0c;谨向全体员工致以节日的问候与诚挚的感谢&#xff01;正是你们的敬业与奋斗&#xff0c;成就了今天的成绩。愿大家节日愉快&#xff0c;阖家幸福&#xff0c;身体健康&#xff01; #北京先智先行科技有限公司 #先知AI #节日快乐...

深入理解C++构造函数:从入门到实践

1. 默认构造函数&#xff1a;对象的"出厂设置" 什么是默认构造函数&#xff1f; 没有参数的构造函数当你没有定义任何构造函数时&#xff0c;编译器自动生成用于创建对象时不传递参数的情况 class Smartphone { public:// 成员初始化方法一: 函数体内初始化Smartp…...

【安装指南】DevC++的安装和使用(超级详细)

目录 一、DevC 介绍 二、DevC 下载与安装 2.1 DevC 的下载方式 2.2 DevC 的安装 三、代码编写 3.1 新建源文件 3.1.1 步骤演示 3.1.2 快捷键指南 3.2 新建项目 3.3 多文件的效果演示 3.3.1 方式一 3.3.2 方式二 四、项目中的文件介绍 五、调试的使用 5.1 设置断…...

计算机组成原理实验(6) 微程序控制单元实验

实验六 微程序控制单元实验 一、实验目的 1、熟悉微程序控制器的原理 2、掌握微程序编制、写入并观察运行状态 二、实验要求 按照实验步骤完成实验项目&#xff0c;掌握设置微地址、微指令输出的方法 三、实验说明 3.1 微程序控制单元的构成&#xff1a;&#xff08;…...

从文本到向量:揭秘词向量转换的奥秘与实践

从文本到向量&#xff1a;揭秘词向量转换的奥秘与实践 在自然语言处理&#xff08;NLP&#xff09;的世界里&#xff0c;计算机处理的是数字和向量&#xff0c;而人类交流使用的是文本语言。如何让计算机理解文本语义并进行分析处理呢&#xff1f;词向量转换便是其中的关键一环…...

在 Windows 中安装 Pynini 的记录

#工作记录 概述 Pynini 是一个用于加权有限状态文法编译的 Python 库&#xff0c;广泛应用于自然语言处理&#xff08;NLP&#xff09;领域。以下记录旨在用于回顾和帮助大家在 Windows 系统中安装 Pynini。 安装思路&#xff1a; 优先用conda虚拟环境 或 在python3.12的vir…...

美丽天天秒链动2+1源码(新零售商城搭建)

什么是链动21模式&#xff1f; 链动21主要是建立团队模式&#xff0c;同时快速提升销量。是目前成员中速度最快的裂变模式。链动21模式合理合规&#xff0c;同时激励用户 公司的利润分享机制&#xff0c;让您在享受购物折扣的同时&#xff0c;也能促进并获得客观收益。 链动21模…...

目标检测中的损失函数(三) | SIoU WIoUv1 WIoUv2 WIoUv3

&#x1f680;该系列将会持续整理和更新BBR相关的问题&#xff0c;如有错误和不足恳请大家指正&#xff0c;欢迎讨论&#xff01;&#xff01;&#xff01; SCYLLA-IoU&#xff08;SIoU&#xff09;来自挂在2022年arxiv上的文章&#xff1a;《SIoU Loss: More Powerful Learnin…...

51、【OS】【Nuttx】【OSTest】参数解析:参数处理过程

背景 接上两篇 blog&#xff1a; 49、【OS】【Nuttx】【OSTest】参数解析&#xff1a;测试项 50、【OS】【Nuttx】【OSTest】参数解析&#xff1a;函数定义 getopt_common 来看 getopt_common 的实现过程 首先校验输入参数是否为空&#xff0c;如果没有输入参数&#xff0…...

python实现基于Windows系统计算器程序

Python实现Windows系统计算器程序&#xff08;含高级功能&#xff09; 下面我将介绍如何使用Python创建一个功能完整的Windows风格计算器程序&#xff0c;包含基本运算和高级数学功能。 1. 使用Tkinter实现基础计算器 import tkinter as tk from tkinter import ttk import …...

日语学习-日语知识点小记-构建基础-JLPT-N4阶段(14):かもしれません (~た・~ない)ほうがいいです

日语学习-日语知识点小记-构建基础-JLPT-N4阶段&#xff08;1&#xff14;&#xff09;&#xff1a;かもしれません &&#xff08;&#xff5e;た・&#xff5e;ない&#xff09;ほうがいいです 1、前言&#xff08;1&#xff09;情况说明&#xff08;2&#xff09;工程师…...

AI Rack架构高速互连的挑战:损耗设计与信号完整性的设计框架

在AI驱动的时代&#xff0c;系统设计已经从单一PCB的视角&#xff0c;逐步转向以整个rack为单位来考量。 对于信号完整性而言&#xff0c;焦点以不再局限于单一PCB上的损耗&#xff0c;而是扩展到芯片与芯片之间的端到端互连损耗&#xff08;end-to-end interconnect loss&…...

React useCallback函数

应用场景&#xff1a;父组件向子组件传递函数类型的props时...

【CTFer成长之路】XSS的魔力

XSS闯关 level1 访问url&#xff1a; http://c884a553-d874-4514-9c32-c19c7d7b6e1c.node3.buuoj.cn/level1?usernamexss 因为是xss&#xff0c;所以对传参进行测试&#xff0c;修改?username1&#xff0c;进行访问 会发现username参数传入什么&#xff0c;welcome之后就…...

多模态RAG演进-MRAG1.0->MRAG2.0->MRAG3.0

MRAG1.0 MRAG1.0是MRAG框架的初始阶段&#xff0c;通常被称为“伪MRAG”。它是对RAG范式的简单扩展&#xff0c;支持多模态数据。MRAG1.0通过利用现有的基于文本的检索和生成机制&#xff0c;实现了从RAG到MRAG的平稳过渡。 MRAG1.0的架构包括三个关键组件&#xff1a; 文档解…...

超预期!淘宝闪购提前开放全国全量,联合饿了么扭转外卖战局

饿了么由守转攻。 作者|景行 编辑|杨舟 淘宝饿了么&#xff0c;终于落子&#xff0c;“淘宝闪购”&#xff0c;横空出世&#xff0c;仅仅2天&#xff0c;业务加速。 4月30日上午&#xff0c;当外卖战场陷入沉寂时&#xff0c;淘宝宣布将即时零售业务“小时达”升级为“淘宝闪…...

Proxmox VE 8.4 显卡直通完整指南:NVIDIA 2080 Ti 实战

背景&#xff1a; PCIe Passthrough 技术允许虚拟机直接访问物理GPU设备&#xff0c;绕过宿主机系统&#xff0c;从而获得接近原生性能的图形处理能力. 参照&#xff1a;从Proxmox VE开始&#xff1a;安装与配置指南。在R740服务器完成了proxmox的安装&#xff0c;并且安装了一…...

算法技巧——打表

什么是打表&#xff1f; 打表&#xff0c;是一个信息学专用术语&#xff0c;意指对一些题目&#xff0c;通过打表技巧获得一个有序表或常量表&#xff0c;来执行程序某一部分&#xff0c;优化时间复杂度。这种算法也可用于在对某种题目没有最优解法时&#xff0c;用来得到分数的…...

JavaScript基础-逻辑运算符

在JavaScript编程中&#xff0c;逻辑运算符用于判断表达式的真假&#xff0c;并根据结果执行特定的操作。掌握逻辑运算符是理解条件控制结构的关键之一。本文将详细介绍JavaScript中的三种主要逻辑运算符&#xff1a;&&&#xff08;逻辑与&#xff09;、||&#xff08;…...

P20:Inception v3算法实战与解析

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 使用InceptionV3实现天气识别 一、模型结构 Inception v3是Google团队在2015年提出的第三代Inception模型&#xff0c;属于卷积神经网络&#xff08;CNN&…...

C++ - 数据容器之 list(创建与初始化、元素访问、容量判断、元素遍历、添加元素、删除元素)

一、创建与初始化 引入 <list> 并使用 std 命名空间 #include <list>using namespace std;创建一个空 list list<int> my_list;创建一个包含 5 个元素&#xff0c;每个元素初始化为 0 的 list list<int> my_list(5);创建一个包含 5 个元素&#xf…...

deepseek 技巧整理

1、导出word 和excel 功能&#xff0c;在使用以下提示词。 请帮我列出减肥期间可以吃的水果&#xff0c;并分析该水果含有的营养元素&#xff0c;以表格的形式星现。1.要以html的方式输出 2.要可以直接运行 3.页面要提供可以直接下载word和excel功能...

柔性PZT压电薄膜多维力传感器在微创手术机器人的应用

随着医疗技术的迅速发展&#xff0c;微创手术机器人正在成为外科手术的重要助手。与传统开放式手术相比&#xff0c;微创手术创伤小、恢复快、感染率低&#xff0c;对手术器械的精细操控性和感知能力提出了更高要求。多维力传感器作为机器人“触觉”的核心部件&#xff0c;对提…...

Java学习手册:Spring Boot 自动配置与快速开发

一、Spring Boot 自动配置概述 Spring Boot 的自动配置是其核心特性之一&#xff0c;它能够根据项目的依赖和配置自动地进行 Spring 应用程序的配置。自动配置的工作流程如下&#xff1a; SpringBootApplication 注解 &#xff1a;这是自动配置的起点&#xff0c;它是一个组合…...

ValueError: expected sequence of length 8 at dim 2 (got 0)

问题描述 在PyCharm中使用强化学习运行Python代码时报错ValueError: expected sequence of length 8 at dim 2 (got 0)。 问题原因 实际上原因就是gym中的env对象的reset、step等方法的返回值作了改动 解决方法 1、第一步&#xff1a; 将代码块中的&#xff08;记得改的需…...

AI赋能新媒体运营:效率提升与能力突破实战指南

AI赋能新媒体运营&#xff1a;效率提升与能力突破实战指南 在信息爆炸的新媒体时代&#xff0c;运营人员面临着内容产出压力大、数据分析复杂、用户互动需求高等多重挑战。AI技术的迅猛发展为新媒体运营带来了革命性的变革可能。本文将为您揭示如何利用AI工具提升工作效率、培…...

单词规律(简单)

思路和同构字符串那道题一样。、但是这道题要注意的地方就是&#xff0c;检查 pattern 和 s 的单词数量是否一致以及在进行字符串比较的时候应该用equals来进行比较&#xff0c;而不能用“&#xff01;”&#xff0c;“&#xff01;”比较的是对象引用而非内容。 class Soluti…...

QGraphicsView QGraphicsScene QGraphicsItem 的关系

在Qt的图形视图框架中&#xff0c;QGraphicsView、QGraphicsScene和QGraphicsItem 三者协同工作&#xff0c;构成一个分层的结构&#xff0c;用于高效管理和显示复杂的图形界面。以下是它们的关系和职责的详细说明&#xff1a; 1. 核心角色 类名职责类比QGraphicsItem场景中的…...

re题(52)BUUCTF-[FlareOn5]Minesweeper Championship Registration

BUUCTF在线评测 jadx打开if条件就是flag...

c++环境和vscode常用的一些有用插件

环境 WSL需要安装cmake 编译器g14 应该是包含了所有std:c23把好像包含部分c26 vscode 需要插件cmake vscode clangd 方便提示吧 File Watch 插件目的在保存.h/.cpp文件时候自动执行vscode 的cmake吧 error lens 方便每次显示错误和警告的提示懒得每次点击去看错误 Edit Sugge…...

UE自动索敌插件Target System Component

https://www.fab.com/zh-cn/listings/9088334d-3bde-4e10-a937-baeb780f880f ​ 一个完全用 C 编写的 UE插件&#xff0c;添加了对简单相机锁定/瞄准系统的支持。它最初​​在蓝图中开发和测试&#xff0c;然后转换并重写为 C 模块和插件。 特征&#xff1a; 可通过一组可在…...

从括号匹配看栈:数据结构入门的实战与原理

在计算机科学的世界里&#xff0c;数据结构是程序员的 “瑞士军刀”&#xff0c;不同的数据结构适用于不同的场景&#xff0c;能高效解决各类问题。其中&#xff0c;栈作为一种简单却强大的数据结构&#xff0c;在很多实际应用中发挥着关键作用。今天&#xff0c;我们就通过一个…...

ReLU函数及其Python实现

ReLU函数及其Python实现 文章目录 ReLU函数及其Python实现1. ReLU函数定义2. Python实现3. 在深度学习中的应用总结 1. ReLU函数定义 ReLU&#xff08;Rectified Linear Unit&#xff0c;修正线性单元&#xff09;函数是深度学习中常用的激活函数之一。它的定义非常简单&#…...

Rain World 雨世界 [DLC 解锁] [Steam Epic] [Windows SteamOS]

Rain World 雨世界 [DLC 解锁] [Steam & Epic] [Windows & SteamOS] 需要有游戏正版基础本体&#xff0c;安装路径不能带有中文&#xff0c;或其它非常规拉丁字符&#xff1b; DLC 版本 至最新全部 DLC 后续可能无法及时更新文章&#xff0c;具体最新版本见下载文件说明…...

n8n 工作流画布上下左右移动的操作方法

n8n 工作流画布上下左右移动的操作方法 1. n8n 工作流画布上下移动2. n8n 工作流画布左右移动3. n8n 工作流画布扩大和缩小4. n8n 工作流画布缩放到适合 1. n8n 工作流画布上下移动 鼠标滚轮向上滚动是向上移动鼠标滚轮向下滚动是向下移动 2. n8n 工作流画布左右移动 按照Shi…...

Linux 常用命令合集

一、用户权限管理 切换管理员身份 sudo su&#xff1a;普通用户临时获取 root 权限&#xff0c;需输入当前用户密码。管理员提示符&#xff1a;root主机名:路径#。退出管理员&#xff1a;exit&#xff0c;返回普通用户状态。 以管理员身份执行命令 sudo 命令 参数&#xff1a;…...

B站Michale_ee——ESP32_IDF SDK——FreeRTOS_7 流数据缓冲区、消息缓冲区

一、Stream Buffer流数据缓冲区 流数据缓冲区用来处理像音频之类的流数据&#xff1b; 1.API简介 &#xff08;1&#xff09;创建流数据缓冲区 &#xff08;2&#xff09;向流数据缓冲区中发送数据 &#xff08;3&#xff09;从流数据缓冲区中接收数据 2.示例代码及运行结果…...

HCL(HashiCorp Configuration Language)是一种结构化配置语言

HCL&#xff08;HashiCorp Configuration Language&#xff09;是一种结构化配置语言&#xff0c;语法简洁且可读性强&#xff0c;广泛用于 Docker Buildx Bake、Terraform、Nomad 等工具的配置。以下是其核心语法规则和示例&#xff1a; 1. 基础结构 HCL 使用 块&#xff08;…...

k9s 一个基于终端的 Kubernetes 集群管理工具(TUI)

k9s 是一个基于终端的 Kubernetes 集群管理工具&#xff08;TUI&#xff09;&#xff0c;通过快捷键和交互式命令快速操作资源。以下是其核心用法和常见场景&#xff1a; 1. 基本命令 启动 k9s k9s # 默认连接当前 kubeconfig 配置的集群k9s -n <namespace> # 指定命…...

高等数学-第七版-下册 选做记录 习题10-1

1. 4. 5....

DBeaver连接人大金仓数据库V9

1、官网下载驱动jdbc 打开官网地址&#xff0c;找到下面的V9R1-JDBC&#xff0c;点击后面的下载即可&#xff0c;保存到本地 2、解压最新版的驱动程序 3、把***_JDBC文件夹内的驱动程序复制到DBeaver安装目录下的plugins文件夹里 4、打开dbeaver程序&#xff0c;增加kingbase…...

跟韩学AiOps系列之2025学MySQL系列_如何在MySQL中开启和提交事务?!

跟韩学AiOps系列之2025学MySQL系列_如何在MySQL中开启和提交事务&#xff1f;! 文章目录 一、事务的基本操作1. 开启事务2. 执行事务内操作3. 提交事务4. 回滚事务 二、验证示例&#xff08;适用于 MySQL 5.7&#xff09;步骤 1&#xff1a;准备测试表和数据步骤 2&#xff1a…...

【KWDB 创作者计划】利用KWDB解决工业物联网场景中的海量数据管理难题的思考

利用KWDB解决工业物联网场景中的海量数据管理难题 一、什么是KWDB&#xff1f;二、工业物联网场景中的数据管理痛点2.1 数据量大且增长迅速2.2 数据多样性2.3 实时性需求2.4 数据分析复杂性 三、KWDB 的技术优势与架构解读3.1 时间序列数据的高效管理3.2 高吞吐写入性能3.3 灵活…...

分享国产AI工作流集成数据库完成业务处理

在现代企业应用中&#xff0c;业务流程的自动化和数据管理是提高效率的关键。Taskflow 作为一个强大的任务流管理工具&#xff0c;可以通过集成数据库实现复杂业务逻辑的处理。本文将分享如何利用 Taskflow 集成数据库&#xff0c;优化业务流程&#xff0c;并展示一个实际案例。…...