Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

补充通过sdk模块记录会话的用户示例 #441

Merged
merged 13 commits into from
Aug 1, 2024
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions appbuilder/core/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,41 @@ def run(self, message: Message, stream: bool=False):
"stream": false
}'

** Session 信息查看 **: 查看本地user_session.db数据库内部信息,下面是一个例子

Examples:

.. code-block:: python

import sqlite3
import json

# 连接到 SQLite 数据库
# 如果文件不存在,会自动在当前目录创建:
user_session_path = 'your_user_session.db地址'
conn = sqlite3.connect(user_session_path)
cursor = conn.cursor()

# 执行一条 SQL 语句,列出所有表
cursor.execute("SELECT name FROM sqlite_master WHERE type='table';")
print(cursor.fetchall())

# 查询appbuilder_session_messages表的列信息
cursor.execute("PRAGMA table_info(appbuilder_session_messages);")
columns_info = cursor.fetchall()

column_names = [info[1] for info in columns_info] # info[1]是列名的位置
for column_name in column_names:
print(column_name)

# 查询特定表中的数据
cursor.execute("SELECT message_value FROM appbuilder_session_messages;")
for row in cursor.fetchall():
print(json.loads(row[0]))

# 关闭 Connection:
conn.close()

"""
component: Component
user_session_config: Optional[Union[sqlalchemy.engine.URL, str]] = None
Expand Down
8 changes: 7 additions & 1 deletion appbuilder/tests/test_image_understand.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@
import unittest
import requests
import appbuilder
import time

from appbuilder.core.message import Message
from appbuilder.core._exception import AppBuilderServerException


@unittest.skipUnless(os.getenv("TEST_CASE", "UNKNOWN") == "CPU_SERIAL", "")
class TestImageUnderstand(unittest.TestCase):
def setUp(self):
"""
Expand Down Expand Up @@ -52,6 +53,7 @@ def test_run_with_image_url(self):
inp = Message(content={"url": self.image_url, "question": "图像内容是什么?"})
msg = self.image_understand.run(inp)
self.assertIsNotNone(msg.content)
time.sleep(1)

