在构建和部署服务器机器人时,Poe 提供了一系列功能强大的指南,帮助开发者实现特定的功能。本文将深入探讨如何利用这些功能来提升你的机器人的能力,确保你能充分发挥 Poe 平台的潜力。
🌐 访问其他 Poe 机器人
Poe 的机器人查询 API 允许开发者调用其他 Poe 上的机器人,这包括 Poe 自己创建的机器人(如 GPT-3.5-Turbo 和 Claude-Instant)以及其他创作者开发的机器人。通过这种方式,创作者无需担心大模型的费用,每个用户消息下,服务器机器人的创建者最多可以调用十次其他机器人。
要声明依赖关系,你需要在你的 PoeBot
类中使用 settings
端点。以下是一个示例:
async def get_settings(self, setting: fp.SettingsRequest) -> fp.SettingsResponse: return fp.SettingsResponse(server_bot_dependencies={"GPT-3.5-Turbo": 1})
在你的 get_response
处理函数中,你可以使用 stream_request
函数来调用任何你想要的机器人。以下是将用户查询转发给 GPT-3.5-Turbo 并返回结果的示例:
async def get_response( self, request: fp.QueryRequest ) -> AsyncIterable[fp.PartialResponse]: async for msg in fp.stream_request( request, "GPT-3.5-Turbo", request.access_key ): yield msg
🔧 使用 OpenAI 函数调用
Poe API 允许你在访问 OpenAI 模型时使用函数调用功能。要使用此功能,你只需提供一个工具列表,其中包含描述你的函数的对象,以及一个可执行函数列表,该列表对应于工具列表。以下是一个示例:
def get_current_weather(location, unit="fahrenheit"): """获取给定位置的当前天气""" # 实现天气获取逻辑
要实现此功能,你需要在 get_settings
中设置依赖关系,以允许两次调用 OpenAI 模型:
async def get_settings(self, setting: fp.SettingsRequest) -> fp.SettingsResponse: return fp.SettingsResponse(server_bot_dependencies={"GPT-3.5-Turbo": 2})
然后在你的 get_response
中调用 OpenAI 模型:
async def get_response( self, request: fp.QueryRequest ) -> AsyncIterable[fp.PartialResponse]: async for msg in fp.stream_request( request, "GPT-3.5-Turbo", request.access_key, tools=tools, tool_executables=tools_executables, ): yield msg
🖼️ 在响应中渲染图像
Poe API 允许你在机器人的响应中嵌入图像,使用 Markdown 语法。以下示例展示了一个返回静态图像的响应:
class SampleImageResponseBot(fp.PoeBot): async def get_response( self, request: fp.QueryRequest ) -> AsyncIterable[fp.PartialResponse]: yield fp.PartialResponse(text=f"This is a test image. ![leopard]({IMAGE_URL})")
💻 渲染 HTML 在响应中
如果机器人的 Markdown 输出包含 HTML 代码块,代码块和预览都会被渲染。例如,以下 Markdown 消息:
```html <html> <h1>hello world</h1> </html>
将渲染为 HTML。 ## 📤 启用文件上传功能 Poe API 允许你的机器人接收文件作为输入。启用文件上传功能非常简单,只需在 `get_settings` 中设置适当的参数: ```python async def get_settings(self, setting: fp.SettingsRequest) -> fp.SettingsResponse: return fp.SettingsResponse( allow_attachments=True, expand_text_attachments=True, enable_image_comprehension=True )
📥 发送文件作为响应
Poe API 允许你在机器人的响应中发送附件。以下是一个示例,展示如何将用户输入写入文本文件并将其附加在响应中:
class AttachmentOutputDemoBot(fp.PoeBot): async def get_response( self, request: fp.QueryRequest ) -> AsyncIterable[fp.PartialResponse]: await self.post_message_attachment( message_id=request.message_id, file_data=request.query[-1].content, filename="dummy.txt" ) yield fp.PartialResponse(text=f"Attached a text file containing your last message.")
🌟 设置介绍消息
为了为用户提供友好的介绍信息,你可以在 get_settings
中设置 introduction_message
参数:
async def get_settings(self, setting: fp.SettingsRequest) -> fp.SettingsResponse: return fp.SettingsResponse( introduction_message="欢迎来到测验机器人。请提供您希望我测验的主题。" )
🤖 多机器人支持
Poe 客户端支持在同一聊天中 @提及其他机器人。要启用此功能,你需要在机器人的设置中启用 enable_multi_bot_chat_prompting
参数。
🔄 更新机器人设置
每个 Poe 机器人的设置控制其行为。例如,server_bot_dependencies
允许你调用其他 Poe 机器人。在修改设置后,确保同步这些更新:
fp.sync_bot_settings(bot_name, access_key)
🌐 访问 HTTP 请求信息
如果你需要访问特定的 HTTP 请求信息,Poe API 允许通过 fp.RequestContext
对象访问请求信息:
class HttpRequestBot(fp.PoeBot): async def get_response_with_context( self, request: fp.QueryRequest, context: fp.RequestContext ) -> AsyncIterable[fp.PartialResponse]: request_url = context.http_request.url query_params = context.http_request.query_params yield fp.PartialResponse( text=f"The request url is: {request_url}, query params are: {query_params}" )
📋 程序化访问你的服务器机器人
Poe 提供了一个辅助函数,方便你在测试和调试时访问机器人查询 API。通过以下方式访问:
import fastapi_poe as fp async def get_responses(api_key, messages): async for partial in fp.get_bot_response(messages=messages, bot_name="GPT-3.5-Turbo", api_key=api_key): print(partial)
🤖 推荐的机器人设置:提升用户体验的最佳实践
在构建和优化你的机器人时,设置适当的参数对于提升用户体验至关重要。以下是一些推荐的设置,帮助你的机器人在 Poe 平台上运行得更顺畅、更智能。
🌟 启用多机器人聊天提示
enable_multi_bot_chat_prompting=True
通过启用这一设置,机器人将在多个机器人同时参与对话时自动应用提示。这确保了机器人能够适当地响应用户输入,尤其是在复杂的对话环境中。建议所有机器人都启用此功能,前提是它们不依赖于特定格式的对话历史。
⚠️ 注意:在某些情况下,这可能导致连续出现两个用户消息。如果你希望自动处理这种情况,可以启用
enforce_author_role_alternation
,以确保角色交替。
📎 允许附件
allow_attachments=True
启用此设置后,用户将能够向你的机器人发送文件。这对于需要用户上传文件以获取帮助的文本类机器人尤其重要。对于文本附件,默认情况下会解析文本内容并将其包含在提示中(因为 expand_text_attachments=True
默认开启)。
🖼️ 启用图像理解
enable_image_comprehension=True
此设置允许机器人将图像转换为文本提示,使用视觉模型来处理上传的图像。对于尚未支持多模态的模型,这个功能是必不可少的。启用此功能能够使你的机器人在处理用户提供的图像时更具智能。
📚 fastapi_poe: Python API 参考文献
在构建和部署机器人的过程中,使用 fastapi_poe
库可以帮助你轻松实现与 Poe 平台的集成。本文将深入探讨 fastapi_poe
的主要类和方法,以便你能够更好地利用这一强大的工具。
🤖 PoeBot 类
fp.PoeBot
是定义你机器人行为的核心类。创建 PoeBot
类后,你可以将其传递给 make_app
来创建一个 FastAPI 应用程序,为你的机器人提供服务。
主要参数:
path (str = “/”): 你的机器人服务的路径。默认设置为
/
,但你可以根据需要进行调整。这在希望从同一服务器提供多个机器人的情况下特别有用。access_key (Optional[str] = None): 机器人访问密钥,用于验证请求是否来自受信任的来源。此密钥应与在 Poe 上集成机器人时提供的密钥相同。
should_insert_attachment_messages (bool = True): 标志,用于决定是否解析附件中的内容并将其作为消息插入对话中。默认设置为 True,建议保留此设置,以使机器人能够理解用户上传的附件。
例子:
class MyBot(fp.PoeBot): async def get_response(self, request: fp.QueryRequest) -> AsyncIterable[fp.PartialResponse]: yield fp.PartialResponse(text="Hello, world!")
📩 处理用户查询
PoeBot.get_response
你可以重写此方法,以定义机器人对用户查询的响应。
Parameters:
request (QueryRequest)
: 表示来自 Poe 的聊天响应请求的对象。
Returns:
AsyncIterable[PartialResponse]
,表示你的响应对象。
例子:
async def get_response(self, request: fp.QueryRequest) -> AsyncIterable[fp.PartialResponse]: last_message = request.query[-1].content yield fp.PartialResponse(text=f"You said: {last_message}")
🔄 处理设置请求
PoeBot.get_settings
重写此方法以定义机器人的设置。
Parameters:
setting (SettingsRequest)
: 表示设置请求的对象。
Returns:
SettingsResponse
,表示你希望用于机器人的设置。
📝 反馈与错误处理
PoeBot.on_feedback
和 PoeBot.on_error
你可以重写这些方法来记录来自用户的反馈或 Poe 服务器的错误。
- Parameters:
feedback_request (ReportFeedbackRequest)
或error_request (ReportErrorRequest)
: 分别表示用户反馈或错误请求的对象。
📂 附件处理
PoeBot.post_message_attachment
用于在机器人响应中输出附件。
- Parameters:
message_id (Identifier)
: 当前QueryRequest
对象相关的消息 ID。access_key (str)
: 用于确保文件上传请求来自授权来源的访问密钥。download_url (Optional[str] = None)
: 要附加到消息的文件的 URL。file_data (Optional[Union[bytes, BinaryIO]] = None)
: 要上传的文件内容。
🏗️ 创建应用
fp.make_app
创建你的机器人应用对象。
- Parameters:
bot (Union[PoeBot, Sequence[PoeBot]])
: 一个机器人对象或多个机器人的列表。access_key (str = "")
: 访问密钥。allow_without_key (bool = False)
: 如果为 True,服务器将启动,即使没有提供访问密钥。
🚀 运行你的机器人
fp.run
使用 FastAPI 应用程序为你的 Poe 机器人提供服务。此函数应在本地运行机器人时使用。
例子:
if __name__ == "__main__": fp.run(app)
🌐 访问其他机器人的 API
fp.stream_request
允许你使用 Poe 的其他机器人进行推理,响应用户消息。
- Parameters:
request (QueryRequest)
: 表示来自 Poe 的查询请求。
📩 发送最终响应
fp.get_final_response
一个辅助函数,用于等待所有 token,并在返回之前合并完整响应。
📦 重要数据结构
- QueryRequest: 表示查询请求的参数。
- ProtocolMessage: Poe 协议中使用的消息。
- PartialResponse: 部分响应的表示形式。
- ErrorResponse: 用于从机器人报告错误的响应。
📜 Poe 协议规范
Poe 是一个与基于 AI 的机器人互动的平台,提供对流行聊天机器人的访问,诸如 OpenAI 的 GPT-3.5-Turbo 和 Anthropic 的 Claude,同时也允许创作者通过实现以下协议来创建自己的机器人。
🏗️ 简介
本规范提供了一种从任何可通过网络访问的服务运行自定义机器人的方法,Poe 应用可以使用这些服务。Poe 用户会向 Poe 服务器发送请求,后者会使用该规范将请求发送到机器人服务器。当机器人服务器响应时,Poe 会将响应显示给用户。
📚 术语
- Poe 服务器:由 Poe 运行,接收客户端请求,将其转换为对机器人服务器的请求,并将响应流式传输回 Poe 客户端。
- 机器人服务器:由创作者运行,响应 Poe 服务器的请求。响应最终将在用户的 Poe 客户端中显示。
🔑 身份标识符
协议对某些请求字段使用标识符,这些标识符被标记为“identifier”。标识符是全局唯一的,由 1 到 3 个小写 ASCII 字符组成,后跟一个连字符,然后是 32 个小写字母数字 ASCII 字符或“=”字符。
例如,符合正则表达式 ^[a-z]{1,3}-[a-z0-9=]{32}$
的标识符格式如下:
- m:表示消息
- u:表示用户
- c:表示会话(线程)
- d:表示与消息一起发送的元数据
🔐 身份验证
在创建机器人时,创作者可以提供一个由 32 个 ASCII 字符组成的访问密钥。为了允许机器人服务器确认请求来自 Poe,所有请求将具有以下 HTTP 头:
Authorization: Bearer <access_key>
📄 内容类型
消息可以使用以下内容类型:
- text/plain:纯文本,无需进一步处理。
- text/markdown:Markdown 文本,支持 GitHub 风格的 Markdown(GFM)。Poe 可能会出于安全或可用性原因修改渲染的 Markdown。
🔄 版本控制
预计该 API 将在未来扩展以支持其他功能。协议版本字符串由两个数字组成(例如,1.0)。第一个数字是请求版本,第二个是响应版本。
- 请求版本:如果请求的形式发生不兼容的变化,则会递增。例如,当前协议仅包含从 Poe 服务器到机器人服务器的单个 API 调用。
- 响应版本:支持新功能的响应版本,每当 Poe 服务器添加支持新功能时,该版本递增。
🚧 限制
Poe 可能会对机器人服务器实施限制,以确保产品的可靠性和可扩展性。具体包括:
- 初始响应必须在 5 秒内返回。
- 任何请求的响应必须在 600 秒内完成。
- 机器人的总响应长度不得超过 100,000 个字符。
- 响应的事件总数不得超过 10,000 个。
- 如果用户与机器人的先前对话中的消息数量超过 1000,Poe 可能会截断对话。
📬 请求
Poe 服务器将向机器人服务器的 URL 发送一个 HTTP POST 请求,内容类型为 application/json
。请求体是一个包含以下键的 JSON 字典:
- version (string):API 版本。
- type (string):请求类型,可能的值包括:
- query:用户向机器人发起查询时调用。
- settings:查询机器人的设置。
- report_feedback:报告用户对消息的反馈。
- report_error:报告与机器人相关的错误。
查询请求
查询请求除了所有有效请求字段外,还包含以下参数:
- query (array):包含一个或多个字典,表示与机器人的先前消息。这些字典包含:
- role (string):消息角色,如
user
、bot
、system
。 - content (string):消息文本。
- content_type (string):消息内容类型。
- timestamp (int):消息发送时间。
- message_id (identifier with type m):消息标识符。
- feedback (array):用户对消息的反馈。
- attachments (array):用户随消息发送的附件信息。
- role (string):消息角色,如
🛠️ 响应
机器人服务器应以 HTTP 200 响应代码响应。如果返回其他响应代码,Poe 服务器将向用户显示错误消息。响应必须包含一系列服务器发送的事件,具体如下:
- meta:表示关于如何处理响应的元数据。
- text:表示发送给用户的一部分文本。
- suggested_reply:表示用户可以发送的建议回复。
- error:指示机器人服务器发生错误。
- done:表示机器人响应结束,必须是流中的最后一个事件。
📝 示例
例如,Poe 服务器可能会发送如下 JSON 请求:
{ "version": "1.0", "type": "query", "query": [ { "role": "user", "content": "What is the capital of Nepal?", "content_type": "text/markdown", "timestamp": 1678299819427621 } ], "user": "u-1234abcd5678efgh", "conversation": "c-jklm9012nopq3456" }
机器人服务器响应如下事件流:
event: meta data: {"content_type": "text/markdown", "linkify": true} event: text data: {"text": "The"} event: text data: {"text": " capital of Nepal is"} event: text data: {"text": " Kathmandu."} event: done data: {}
🔜 下一步
请查看 快速入门 以迅速运行一个机器人。如果你正在构建自己的机器人,推荐使用 fastapi-poe
库,该库用于使用 FastAPI 框架构建 Poe 机器人。
通过遵循这些规范和指南,你将能够更有效地与 Poe 平台进行互动,构建出更好的 AI 机器人!