Skip to content

Commit ffb0c83

Browse files
committed
update cookbook
2 parents c07f660 + 59439eb commit ffb0c83

35 files changed

+5520
-506
lines changed

authors.yaml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -385,4 +385,9 @@ lara-openai:
385385
glojain:
386386
name: "Glory Jain"
387387
website: "https://www.linkedin.com/in/gloryjain/"
388-
avatar: "https://media.licdn.com/dms/image/v2/C4E03AQH72n6Sm5q69Q/profile-displayphoto-shrink_400_400/profile-displayphoto-shrink_400_400/0/1557995338725?e=1756339200&v=beta&t=FGTXiCZwTZvqHCY-wd8It15EDf11Rex1oLlBKRGHNtY"
388+
avatar: "https://media.licdn.com/dms/image/v2/C4E03AQH72n6Sm5q69Q/profile-displayphoto-shrink_400_400/profile-displayphoto-shrink_400_400/0/1557995338725?e=1756339200&v=beta&t=FGTXiCZwTZvqHCY-wd8It15EDf11Rex1oLlBKRGHNtY"
389+
390+
corwin:
391+
name: "Corwin Cheung"
392+
website: "https://www.linkedin.com/in/corwincubes/"
393+
avatar: "https://avatars.githubusercontent.com/u/85517581?v=4"

examples/Optimize_Prompts.ipynb

Lines changed: 953 additions & 0 deletions
Large diffs are not rendered by default.

examples/Prompt_migration_guide.ipynb

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -698,6 +698,51 @@
698698
"Consistent testing and refinement ensure your prompts consistently achieve their intended results."
699699
]
700700
},
701+
{
702+
"cell_type": "markdown",
703+
"id": "cac0dc7f",
704+
"metadata": {},
705+
"source": [
706+
"### Current Example\n",
707+
"\n",
708+
"Let’s evaluate whether our current prompt migration has actually improved for the task of this judge. The original prompt, drawn from this [paper](https://arxiv.org/pdf/2306.05685), is designed to serve as a judge between two assistants’ answers. Conveniently, the paper provides a set of human-annotated ground truths, so we can measure how often the LLM judge agrees with the humans judgments.\n",
709+
"\n",
710+
"Thus, our metric of success will be measuring how closely the judgments generated by our migrated prompt align with human evaluations compared to the judgments generated with our baseline prompt. For context, the benchmark we’re using is a subset of MT-Bench, which features multi-turn conversations. In this example, we’re evaluating 200 conversation rows, each comparing the performance of different model pairs.\n",
711+
"\n"
712+
]
713+
},
714+
{
715+
"cell_type": "markdown",
716+
"id": "6f50f9a0",
717+
"metadata": {},
718+
"source": [
719+
"On our evaluation subset, a useful reference anchor is human-human agreement, since each conversation is rated by multiple annotators. Humans do not always agree with each other on which assistant answer is better, so we wouldn't expect our judge to achieve perfect agreement either. For turn 1 (without ties), humans agree with each other in 81% of cases, and for turn 2, in 76% of cases."
720+
]
721+
},
722+
{
723+
"cell_type": "markdown",
724+
"id": "7af0337b",
725+
"metadata": {},
726+
"source": [
727+
"![Graph 3 for Model Agreement](../images/prompt_migrator_fig.png)"
728+
]
729+
},
730+
{
731+
"cell_type": "markdown",
732+
"id": "800da674",
733+
"metadata": {},
734+
"source": [
735+
"Comparing this to our models before migration, GPT-4 (as used in the paper) achieves an agreement with human judgments of 74% on turn 1 and 71% on turn 2, which is not bad, but still below the human-human ceiling. Switching to GPT-4.1 (using the same prompt) improves the agreement: 77% on turn 1 and 72% on turn 2. Finally, after migrating and tuning our prompt specifically for GPT-4.1, the agreement climbs further, reaching 80% on turn 1 and 72% on turn 2, very close to matching the level of agreement seen between human annotators."
736+
]
737+
},
738+
{
739+
"cell_type": "markdown",
740+
"id": "43ae2ba5",
741+
"metadata": {},
742+
"source": [
743+
"Viewed all together, we can see that prompt migration and upgrading to more powerful models improve agreement on our sample task. Go ahead and try it on your prompt now!"
744+
]
745+
},
701746
{
702747
"cell_type": "markdown",
703748
"id": "c3ed1776",
@@ -883,7 +928,7 @@
883928
"name": "python",
884929
"nbconvert_exporter": "python",
885930
"pygments_lexer": "ipython3",
886-
"version": "3.11.8"
931+
"version": "3.12.9"
887932
}
888933
},
889934
"nbformat": 4,