def test_run_with_raw_image(self):
"""
Expand All @@ -68,6 +70,7 @@ def test_run_with_raw_image(self):
inp = Message(content={"raw_image": self.raw_image, "question": "图像内容是什么?"})
msg = self.image_understand.run(inp)
self.assertIsNotNone(msg.content)
time.sleep(1)

def test_tool_eval_valid(self):
"""测试 tool 方法对有效请求的处理。"""
Expand All @@ -82,18 +85,21 @@ def test_tool_eval_valid(self):
img_name=img_name, file_urls=file_urls, origin_query="")
res = [item for item in result]
self.assertNotEqual(len(res), 0)
time.sleep(1)

def test_tool_eval_invalid(self):
"""测试 tool 方法对无效请求的处理。"""
with self.assertRaises(ValueError):
result = self.image_understand.tool_eval(name="image_understand", streaming=True,
origin_query="")
next(result)
time.sleep(1)

def test_run_language_en(self):
"""测试 tool 方法对无效请求的处理。"""
inp = Message(content={"raw_image": self.raw_image, "question": "图像内容是什么?", "language": "en"})
self.image_understand.run(inp)
time.sleep(1)

def test_run_raise(self):
# question is empty
Expand Down
240 changes: 238 additions & 2 deletions cookbooks/components/agent_runtime.ipynb

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions docs/basic_module/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ AppBuilder面向开发者提供AI原生应用一站式开发工具,包括基
- AI基础能力组件 SDK:支持Python
- [获取模型列表](/docs/basic_module/get_model_list.md)
- [基础能力组件](/docs/basic_module/components.md)
- [组件调用的服务化封装](/docs/basic_module/agentruntime.md)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

将文档目录链接放在 进阶实践 下面,同时更新下docs/ 目录下的README

- [会话数据管理工具](/docs/basic_module/userseesion.md)

## 功能示例

Expand Down
180 changes: 180 additions & 0 deletions docs/basic_module/agentruntime.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
# `AgentRuntime`类

## 简介

AgentRuntime 是对组件调用的服务化封装,开发者不是必须要用 AgentRuntime 才能运行自己的组件服务。但 AgentRuntime 可以快速帮助开发者服务化组件服务,并且提供API、对话框等部署方式。此外,结合 Component 和 Message 自带的运行和调试接口,可以方便开发者快速获得一个调试 Agent 的服务。


## Python基本用法

### 1、实例化`AgentRuntime() -> AgentRuntime`

#### 方法参数

| 参数名称 | 参数类型 | 描述 | 示例值 |
|--------|--------|------------|-----------|
| component | Component | 可运行的 Component,需要实现 run(message, stream, **args) 方法 | "正确的component组件或client" |
| user_session_config | sqlalchemy.engine.URL、str、None | Session 输出存储配置字符串。默认使用 sqlite:///user_session.db | "正确的存储配置字符串" |

#### 方法功能

返回一个调试 Agent 的服务

#### 示例代码

```python
import os
import appbuilder
os.environ["APPBUILDER_TOKEN"] = '...'
component = appbuilder.Playground(
prompt_template="{query}",
model="eb-4"
)
agent = appbuilder.AgentRuntime(component=component)
```

### 2、运行Agent服务`AgentRuntime.chat(message: Message, stream: bool = False, **args) -> Message`

#### 方法参数

| 参数名称 | 参数类型 | 描述 | 示例值 |
|--------|--------|------------|-----------|
| message | Message | 该次对话用户输入的 Message | "正确的Message" |
| stream | bool | 是否使用流式请求。默认为 False | False |

#### 方法功能

运行一个 Agent 服务,执行一次对话

#### 示例代码

```python
import os
import appbuilder
os.environ["APPBUILDER_TOKEN"] = '...'
component = appbuilder.Playground(
prompt_template="{query}",
model="eb-4"
)
agent = appbuilder.AgentRuntime(component=component)
message = appbuilder.Message({"query": "你好"})
print(agent.chat(message, stream=False))
```

### 3、提供 Flask http API 接口`AgentRuntime.serve(self, host='0.0.0.0', debug=True, port=8092, url_rule="/chat"`

#### 方法参数

| 参数名称 | 参数类型 | 描述 | 示例值 |
|--------|--------|------------|-----------|
| host | String | 服务主机地址,默认为 '0.0.0.0' | '0.0.0.0' |
| debug | bool | 是否是调试模式,默认为 True | False |
| port | int | 服务端口号,默认为 8092 | 8092 |
| url_rule | String | Flask 路由规则,默认为 '/chat' | '/chat' |

#### 方法功能

将 component 服务化,提供 Flask http API 接口

#### 示例代码

```python
import os
import appbuilder
os.environ["APPBUILDER_TOKEN"] = '...'
component = appbuilder.Playground(
prompt_template="{query}",
model="eb-4"
)
user_session_config = "sqlite:///foo.db"
agent = appbuilder.AgentRuntime(
component=component, user_session_config=user_session_config)
agent.serve(debug=False, port=8091)
```


### 4、提供 chainlit demo 页面`AgentRuntime.chainlit_demo(host='0.0.0.0', port=8091)`


#### 方法参数

| 参数名称 | 参数类型 | 描述 | 示例值 |
|--------|--------|------------|-----------|
| host | string | 服务主机地址,默认为 '0.0.0.0' | "0.0.0.0" |
| port | int | 服务端口号,默认为 8092 | 8091 |

#### 方法功能

将 component 服务化,提供 chainlit demo 页面

#### 示例代码

```python
import os
import logging
from appbuilder.core.component import Component
from appbuilder import (
AgentRuntime, UserSession, Message, QueryRewrite, Playground,
)
os.environ["APPBUILDER_TOKEN"] = 'YOUR_APPBUILDER_TOKEN'
class PlaygroundWithHistory(Component):
def __init__(self):
super().__init__()
self.query_rewrite = QueryRewrite(model="ERNIE Speed-AppBuilder")
self.play = Playground(
prompt_template="{query}",
model="eb-4"
)
def run(self, message: Message, stream: bool=False):
user_session = UserSession()
# 获取 Session 历史数据
history_queries = user_session.get_history("query", limit=1)
history_answers = user_session.get_history("answer", limit=1)
if history_queries and history_answers:
history = []
for query, answer in zip(history_queries, history_answers):
history.extend([query.content, answer.content])
logging.info(f"history: {history}")
message = self.query_rewrite(
Message(history + [message.content]), rewrite_type="带机器人回复")
logging.info(f"message: {message}")
answer = self.play.run(message, stream)
# 保存本轮数据
user_session.append({
"query": message,
"answer": answer,
})
return answer

agent = AgentRuntime(component=PlaygroundWithHistory())
agent.chainlit_demo(port=8091)
```

### 5、将 appbuilder client 服务化,提供 chainlit demo 页面`AgentRuntime.chainlit_agent(host='0.0.0.0', port=8091)`


#### 方法参数

| 参数名称 | 参数类型 | 描述 | 示例值 |
|--------|--------|------------|-----------|
| host | string | 服务主机地址,默认为 '0.0.0.0' | "0.0.0.0" |
| port | int | 服务端口号,默认为 8092 | 8091 |

#### 方法返回值

将 appbuilder client 服务化,提供 chainlit demo 页面

#### 示例代码

```python
import appbuilder
import os

os.environ["APPBUILDER_TOKEN"] = '...'
app_id = '...' # 已发布AppBuilder应用ID,可在console端查看
builder = appbuilder.AppBuilderClient(app_id)
conversation_id = builder.create_conversation()
agent = appbuilder.AgentRuntime(component=builder)
message = appbuilder.Message({"query": "北京今天天气怎么样"})
print(agent.chat(message, stream=False))
```
91 changes: 91 additions & 0 deletions docs/basic_module/usersession.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# `UserSession`类

## 简介

会话数据管理工具,实例化后将是一个全局变量。提供保存对话数据与获取历史数据的方法。

## 应用场景

**必须**在 AgentRuntime 启动的服务中使用。

## Python基本用法

### 1、实例化`UserSession().__init__ -> UserSession`

#### 方法参数

| 参数名称 | 参数类型 | 描述 | 示例值 |
|--------|--------|------------|-----------|
| user_session_config | sqlalchemy.engine.URL、str、None | Session 输出存储配置字符串。默认使用 sqlite:///user_session.db | "正确的存储配置字符串" |

#### 方法功能

初始化 UserSession

#### 示例代码

```python
user_session = UserSession()
```

### 2、获取同个 session 中名为 key 的历史变量`UserSession().get_history(self, key: str, limit: int=10) -> List[Message]:`

#### 方法参数

| 参数名称 | 参数类型 | 描述 | 示例值 |
|--------|--------|------------|-----------|
| key | String | 历史变量 | "answer" |
| limit | int | 最近 limit 条 Message 数据 | 10 |

#### 方法功能

获取同个 session 中名为 key 的历史变量。在非服务化版本中从内存获取。在服务化版本中,将从数据库获取。

#### 方法返回值

`List[Message]`

衍生类`Message`定义如下:

```python
class Message(BaseModel, Generic[_T], extra=Extra.allow):
content: Optional[_T] = {}
name: Optional[str] = "msg"
mtype: Optional[str] = "dict"
id: Optional[str] = str(uuid.uuid4())
```

#### 示例代码

```python
history_queries = user_session.get_history("query", limit=1)
```

### 3、将 message_dict 中的变量保存到 session 中`UserSession().append(self, message_dict: Dict[str, Message]) -> None`

#### 方法参数

| 参数名称 | 参数类型 | 描述 | 示例值 |
|--------|--------|------------|-----------|
| message_dict | Dict | 包含 Message 的字典,其中键为字符串类型,值为 Message 类型 | {"query": message} |

#### 方法功能

将 message_dict 中的变量保存到 session 中。在非服务化版本中使用内存存储。在服务化版本中,将使用数据库进行存储。

#### 示例代码

```python
user_session.append({
"query": message,
"answer": answer,
})
```

### 4、UserSession结合AgentRuntime使用以及user_session.db文件读取

- [UserSession结合AgentRuntime使用以及user_session.db文件读取](https://github.com/baidubce/app-builder/blob/master/cookbooks/components/agent_runtime.ipynb)




5 changes: 3 additions & 2 deletions docs/trace/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@

本文档目录包含以下内容

- [Appbuilder Trace跟踪功能基本用法](./basic.md)
- [Phoneix可视化软件的进阶用法](./phoenix_method.md)
- [Appbuilder Trace跟踪功能基本用法](https://github.com/baidubce/app-builder/blob/master/docs/trace/basic.md)
- [Phoneix可视化软件的进阶用法](https://github.com/baidubce/app-builder/blob/master/docs/trace/phoenix_method.md)
- [Appbuilder Trace跟踪功能示例](https://github.com/baidubce/app-builder/blob/master/cookbooks/appbuilder_trace/trace.ipynb)
Loading