promptflow

Форк
0
/
chat-stream-with-async-flex-flow.ipynb 
380 строк · 10.3 Кб
1
{
2
 "cells": [
3
  {
4
   "cell_type": "markdown",
5
   "metadata": {},
6
   "source": [
7
    "# Stream chat with async flex flow"
8
   ]
9
  },
10
  {
11
   "cell_type": "markdown",
12
   "metadata": {},
13
   "source": [
14
    "**Learning Objectives** - Upon completing this tutorial, you should be able to:\n",
15
    "\n",
16
    "- Write LLM application using class based flex flow.\n",
17
    "- Use AzureOpenAIModelConfiguration as class init parameter.\n",
18
    "- Use prompty to stream completions.\n",
19
    "- Convert the application into a async flow and batch run against multi lines of data.\n",
20
    "- Use classed base flow to evaluate the main flow and learn how to do aggregation.\n",
21
    "\n",
22
    "## 0. Install dependent packages"
23
   ]
24
  },
25
  {
26
   "cell_type": "code",
27
   "execution_count": null,
28
   "metadata": {},
29
   "outputs": [],
30
   "source": [
31
    "%%capture --no-stderr\n",
32
    "%pip install -r ./requirements.txt"
33
   ]
34
  },
35
  {
36
   "cell_type": "markdown",
37
   "metadata": {},
38
   "source": [
39
    "## 1. Trace your application with promptflow\n",
40
    "\n",
41
    "Assume we already have a python program, which leverage prompty."
42
   ]
43
  },
44
  {
45
   "cell_type": "code",
46
   "execution_count": null,
47
   "metadata": {},
48
   "outputs": [],
49
   "source": [
50
    "with open(\"flow.py\") as fin:\n",
51
    "    print(fin.read())"
52
   ]
53
  },
54
  {
55
   "cell_type": "markdown",
56
   "metadata": {},
57
   "source": [
58
    "When `stream=true` is configured in the parameters of a prompt whose output format is text, promptflow sdk will return a generator type, which item is the content of each chunk.\n",
59
    "\n",
60
    "Reference openai doc on how to do it using plain python code: [how_to_stream_completions](https://cookbook.openai.com/examples/how_to_stream_completions)"
61
   ]
62
  },
63
  {
64
   "cell_type": "code",
65
   "execution_count": null,
66
   "metadata": {},
67
   "outputs": [],
68
   "source": [
69
    "with open(\"chat.prompty\") as fin:\n",
70
    "    print(fin.read())"
71
   ]
72
  },
73
  {
74
   "cell_type": "markdown",
75
   "metadata": {},
76
   "source": [
77
    "\n",
78
    "### Create necessary connections\n",
79
    "Connection helps securely store and manage secret keys or other sensitive credentials required for interacting with LLM and other external tools for example Azure Content Safety.\n",
80
    "\n",
81
    "Above prompty uses connection `open_ai_connection` inside, we need to set up the connection if we haven't added it before. After created, it's stored in local db and can be used in any flow.\n",
82
    "\n",
83
    "Prepare your Azure Open AI resource follow this [instruction](https://learn.microsoft.com/en-us/azure/cognitive-services/openai/how-to/create-resource?pivots=web-portal) and get your `api_key` if you don't have one."
84
   ]
85
  },
86
  {
87
   "cell_type": "code",
88
   "execution_count": null,
89
   "metadata": {},
90
   "outputs": [],
91
   "source": [
92
    "from promptflow.client import PFClient\n",
93
    "from promptflow.connections import AzureOpenAIConnection, OpenAIConnection\n",
94
    "\n",
95
    "# client can help manage your runs and connections.\n",
96
    "pf = PFClient()\n",
97
    "try:\n",
98
    "    conn_name = \"open_ai_connection\"\n",
99
    "    conn = pf.connections.get(name=conn_name)\n",
100
    "    print(\"using existing connection\")\n",
101
    "except:\n",
102
    "    # Follow https://learn.microsoft.com/en-us/azure/ai-services/openai/how-to/create-resource?pivots=web-portal to create an Azure Open AI resource.\n",
103
    "    connection = AzureOpenAIConnection(\n",
104
    "        name=conn_name,\n",
105
    "        api_key=\"<your_AOAI_key>\",\n",
106
    "        api_base=\"<your_AOAI_endpoint>\",\n",
107
    "        api_type=\"azure\",\n",
108
    "    )\n",
109
    "\n",
110
    "    # use this if you have an existing OpenAI account\n",
111
    "    # connection = OpenAIConnection(\n",
112
    "    #     name=conn_name,\n",
113
    "    #     api_key=\"<user-input>\",\n",
114
    "    # )\n",
115
    "\n",
116
    "    conn = pf.connections.create_or_update(connection)\n",
117
    "    print(\"successfully created connection\")\n",
118
    "\n",
119
    "print(conn)"
120
   ]
121
  },
122
  {
123
   "cell_type": "markdown",
124
   "metadata": {},
125
   "source": [
126
    "### Visualize trace by using start_trace\n",
127
    "\n",
128
    "Note we add `@trace` in the `my_llm_tool` function, re-run below cell will collect a trace in trace UI."
129
   ]
130
  },
131
  {
132
   "cell_type": "code",
133
   "execution_count": null,
134
   "metadata": {},
135
   "outputs": [],
136
   "source": [
137
    "from promptflow.tracing import start_trace\n",
138
    "from promptflow.core import AzureOpenAIModelConfiguration\n",
139
    "\n",
140
    "from flow import ChatFlow\n",
141
    "\n",
142
    "# create a chatFlow obj with connection\n",
143
    "config = AzureOpenAIModelConfiguration(\n",
144
    "    connection=\"open_ai_connection\", azure_deployment=\"gpt-35-turbo\"\n",
145
    ")\n",
146
    "chat_flow = ChatFlow(config)\n",
147
    "\n",
148
    "# start a trace session, and print a url for user to check trace\n",
149
    "start_trace()\n",
150
    "\n",
151
    "# run the flow as function, which will be recorded in the trace\n",
152
    "result = chat_flow(question=\"What is ChatGPT? Please explain with detailed statement\")\n",
153
    "# note the type is async generator object as we enabled stream in prompty\n",
154
    "result"
155
   ]
156
  },
157
  {
158
   "cell_type": "code",
159
   "execution_count": null,
160
   "metadata": {},
161
   "outputs": [],
162
   "source": [
163
    "import asyncio\n",
164
    "\n",
165
    "# print result in stream manner\n",
166
    "async for output in result:\n",
167
    "    print(output, end=\"\")\n",
168
    "    await asyncio.sleep(0.01)"
169
   ]
170
  },
171
  {
172
   "cell_type": "code",
173
   "execution_count": null,
174
   "metadata": {},
175
   "outputs": [],
176
   "source": [
177
    "result = chat_flow(question=\"What is ChatGPT? Please explain with consise statement\")\n",
178
    "\n",
179
    "answer = \"\"\n",
180
    "async for output in result:\n",
181
    "    answer += output\n",
182
    "answer"
183
   ]
184
  },
185
  {
186
   "cell_type": "markdown",
187
   "metadata": {},
188
   "source": [
189
    "### Eval the result "
190
   ]
191
  },
192
  {
193
   "cell_type": "code",
194
   "execution_count": null,
195
   "metadata": {},
196
   "outputs": [],
197
   "source": [
198
    "%load_ext autoreload\n",
199
    "%autoreload 2\n",
200
    "\n",
201
    "import paths  # add the code_quality module to the path\n",
202
    "from check_list import EvalFlow\n",
203
    "\n",
204
    "eval_flow = EvalFlow(config)\n",
205
    "# evaluate answer agains a set of statement\n",
206
    "eval_result = eval_flow(\n",
207
    "    answer=answer,\n",
208
    "    statements={\n",
209
    "        \"correctness\": \"It contains a detailed explanation of ChatGPT.\",\n",
210
    "        \"consise\": \"It is a consise statement.\",\n",
211
    "    },\n",
212
    ")\n",
213
    "eval_result"
214
   ]
215
  },
216
  {
217
   "cell_type": "markdown",
218
   "metadata": {},
219
   "source": [
220
    "## 2. Batch run the function as flow with multi-line data\n"
221
   ]
222
  },
223
  {
224
   "cell_type": "markdown",
225
   "metadata": {},
226
   "source": [
227
    "### Batch run with a data file (with multiple lines of test data)\n"
228
   ]
229
  },
230
  {
231
   "cell_type": "code",
232
   "execution_count": null,
233
   "metadata": {},
234
   "outputs": [],
235
   "source": [
236
    "from promptflow.client import PFClient\n",
237
    "\n",
238
    "pf = PFClient()"
239
   ]
240
  },
241
  {
242
   "cell_type": "code",
243
   "execution_count": null,
244
   "metadata": {},
245
   "outputs": [],
246
   "source": [
247
    "data = \"./data.jsonl\"  # path to the data file\n",
248
    "# create run with the flow function and data\n",
249
    "base_run = pf.run(\n",
250
    "    flow=chat_flow,\n",
251
    "    data=data,\n",
252
    "    column_mapping={\n",
253
    "        \"question\": \"${data.question}\",\n",
254
    "        \"chat_history\": \"${data.chat_history}\",\n",
255
    "    },\n",
256
    "    stream=True,\n",
257
    ")"
258
   ]
259
  },
260
  {
261
   "cell_type": "code",
262
   "execution_count": null,
263
   "metadata": {},
264
   "outputs": [],
265
   "source": [
266
    "details = pf.get_details(base_run)\n",
267
    "details.head(10)"
268
   ]
269
  },
270
  {
271
   "cell_type": "markdown",
272
   "metadata": {},
273
   "source": [
274
    "## 3. Evaluate your flow\n",
275
    "Then you can use an evaluation method to evaluate your flow. The evaluation methods are also flows which usually using LLM assert the produced output matches certain expectation. "
276
   ]
277
  },
278
  {
279
   "cell_type": "markdown",
280
   "metadata": {},
281
   "source": [
282
    "### Run evaluation on the previous batch run\n",
283
    "The **base_run** is the batch run we completed in step 2 above, for web-classification flow with \"data.jsonl\" as input."
284
   ]
285
  },
286
  {
287
   "cell_type": "code",
288
   "execution_count": null,
289
   "metadata": {},
290
   "outputs": [],
291
   "source": [
292
    "eval_run = pf.run(\n",
293
    "    flow=eval_flow,\n",
294
    "    data=\"./data.jsonl\",  # path to the data file\n",
295
    "    run=base_run,  # specify base_run as the run you want to evaluate\n",
296
    "    column_mapping={\n",
297
    "        \"answer\": \"${run.outputs.output}\",\n",
298
    "        \"statements\": \"${data.statements}\",\n",
299
    "    },\n",
300
    "    stream=True,\n",
301
    ")"
302
   ]
303
  },
304
  {
305
   "cell_type": "code",
306
   "execution_count": null,
307
   "metadata": {},
308
   "outputs": [],
309
   "source": [
310
    "details = pf.get_details(eval_run)\n",
311
    "details.head(10)"
312
   ]
313
  },
314
  {
315
   "cell_type": "code",
316
   "execution_count": null,
317
   "metadata": {},
318
   "outputs": [],
319
   "source": [
320
    "import json\n",
321
    "\n",
322
    "metrics = pf.get_metrics(eval_run)\n",
323
    "print(json.dumps(metrics, indent=4))"
324
   ]
325
  },
326
  {
327
   "cell_type": "code",
328
   "execution_count": null,
329
   "metadata": {},
330
   "outputs": [],
331
   "source": [
332
    "pf.visualize([base_run, eval_run])"
333
   ]
334
  },
335
  {
336
   "cell_type": "markdown",
337
   "metadata": {},
338
   "source": [
339
    "## Next steps\n",
340
    "\n",
341
    "By now you've successfully run your chat flow and did evaluation on it. That's great!\n",
342
    "\n",
343
    "You can check out more examples:\n",
344
    "- [Stream Chat](https://github.com/microsoft/promptflow/tree/main/examples/flex-flows/chat-stream): demonstrates how to create a chatbot that runs in streaming mode."
345
   ]
346
  }
347
 ],
348
 "metadata": {
349
  "build_doc": {
350
   "author": [
351
    "D-W-@github.com",
352
    "wangchao1230@github.com"
353
   ],
354
   "category": "local",
355
   "section": "Flow",
356
   "weight": 12
357
  },
358
  "description": "A quickstart tutorial to run a class based flex flow in stream mode and evaluate it.",
359
  "kernelspec": {
360
   "display_name": "prompt_flow",
361
   "language": "python",
362
   "name": "python3"
363
  },
364
  "language_info": {
365
   "codemirror_mode": {
366
    "name": "ipython",
367
    "version": 3
368
   },
369
   "file_extension": ".py",
370
   "mimetype": "text/x-python",
371
   "name": "python",
372
   "nbconvert_exporter": "python",
373
   "pygments_lexer": "ipython3",
374
   "version": "3.9.18"
375
  },
376
  "resources": "examples/requirements.txt, examples/flex-flows/chat-basic, examples/flex-flows/eval-checklist"
377
 },
378
 "nbformat": 4,
379
 "nbformat_minor": 2
380
}
381

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.