examples/Reinforcement_Fine_Tuning.ipynb

Lines changed: 230 additions & 161 deletions
Large diffs are not rendered by default.

examples/agents_sdk/evaluate_agents.ipynb

Lines changed: 153 additions & 186 deletions
Large diffs are not rendered by default.

examples/chatgpt/gpt_actions_library/gpt_action_snowflake_direct.ipynb

Lines changed: 97 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -99,15 +99,15 @@
9999
"cell_type": "markdown",
100100
"metadata": {},
101101
"source": [
102-
"## ChatGPT Steps"
102+
"## 1. Configure the Custom GPT"
103103
]
104104
},
105105
{
106106
"cell_type": "markdown",
107107
"metadata": {},
108108
"source": [
109109
"\n",
110-
"### Custom GPT Instructions\n",
110+
"### Set GPT Instructions\n",
111111
"\n",
112112
"Once you've created a Custom GPT, copy the text below in the Instructions panel. Have questions? Check out [Getting Started Example](https://platform.openai.com/docs/actions/getting-started) to see how this step works in more detail."
113113
]
@@ -217,7 +217,7 @@
217217
"cell_type": "markdown",
218218
"metadata": {},
219219
"source": [
220-
"## Authentication Instructions"
220+
"## 2. Configure Snowflake Integration"
221221
]
222222
},
223223
{
@@ -231,20 +231,11 @@
231231
"cell_type": "markdown",
232232
"metadata": {},
233233
"source": [
234-
"### Pre-Action Steps"
235-
]
236-
},
237-
{
238-
"cell_type": "markdown",
239-
"metadata": {},
240-
"source": [
241-
"Before you set up authentication in ChatGPT, please take the following steps in Snowflake.\n",
242-
"\n",
243-
"### 1. Optional: Configure IP Whitelisting for ChatGPT\n",
234+
"### Configure IP Whitelisting for ChatGPT\n",
244235
"Snowflake accounts with network policies that limit connections by IP, may require exceptions to be added for ChatGPT.\n",
245236
"* Review the Snowflake documentation on [Network Policies](https://docs.snowflake.com/en/user-guide/network-policies)\n",
246237
"* Go to the Snowflake Worksheets\n",
247-
"* Create a network rule with the ChatGPT IP egress ranges listed [here](https://platform.openai.com/docs/actions/production/ip-egress-ranges)\n",
238+
"* Create a network rule with the ChatGPT IP egress ranges listed [here](https://platform.openai.com/docs/actions/production/ip-egress-ranges#ip-egress-ranges)\n",
248239
"* Create a corresponding Network Policy"
249240
]
250241
},
@@ -258,26 +249,11 @@
258249
},
259250
"outputs": [],
260251
"source": [
261-
"## Example with ChatGPT IPs as of October 23, 2024\n",
262-
"## Make sure to get the current IP ranges from https://platform.openai.com/docs/actions/production\n",
252+
"## ChatGPT IP ranges available at https://openai.com/chatgpt-actions.json\n",
263253
"CREATE NETWORK RULE chatgpt_network_rule\n",
264254
" MODE = INGRESS\n",
265255
" TYPE = IPV4\n",
266-
" VALUE_LIST = ('23.102.140.112/28',\n",
267-
" '13.66.11.96/28',\n",
268-
" '104.210.133.240/28',\n",
269-
" '70.37.60.192/28',\n",
270-
" '20.97.188.144/28',\n",
271-
" '20.161.76.48/28',\n",
272-
" '52.234.32.208/28',\n",
273-
" '52.156.132.32/28',\n",
274-
" '40.84.220.192/28',\n",
275-
" '23.98.178.64/28',\n",
276-
" '51.8.155.32/28',\n",
277-
" '20.246.77.240/28',\n",
278-
" '172.178.141.0/28',\n",
279-
" '172.178.141.192/28',\n",
280-
" '40.84.180.128/28');\n",
256+
" VALUE_LIST = ('23.102.140.112/28',...,'40.84.180.128/28');\n",
281257
"\n",
282258
"CREATE NETWORK POLICY chatgpt_network_policy\n",
283259
" ALLOWED_NETWORK_RULE_LIST = ('chatgpt_network_rule');"
@@ -287,14 +263,14 @@
287263
"cell_type": "markdown",
288264
"metadata": {},
289265
"source": [
290-
"Network policies can be applied at the account, security integration, and user level. The most specific network policy overrides the more general network policies. Depending on how these policies are applied, you may need to alter the policies for individual users in addition to the security integration. If you face this issue, you may encounter Snowflake's error code 390422."
266+
"Network policies can be applied at the account, security integration, and user level. The most specific network policy overrides the more general network policies. Depending on how these policies are applied, you may need to alter the policies for individual users in addition to the security integration. If you face this issue, you may encounter Snowflake's error code 390422 or a generic \"Invalid Client\" error."
291267
]
292268
},
293269
{
294270
"cell_type": "markdown",
295271
"metadata": {},
296272
"source": [
297-
"### 2. Set up the Security Integration\n",
273+
"### Create the Security Integration\n",
298274
"* Review the Snowflake OAuth Overview: [https://docs.snowflake.com/en/user-guide/oauth-snowflake-overview](https://docs.snowflake.com/en/user-guide/oauth-snowflake-overview)\n",
299275
"* Create new OAuth credentials through a [Security Integration](https://docs.snowflake.com/en/sql-reference/sql/create-security-integration-oauth-snowflake) - you will need a new one for each OAuth app/custom GPT since Snowflake Redirect URIs are 1-1 mapped to Security Integrations"
300276
]
@@ -324,7 +300,89 @@
324300
"cell_type": "markdown",
325301
"metadata": {},
326302
"source": [
327-
"\n",
303+
"<details>\n",
304+
" <summary>Optional: Automate Network Rule Configuration</summary>\n",
305+
" \n",
306+
" There are now over 100 egress IP addresses used by ChatGPT. The list updates irregularly and without announcement. To keep up to date with it, we can fetch the list on a daily basis and apply it to our network rule.\n",
307+
"\n",
308+
" ### Network rule to allow outbound traffic to OpenAI\n",
309+
" ```sql\n",
310+
" CREATE OR REPLACE NETWORK RULE chatgpt_actions_rule\n",
311+
" MODE = EGRESS -- outbound\n",
312+
" TYPE = HOST_PORT\n",
313+
" VALUE_LIST = ('openai.com:443');\n",
314+
" ```\n",
315+
" ### Access Integration to apply the rule\n",
316+
" ```sql\n",
317+
" CREATE OR REPLACE EXTERNAL ACCESS INTEGRATION chatgpt_actions_integration\n",
318+
" ALLOWED_NETWORK_RULES = (chatgpt_actions_rule)\n",
319+
" ENABLED = TRUE;\n",
320+
" ```\n",
321+
"\n",
322+
" ### UDF to Fetch the IP ranges\n",
323+
" ```sql\n",
324+
" CREATE OR REPLACE FUNCTION getChatGPTActionsAddresses()\n",
325+
" RETURNS ARRAY -- array<varchar>\n",
326+
" LANGUAGE PYTHON\n",
327+
" RUNTIME_VERSION = 3.10\n",
328+
" PACKAGES = ('requests')\n",
329+
" EXTERNAL_ACCESS_INTEGRATIONS = (chatgpt_actions_integration)\n",
330+
" HANDLER = 'get_ip_address_ranges'\n",
331+
"AS\n",
332+
"$$\n",
333+
"import requests\n",
334+
"\n",
335+
"def get_ip_address_ranges():\n",
336+
" resp = requests.get(\"https://openai.com/chatgpt-actions.json\", timeout=10)\n",
337+
" resp.raise_for_status()\n",
338+
" data = [entry[\"ipv4Prefix\"] for entry in resp.json().get(\"prefixes\", []) if \"ipv4Prefix\" in entry]\n",
339+
" return data\n",
340+
"$$;\n",
341+
" ```\n",
342+
" ### Procedure to update the network rule\n",
343+
" ```sql\n",
344+
" CREATE OR REPLACE PROCEDURE update_chatgpt_network_rule()\n",
345+
" RETURNS STRING\n",
346+
" LANGUAGE SQL\n",
347+
"AS\n",
348+
"$$\n",
349+
"DECLARE\n",
350+
" ip_list STRING;\n",
351+
"BEGIN\n",
352+
" -- Properly quote the IPs for use in VALUE_LIST\n",
353+
" ip_list := '''' || ARRAY_TO_STRING(getChatGPTActionsAddresses(), ''',''') || '''';\n",
354+
"\n",
355+
" -- Run the dynamic SQL to update the rule\n",
356+
" EXECUTE IMMEDIATE\n",
357+
" 'ALTER NETWORK RULE chatgpt_network_rule SET VALUE_LIST = (' || ip_list || ')';\n",
358+
"\n",
359+
" RETURN 'chatgpt_network_rule updated with ' || ARRAY_SIZE(getChatGPTActionsAddresses()) || ' entries';\n",
360+
"END;\n",
361+
"$$;\n",
362+
" ```\n",
363+
"\n",
364+
" ### Call the procedure\n",
365+
" ```sql\n",
366+
" CALL update_chatgpt_network_rule();\n",
367+
" ```\n",
368+
"\n",
369+
" ### Run the procedure every day at 6AM Pacific Time\n",
370+
" ```sql\n",
371+
" CREATE OR REPLACE TASK auto_update_chatgpt_network_rule\n",
372+
" WAREHOUSE = COMPUTE_WH\n",
373+
" SCHEDULE = 'USING CRON 0 6 * * * America/Los_Angeles'\n",
374+
"AS\n",
375+
" CALL update_chatgpt_network_rule();\n",
376+
" ```\n",
377+
"</details>"
378+
]
379+
},
380+
{
381+
"cell_type": "markdown",
382+
"metadata": {},
383+
"source": [
384+
"## 3. Configure GPT Action Authentication\n",
385+
"### Gather key information from Snowflake\n",
328386
"* Retrieve your OAuth Client ID, Auth URL, and Token URL\n"
329387
]
330388
},
@@ -346,7 +404,7 @@
346404
"metadata": {},
347405
"source": [
348406
"\n",
349-
"You’ll find the required information in these 3 columns:"
407+
"You’ll find the required information in these 3 rows:"
350408
]
351409
},
352410
{
@@ -391,7 +449,7 @@
391449
"cell_type": "markdown",
392450
"metadata": {},
393451
"source": [
394-
"### In ChatGPT"
452+
"### Set OAuth Values in GPT Action Authentication"
395453
]
396454
},
397455
{
@@ -407,18 +465,18 @@
407465
"| Client Secret | OAUTH_CLIENT_SECRET from SHOW_OAUTH_CLIENT_SECRETS |\n",
408466
"| Authorization URL | OAUTH_AUTHORIZATION_ENDPOINT from DESCRIBE SECURITY INTEGRATION |\n",
409467
"| Token URL | OAUTH_TOKEN_ENDPOINT from DESCRIBE SECURITY INTEGRATION |\n",
410-
"| Scope | session:role:your_role* |\n",
468+
"| Scope | session:role:CHATGPT_INTEGRATION_ROLE* |\n",
411469
"| Token Exchange Method | Default (POST Request) |\n",
412470
"\n",
413471
"\n",
414-
"*Snowflake scopes pass the role in the format `session:role:<your_role>` for example `session:role:CHATGPT_INTEGRATION_ROLE`. It's possible to leave this empty and specify the role in the instructions, but by adding it here it becomes included in OAuth Consent Request which can sometimes be more reliable. "
472+
"*Snowflake scopes pass the role in the format `session:role:<your_role>` for example `session:role:CHATGPT_INTEGRATION_ROLE`. You can optionally leave this field empty and specify the role in the GPT instructions, but by adding it here it becomes included in OAuth Consent Request which can sometimes be more reliable. "
415473
]
416474
},
417475
{
418476
"cell_type": "markdown",
419477
"metadata": {},
420478
"source": [
421-
"### Post-Action Steps"
479+
"### 4. Update the Snowflake Integration Redirect URI"
422480
]
423481
},
424482
{
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
__pycache__
2+
.DS_Store
3+
.python-version
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# Databricks MCP Assistant (with React UI)
2+
3+
A full-stack, Databricks-themed conversational assistant for supply chain queries, powered by OpenAI Agents and Databricks MCP servers. Includes a React chat UI and a FastAPI backend that streams agent responses.
4+
5+
---
6+
7+
## Features
8+
- Conversational chat UI (React) with Databricks red palette
9+
- FastAPI backend with streaming `/chat` endpoint
10+
- Secure Databricks MCP integration
11+
- Example agent logic and tool usage
12+
- Modern UX, easy local development
13+
14+
15+
## Quickstart
16+
17+
### 0. Databricks assets
18+
19+
You can kick start your project with Databricks’ Supply-Chain Optimization Solution Accelerator (or any other accelerator if working in a different industry). Clone this accelerator’s GitHub repo into your Databricks workspace and run the bundled notebooks by running notebook 1:
20+
21+
https://github.com/lara-openai/databricks-supply-chain
22+
23+
These notebooks stand up every asset the Agent will later reach via MCP, from raw enterprise tables and unstructured e-mails to classical ML models and graph workloads.
24+
25+
### 1. Prerequisites
26+
- Python 3.10+
27+
- Node.js 18+
28+
- Databricks credentials in `~/.databrickscfg`
29+
- OpenAI API key
30+
- (Optional) Virtualenv/pyenv for Python isolation
31+
32+
### 2. Install Python Dependencies
33+
```bash
34+
pip install -r requirements.txt
35+
```
36+
37+
### 3. Start the Backend (FastAPI)
38+
39+
To kick off the backend, run:
40+
41+
```bash
42+
python -m uvicorn api_server:app --reload --port 8000
43+
```
44+
- The API will be available at http://localhost:8000
45+
- FastAPI docs: http://localhost:8000/docs
46+
47+
### 4. Start the Frontend (React UI)
48+
In a different terminal, run the following:
49+
```bash
50+
cd ui
51+
npm install
52+
npm run dev
53+
```
54+
- The app will be available at http://localhost:5173
55+
56+
---
57+
58+
## Usage
59+
1. Open [http://localhost:5173](http://localhost:5173) in your browser.
60+
2. Type a supply chain question (e.g., "What are the delays with distribution center 5?") and hit Send.
61+
3. The agent will stream back a response from the Databricks MCP server.
62+
63+
---
64+
65+
## Troubleshooting
66+
- **Port already in use:** Kill old processes with `lsof -ti:8000 | xargs kill -9` (for backend) or change the port.
67+
- **Frontend not loading:** Make sure you ran `npm install` and `npm run dev` in the `ui/` folder.
68+
69+
---
70+
71+
## Customization
72+
- To change the agent's greeting, edit `ui/src/components/ChatUI.jsx`.
73+
- To update backend agent logic, modify `api_server.py`.
74+
- UI styling is in `ui/src/components/ChatUI.css` (Databricks red palette).
75+
76+
77+

0 commit comments

Comments
 (0)