Compare commits
361 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| defb9e3ecb | |||
| 37393b7e98 | |||
| ecd859a67c | |||
| decca8e671 | |||
| 5ea0815187 | |||
| cf149650f5 | |||
| 4c6c231ea4 | |||
| 5955b26509 | |||
| 31f54bca55 | |||
| b1ae7bb736 | |||
| 31fe12e0da | |||
| 90b0c5e295 | |||
| 79fe1930cf | |||
| ab225c3eab | |||
| 6f1de75909 | |||
| 230ed64e41 | |||
| ef126c3a93 | |||
| 51a7534733 | |||
| 4f5d2bde13 | |||
| 3d05fe5d77 | |||
| c16ca673af | |||
| 6619034bce | |||
| c56fb5d8f7 | |||
| b407a5edb5 | |||
| e6a27d17fb | |||
| 34077fd479 | |||
| 7a68ad5a7f | |||
| 74a1b6c2f2 | |||
| 9a90ae5264 | |||
| 310c1bc105 | |||
| cd20b29299 | |||
| 0cb7aeb81c | |||
| 98db5eeeae | |||
| c21cb34ff6 | |||
| e28c7b9d92 | |||
| ee4e565604 | |||
| 6dbb089f4c | |||
| c4b694db8d | |||
| 97f428ad06 | |||
| ef92ee5408 | |||
| d094668d03 | |||
| 5bb5fc1625 | |||
| 1d57e0071d | |||
| 2a344c4f5c | |||
| ce02559b8d | |||
| e42746e372 | |||
| 3149dfd03a | |||
| e499fdbdab | |||
| e57df39248 | |||
| 09b192b98b | |||
| 13f01a0621 | |||
| cf879a1a58 | |||
| fcdf2ab63e | |||
| 083d8109c2 | |||
| 89cfc8b25f | |||
| c46e157f92 | |||
| 05d6026d37 | |||
| 8e98d5c146 | |||
| 3f311c0669 | |||
| b1a2f9d42b | |||
| 142f55c94c | |||
| 230a110e52 | |||
| 83e2b031cd | |||
| 4844e26e5c | |||
| 70a049af3c | |||
| dc11776c86 | |||
| 2448a42b90 | |||
| c75a900174 | |||
| 2fb7adfe0e | |||
| dc82270724 | |||
| d880a48dd0 | |||
| 7567e8b45e | |||
| 0d59a90151 | |||
| 98ad550b1a | |||
| b58f43ce9f | |||
| acf6adcd91 | |||
| daf6576c3c | |||
| 8caa4defa6 | |||
| 26918b8de4 | |||
| 6fb5ebe2f9 | |||
| c0aa67995b | |||
| 9f841f8328 | |||
| 99c75eece9 | |||
| 57d2586ee3 | |||
| 4280a43ec8 | |||
| 7f1082bbb2 | |||
| 57cfc45804 | |||
| 30e8913875 | |||
| 0ce6d4d7a4 | |||
| 584ba8d48e | |||
| 925805ee11 | |||
| 76fb73c971 | |||
| 6d19ea9ac0 | |||
| 90431090e9 | |||
| 6dff35b204 | |||
| e634c7978d | |||
| 7a9e99bba2 | |||
| efcdd4405b | |||
| bf3614690f | |||
| 7463e00da3 | |||
| cbe9de0c57 | |||
| a023507d42 | |||
| e48f544ddc | |||
| 4aa7ad5642 | |||
| c39cdbcd01 | |||
| 71eaa8bcc6 | |||
| 1e1cbdfc79 | |||
| cc8af4a43a | |||
| 43fbd48ab8 | |||
| 5ec66e9452 | |||
| 211521c82e | |||
| 4ddaab1efb | |||
| 53e5ce2e83 | |||
| 9f4bd1cb64 | |||
| 456863752b | |||
| c2dc34bbd6 | |||
| fcabb04baf | |||
| 8e7c32d3d6 | |||
| 7e3013d914 | |||
| 4a664c33d2 | |||
| 6d049ee2e4 | |||
| fa73e73664 | |||
| bf67ee6056 | |||
| a1abef2ee9 | |||
| a753e01d3c | |||
| 9b15065b24 | |||
| 6e4150537c | |||
| 233d715a14 | |||
| 77ac385dfe | |||
| 53b78fcd7d | |||
| 16f81bd7ee | |||
| 0ee049fd11 | |||
| 7dba17e5bc | |||
| eeb678b937 | |||
| fe4eb664fd | |||
| 257720e443 | |||
| e7afaedf3e | |||
| b66b47a708 | |||
| fe485ff62e | |||
| 1ebe1cee67 | |||
| e9252eb48a | |||
| dad7728135 | |||
| c5111e3335 | |||
| bbbdb98362 | |||
| 60cdc2af84 | |||
| 344c20f331 | |||
| 2b0496e947 | |||
| 6c63dba6fb | |||
| 734c021a2e | |||
| eeb034896f | |||
| 4c977e8384 | |||
| c6137713c7 | |||
| fd4b1893f1 | |||
| e542e6136b | |||
| 393451e304 | |||
| 5084ba27ab | |||
| c82771f841 | |||
| dc6860535a | |||
| c872617b4e | |||
| 47c8682761 | |||
| 683400788b | |||
| 05065a8329 | |||
| 1ae4d2bbc7 | |||
| ae38f406fd | |||
| 4897d01cb0 | |||
| bd7b563463 | |||
| 530241dd0b | |||
| 6338641107 | |||
| 6d62fb89c3 | |||
| 7d4df3b6e5 | |||
| bc28db5b92 | |||
| f78186c0f7 | |||
| e3292f5566 | |||
| 58f980f411 | |||
| 4740d0611d | |||
| 3651a10e80 | |||
| 483b51c51c | |||
| cdbddef86d | |||
| 3690109abf | |||
| 2e322b4fc8 | |||
| 735e5f3ddc | |||
| e4cb4c75e5 | |||
| 1693deff72 | |||
| 3270f1228d | |||
| eeabf48d29 | |||
| 89348aa8e5 | |||
| 3ab2ce27b5 | |||
| 265261862f | |||
| 66cf052b8c | |||
| 2ca2d81e58 | |||
| 951ba4dfd8 | |||
| 386d210e8b | |||
| 9321602845 | |||
| 26c06353f0 | |||
| 62cf12d6eb | |||
| 253ee61463 | |||
| 2ccd2a9397 | |||
| c139e8e3e6 | |||
| 6e6e96c422 | |||
| b677e5226d | |||
| df723584b6 | |||
| efe06ffff0 | |||
| 6ba052d58f | |||
| 8cf52058b5 | |||
| 1bae09126c | |||
| bbbae9de9d | |||
| 7cb6d06316 | |||
| bca5492829 | |||
| f6a4d8681f | |||
| fd3836ec95 | |||
| f304c2dc08 | |||
| f13a1a2fc3 | |||
| df1453e30c | |||
| bac204f800 | |||
| dbf24a7daa | |||
| 6a29b1ac96 | |||
| 6c700d9e0f | |||
| ab69e87c2a | |||
| d1f97531dc | |||
| 17ebbca6ea | |||
| 08ddaaaa2f | |||
| 7515fe5f3e | |||
| cd49dae7ed | |||
| 2977f56061 | |||
| 8938286862 | |||
| 7b90d03f28 | |||
| 9dfe4d6d79 | |||
| 3a781a453e | |||
| e23487b1d8 | |||
| ccee75721b | |||
| 0a4147116c | |||
| e58b40b34c | |||
| 0db05b9b96 | |||
| a8a191ae87 | |||
| 4d92775aa8 | |||
| 477847111e | |||
| efbcfb1d2e | |||
| a9b01c761c | |||
| dac2f7c84e | |||
| 478142e509 | |||
| e76d5ba679 | |||
| 23dc9c0f68 | |||
| 8b96176d8a | |||
| 1bbf5f4823 | |||
| 2f57682035 | |||
| 4c05160f98 | |||
| 3e9ad64a7f | |||
| 21fa19c73b | |||
| 58257d546b | |||
| 5e99d810fd | |||
| a2dc717d85 | |||
| 87062e6ca8 | |||
| ae3a21c5ff | |||
| ccebb8a2fa | |||
| 2d21d6e688 | |||
| 270d96b7e3 | |||
| ea21daa96f | |||
| 42845f8d07 | |||
| 8b63ae9c46 | |||
| 173060dc50 | |||
| d19b35cd48 | |||
| 0c83fbd679 | |||
| 6ae9c1d9cb | |||
| 27523b657a | |||
| 56d73c1a3f | |||
| 0d2ad9faab | |||
| 4572f00657 | |||
| 9ed208131f | |||
| 91b03b2ea7 | |||
| 70b5dc3a63 | |||
| d6ab0aa232 | |||
| f679e1c76b | |||
| b91f86ba3d | |||
| 0f2302fda4 | |||
| ff729c05af | |||
| 76a6821fb8 | |||
| 97c7a38a69 | |||
| 5d398a8a64 | |||
| 4252f6186b | |||
| 22148ade9f | |||
| b8332fe8e1 | |||
| e40e92a133 | |||
| ba8f345f80 | |||
| 2ddbf1ba0d | |||
| 23567c8f98 | |||
| 8d39ae7763 | |||
| a2edc41fc7 | |||
| 591b6fc44d | |||
| f8a3d92ce0 | |||
| a1d18d83da | |||
| 1ad881e9fc | |||
| 2de26be464 | |||
| 36f09543b2 | |||
| 393acf8557 | |||
| ab27f2ab79 | |||
| d13b5ea30a | |||
| 81843b9285 | |||
| b19f85234b | |||
| 9dee30a616 | |||
| 4489eb1291 | |||
| dde72e3800 | |||
| e49fca4b51 | |||
| 0411b08c07 | |||
| 6c490ab781 | |||
| 737884d297 | |||
| 00c63b046d | |||
| d04bf78335 | |||
| 7dbe12b893 | |||
| 4caa9cbc02 | |||
| af1f61186a | |||
| 13dea6ae1a | |||
| fa9698a681 | |||
| 4bed7c7895 | |||
| a3954f3dda | |||
| b779e231bf | |||
| de12de1437 | |||
| 5274ea5277 | |||
| 398d775122 | |||
| aca18e12ef | |||
| 270c2ed0aa | |||
| 2cf960196f | |||
| 6b83edc8fd | |||
| 711822223a | |||
| 8e6872b57c | |||
| e14224b05d | |||
| c3a30898af | |||
| f3f6fb0444 | |||
| 641b6d61a7 | |||
| c0996a64a7 | |||
| a8904f39e2 | |||
| 81011f6336 | |||
| 117b193ee9 | |||
| bd724a7939 | |||
| 866cdca216 | |||
| ba321ac5b0 | |||
| 8fab0ac2ad | |||
| 563eb936e4 | |||
| 09c069de4b | |||
| 1224c3b40e | |||
| 1001a1586f | |||
| cb01f6e002 | |||
| 6ffc59d96a | |||
| 860b8e58f8 | |||
| 615699e2aa | |||
| 7c8436373e | |||
| cfe97c6777 | |||
| fdbc626789 | |||
| 1638349028 | |||
| 17058d4ddb | |||
| 2661f330e2 | |||
| 46b9b653c1 | |||
| c7ca760e4a | |||
| deb9cb23cc | |||
| 063ed8ee46 | |||
| 43b09e64da | |||
| 7bf72e21be | |||
| dd80807db3 | |||
| a84bec3afd | |||
| 0b5ad46744 | |||
| 260d080fda | |||
| 4f0c8ba1be |
@@ -0,0 +1,31 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: bug
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
Write a concise description of what the bug is.
|
||||
|
||||
**Files**
|
||||
If possible, please provide the PDF file causing the issue.
|
||||
|
||||
**Job ID**
|
||||
If you have it, please provide the ID of the job you ran.
|
||||
You can find it here: https://cloud.llamaindex.ai/parse in the "History" tab.
|
||||
|
||||
**Client:**
|
||||
Please remove untested options:
|
||||
- Python Library
|
||||
- API
|
||||
- Frontend (cloud.llamaindex.ai)
|
||||
- Typescript Library
|
||||
- Notebook
|
||||
|
||||
**Additional context**
|
||||
Add any additional context about the problem here.
|
||||
What options did you use? Premium mode, multimodal, fast mode, parsing instructions, etc.
|
||||
Screenshots, code snippets, etc.
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
name: Custom issue
|
||||
about: Not a bug nor a feature request
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: enhancement
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
# Please see the documentation for all configuration options:
|
||||
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
|
||||
# and
|
||||
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
|
||||
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
@@ -0,0 +1,53 @@
|
||||
name: Build Package - Python
|
||||
|
||||
# Build package on its own without additional pip install
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- "py/**"
|
||||
pull_request:
|
||||
paths:
|
||||
- "py/**"
|
||||
env:
|
||||
UV_VERSION: "0.7.20"
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
# You can use PyPy versions in python-version.
|
||||
# For example, pypy-2.7 and pypy-3.8
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest]
|
||||
python-version: ["3.9"]
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
|
||||
- name: Install uv
|
||||
uses: astral-sh/setup-uv@v6
|
||||
with:
|
||||
version: ${{ env.UV_VERSION }}
|
||||
|
||||
- name: Set up Python
|
||||
run: uv python install
|
||||
|
||||
- name: Display Python version
|
||||
run: python --version
|
||||
|
||||
- name: Build
|
||||
working-directory: py
|
||||
run: uv build
|
||||
|
||||
- name: Test installing built package
|
||||
shell: bash
|
||||
working-directory: py
|
||||
run: |
|
||||
uv venv
|
||||
uv pip install dist/*.whl
|
||||
|
||||
- name: Test import
|
||||
working-directory: py
|
||||
run: uv run -- python -c "import llama_cloud_services"
|
||||
@@ -0,0 +1,36 @@
|
||||
name: Build Package - TypeScript
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- "ts/**"
|
||||
pull_request:
|
||||
paths:
|
||||
- "ts/**"
|
||||
|
||||
jobs:
|
||||
pre_release:
|
||||
name: Pre Release
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout Repo
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: 10
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: "ts/llama_cloud_services/.nvmrc"
|
||||
|
||||
- name: Install dependencies
|
||||
working-directory: ts/llama_cloud_services/
|
||||
run: pnpm install --no-frozen-lockfile
|
||||
|
||||
- name: Build
|
||||
working-directory: ts/llama_cloud_services/
|
||||
run: pnpm run build
|
||||
@@ -0,0 +1,95 @@
|
||||
name: Claude Code
|
||||
|
||||
on:
|
||||
issue_comment:
|
||||
types: [created]
|
||||
pull_request_review_comment:
|
||||
types: [created]
|
||||
issues:
|
||||
types: [opened, assigned]
|
||||
pull_request_review:
|
||||
types: [submitted]
|
||||
|
||||
jobs:
|
||||
claude:
|
||||
if: |
|
||||
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
|
||||
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
|
||||
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) ||
|
||||
(github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')))
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: read
|
||||
issues: read
|
||||
id-token: write
|
||||
steps:
|
||||
- name: Check repository access
|
||||
id: check-access
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
# Get the user who triggered the event
|
||||
case "${{ github.event_name }}" in
|
||||
"issue_comment")
|
||||
USER="${{ github.event.comment.user.login }}"
|
||||
;;
|
||||
"pull_request_review_comment")
|
||||
USER="${{ github.event.comment.user.login }}"
|
||||
;;
|
||||
"pull_request_review")
|
||||
USER="${{ github.event.review.user.login }}"
|
||||
;;
|
||||
"issues")
|
||||
USER="${{ github.event.issue.user.login }}"
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "Checking repository access for user: $USER"
|
||||
|
||||
# Check if user has write access to the repository
|
||||
REPO="${{ github.repository }}"
|
||||
if gh api repos/$REPO/collaborators/$USER/permission --jq '.permission' | grep -E "(admin|write)" > /dev/null 2>&1; then
|
||||
echo "User $USER has write access to the repository"
|
||||
echo "authorized=true" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "User $USER does not have write access to the repository"
|
||||
echo "authorized=false" >> $GITHUB_OUTPUT
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Checkout repository
|
||||
if: steps.check-access.outputs.authorized == 'true'
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 1
|
||||
|
||||
- name: Run Claude Code
|
||||
if: steps.check-access.outputs.authorized == 'true'
|
||||
id: claude
|
||||
uses: anthropics/claude-code-action@beta
|
||||
with:
|
||||
anthropic_api_key: ${{ secrets.ANTHROPIC_GITHUB_API_KEY }}
|
||||
|
||||
# Optional: Specify model (defaults to Claude Sonnet 4, uncomment for Claude Opus 4)
|
||||
# model: "claude-opus-4-20250514"
|
||||
|
||||
# Optional: Customize the trigger phrase (default: @claude)
|
||||
# trigger_phrase: "/claude"
|
||||
|
||||
# Optional: Trigger when specific user is assigned to an issue
|
||||
# assignee_trigger: "claude-bot"
|
||||
|
||||
# Optional: Allow Claude to run specific commands
|
||||
# Allow bash commands to be run, for things like running tests, linting, etc.
|
||||
allowed_tools: "Bash(rg:*),Bash(find:*),Bash(grep:*),Bash(pnpm:*),Bash(npm:*),Bash(uv:*),Bash(pip:*),Bash(pipx:*),Bash(make:*),Bash(cd:*),WebFetch"
|
||||
|
||||
# Optional: Add custom instructions for Claude to customize its behavior for your project
|
||||
# custom_instructions: |
|
||||
# Follow our coding standards
|
||||
# Ensure all new code has tests
|
||||
# Use TypeScript for new files
|
||||
|
||||
# Optional: Custom environment variables for Claude
|
||||
# claude_env: |
|
||||
# NODE_ENV: test
|
||||
@@ -0,0 +1,41 @@
|
||||
name: "CodeQL"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: ["main"]
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: ["main"]
|
||||
schedule:
|
||||
- cron: "30 16 * * 4"
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
# Runner size impacts CodeQL analysis time. To learn more, please see:
|
||||
# - https://gh.io/recommended-hardware-resources-for-running-codeql
|
||||
# - https://gh.io/supported-runners-and-hardware-resources
|
||||
# - https://gh.io/using-larger-runners
|
||||
# Consider using larger runners for possible analysis time improvements.
|
||||
runs-on: "ubuntu-latest"
|
||||
timeout-minutes: 360
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v5
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v3
|
||||
with:
|
||||
languages: python
|
||||
dependency-caching: true
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v3
|
||||
with:
|
||||
category: "/language:python"
|
||||
@@ -0,0 +1,35 @@
|
||||
name: Lint - Python
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request:
|
||||
|
||||
env:
|
||||
UV_VERSION: "0.7.20"
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
# You can use PyPy versions in python-version.
|
||||
# For example, pypy-2.7 and pypy-3.8
|
||||
matrix:
|
||||
python-version: ["3.9"]
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: ${{ github.event_name == 'pull_request' && 2 || 0 }}
|
||||
- name: Install uv
|
||||
uses: astral-sh/setup-uv@v6
|
||||
with:
|
||||
version: ${{ env.UV_VERSION }}
|
||||
|
||||
- name: Set up Python
|
||||
run: uv python install ${{ matrix.python-version }}
|
||||
|
||||
- name: Run linter
|
||||
shell: bash
|
||||
working-directory: py
|
||||
run: uv run -- pre-commit run -a
|
||||
@@ -0,0 +1,37 @@
|
||||
name: Lint - TypeScript
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- "ts/**"
|
||||
pull_request:
|
||||
paths:
|
||||
- "ts/**"
|
||||
|
||||
env:
|
||||
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
|
||||
TURBO_TEAM: ${{ vars.TURBO_TEAM }}
|
||||
TURBO_REMOTE_ONLY: true
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: 10
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: "ts/llama_cloud_services/.nvmrc"
|
||||
- name: Install dependencies
|
||||
run: pnpm install --no-frozen-lockfile
|
||||
- name: Run lint
|
||||
working-directory: ts/llama_cloud_services/
|
||||
run: pnpm run lint
|
||||
- name: Run Prettier
|
||||
working-directory: ts/llama_cloud_services/
|
||||
run: pnpm run format
|
||||
@@ -0,0 +1,66 @@
|
||||
name: Publish Release - Python
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "v*"
|
||||
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
UV_VERSION: "0.7.20"
|
||||
|
||||
jobs:
|
||||
build-n-publish:
|
||||
name: Build and publish to PyPI
|
||||
if: github.repository == 'run-llama/llama_cloud_services'
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
|
||||
- name: Install uv
|
||||
uses: astral-sh/setup-uv@v6
|
||||
with:
|
||||
version: ${{ env.UV_VERSION }}
|
||||
|
||||
- name: Set up Python
|
||||
run: uv python install
|
||||
|
||||
- name: Display Python version
|
||||
run: python --version
|
||||
|
||||
- name: Build
|
||||
working-directory: py
|
||||
run: uv build
|
||||
|
||||
- name: Test installing built package
|
||||
shell: bash
|
||||
working-directory: py
|
||||
run: |
|
||||
uv venv
|
||||
uv pip install dist/*.whl
|
||||
|
||||
- name: Publish package
|
||||
shell: bash
|
||||
working-directory: py
|
||||
run: uv publish --token ${{ secrets.LLAMA_PARSE_PYPI_TOKEN }}
|
||||
|
||||
- name: Build and publish llama-parse
|
||||
working-directory: py/llama_parse/
|
||||
run: |
|
||||
uv build
|
||||
uv publish --token ${{ secrets.LLAMA_PARSE_PYPI_TOKEN }}
|
||||
|
||||
- name: Create GitHub Release
|
||||
id: create_release
|
||||
uses: actions/create-release@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token
|
||||
with:
|
||||
tag_name: ${{ github.ref }}
|
||||
release_name: ${{ github.ref }} - LlamaCloud Services PY
|
||||
artifacts: "py/**/dist/*"
|
||||
generateReleaseNotes: true
|
||||
draft: false
|
||||
prerelease: false
|
||||
@@ -0,0 +1,54 @@
|
||||
name: Publish Release - TypeScript
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "llama-cloud-services@*"
|
||||
|
||||
jobs:
|
||||
build-and-publish:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Repo
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: 10
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: "ts/llama_cloud_services/.nvmrc"
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install --no-frozen-lockfile
|
||||
|
||||
- name: Run Build
|
||||
working-directory: ts/llama_cloud_services/
|
||||
run: pnpm build
|
||||
|
||||
- name: Build tarball
|
||||
run: |
|
||||
pnpm pack
|
||||
working-directory: ts/llama_cloud_services
|
||||
|
||||
- name: Setup npm authentication
|
||||
run: echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > ~/.npmrc
|
||||
env:
|
||||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
|
||||
- name: Release
|
||||
working-directory: ts/llama_cloud_services
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
run: pnpm publish --access public --no-git-checks
|
||||
|
||||
- name: Create release
|
||||
uses: ncipollo/release-action@v1
|
||||
with:
|
||||
artifacts: "ts/llama_cloud_services/llama-cloud-services*.tgz"
|
||||
name: Release ${{ github.ref }} - LlamaCloud Services TS
|
||||
bodyFile: "ts/llama_cloud_services/CHANGELOG.md"
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -0,0 +1,38 @@
|
||||
name: Test end-to-end - Python
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- "py/**"
|
||||
|
||||
env:
|
||||
UV_VERSION: "0.7.20"
|
||||
LLAMA_CLOUD_API_KEY: ${{ secrets.LLAMA_CLOUD_API_KEY }}
|
||||
|
||||
jobs:
|
||||
test_e2e:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
# You can use PyPy versions in python-version.
|
||||
# For example, pypy-2.7 and pypy-3.8
|
||||
matrix:
|
||||
python-version: ["3.12"]
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Install uv
|
||||
uses: astral-sh/setup-uv@v6
|
||||
with:
|
||||
version: ${{ env.UV_VERSION }}
|
||||
|
||||
- name: Set up Python
|
||||
run: uv python install ${{ matrix.python-version }} && uv python pin ${{ matrix.python-version }}
|
||||
|
||||
- name: Run Tests
|
||||
working-directory: py
|
||||
run: make e2e
|
||||
|
||||
- name: Remove virtual environment
|
||||
working-directory: py
|
||||
run: rm -rf .venv/
|
||||
@@ -0,0 +1,42 @@
|
||||
name: Test - Python
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- "py/**"
|
||||
pull_request:
|
||||
paths:
|
||||
- "py/**"
|
||||
|
||||
env:
|
||||
UV_VERSION: "0.7.20"
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
# You can use PyPy versions in python-version.
|
||||
# For example, pypy-2.7 and pypy-3.8
|
||||
matrix:
|
||||
python-version: ["3.9", "3.10", "3.11", "3.12"]
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Install uv
|
||||
uses: astral-sh/setup-uv@v6
|
||||
with:
|
||||
version: ${{ env.UV_VERSION }}
|
||||
|
||||
- name: Set up Python
|
||||
run: uv python install ${{ matrix.python-version }} && uv python pin ${{ matrix.python-version }}
|
||||
|
||||
- name: Run Tests
|
||||
working-directory: py
|
||||
run: uv run pytest unit_tests/ -v
|
||||
|
||||
- name: Remove virtual environment
|
||||
working-directory: py
|
||||
run: rm -rf .venv/
|
||||
@@ -0,0 +1,42 @@
|
||||
name: Lint - TypeScript
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- "ts/**"
|
||||
pull_request:
|
||||
paths:
|
||||
- "ts/**"
|
||||
|
||||
env:
|
||||
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
|
||||
TURBO_TEAM: ${{ vars.TURBO_TEAM }}
|
||||
TURBO_REMOTE_ONLY: true
|
||||
LLAMA_CLOUD_API_KEY: ${{ secrets.LLAMA_CLOUD_API_KEY }}
|
||||
|
||||
jobs:
|
||||
test:
|
||||
name: Test - TypeScript
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: 10
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: "ts/llama_cloud_services/.nvmrc"
|
||||
- name: Install dependencies
|
||||
run: pnpm install --no-frozen-lockfile
|
||||
- name: Run Build
|
||||
working-directory: ts/llama_cloud_services/
|
||||
run: pnpm build
|
||||
- name: Run Tests
|
||||
working-directory: ts/llama_cloud_services/
|
||||
run: pnpm test
|
||||
- name: Run e2e tests
|
||||
working-directory: ts/e2e-tests/
|
||||
run: pnpm test
|
||||
@@ -1,3 +1,11 @@
|
||||
.git
|
||||
__pycache__/
|
||||
*.pyc
|
||||
*.pyc
|
||||
.DS_Store
|
||||
.idea
|
||||
.env*
|
||||
.ipynb_checkpoints*
|
||||
*_cache/
|
||||
node_modules/
|
||||
.turbo/
|
||||
dist/
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
---
|
||||
default_language_version:
|
||||
python: python3
|
||||
|
||||
repos:
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v4.5.0
|
||||
hooks:
|
||||
- id: check-byte-order-marker
|
||||
- id: check-merge-conflict
|
||||
- id: check-symlinks
|
||||
- id: check-toml
|
||||
- id: check-yaml
|
||||
- id: detect-private-key
|
||||
- id: end-of-file-fixer
|
||||
- id: mixed-line-ending
|
||||
- id: trailing-whitespace
|
||||
exclude: ^ts/llama_cloud_services/src/client/
|
||||
- repo: https://github.com/charliermarsh/ruff-pre-commit
|
||||
rev: v0.1.5
|
||||
|
||||
hooks:
|
||||
- id: ruff
|
||||
args: [--fix, --exit-non-zero-on-fix]
|
||||
exclude: ".*uv.lock"
|
||||
- repo: https://github.com/psf/black-pre-commit-mirror
|
||||
rev: 23.10.1
|
||||
hooks:
|
||||
- id: black-jupyter
|
||||
name: black-src
|
||||
alias: black
|
||||
exclude: ".*uv.lock"
|
||||
- repo: https://github.com/pre-commit/mirrors-mypy
|
||||
rev: v1.0.1
|
||||
hooks:
|
||||
- id: mypy
|
||||
exclude: ^py/tests|^py/unit_tests
|
||||
additional_dependencies:
|
||||
[
|
||||
"types-requests",
|
||||
"types-Deprecated",
|
||||
"types-redis",
|
||||
"types-setuptools",
|
||||
"types-PyYAML",
|
||||
"types-protobuf==4.24.0.4",
|
||||
]
|
||||
args:
|
||||
[
|
||||
--disallow-untyped-defs,
|
||||
--ignore-missing-imports,
|
||||
--python-version=3.10,
|
||||
]
|
||||
- repo: https://github.com/adamchainz/blacken-docs
|
||||
rev: 1.16.0
|
||||
hooks:
|
||||
- id: blacken-docs
|
||||
name: black-docs-text
|
||||
alias: black
|
||||
types_or: [rst, markdown, tex]
|
||||
additional_dependencies: [black==23.10.1]
|
||||
# Using PEP 8's line length in docs prevents excess left/right scrolling
|
||||
args: [--line-length=79]
|
||||
- repo: https://github.com/pre-commit/mirrors-prettier
|
||||
rev: v3.0.3
|
||||
hooks:
|
||||
- id: prettier
|
||||
exclude: ^(uv.lock|ts/llama_cloud_services/pnpm-lock.yaml|ts/e2e-tests)
|
||||
- repo: https://github.com/codespell-project/codespell
|
||||
rev: v2.2.6
|
||||
hooks:
|
||||
- id: codespell
|
||||
additional_dependencies: [tomli]
|
||||
exclude: ^(uv.lock|docs|ts|examples|pnpm-lock.yaml)
|
||||
args:
|
||||
[
|
||||
"--ignore-words-list",
|
||||
"astroid,gallary,momento,narl,ot,rouge,nin,gere,te,inh,vor",
|
||||
]
|
||||
- repo: https://github.com/srstevenson/nb-clean
|
||||
rev: 3.1.0
|
||||
hooks:
|
||||
- id: nb-clean
|
||||
args: [--preserve-cell-outputs, --remove-empty-cells]
|
||||
- repo: https://github.com/pappasam/toml-sort
|
||||
rev: v0.23.1
|
||||
hooks:
|
||||
- id: toml-sort-fix
|
||||
exclude: ".*uv.lock"
|
||||
|
||||
exclude: ^(.github/ISSUE_TEMPLATE|ts/llama_cloud_services/src/client|pnpm-lock.yaml)
|
||||
@@ -0,0 +1,33 @@
|
||||
# Python
|
||||
|
||||
## Installation
|
||||
|
||||
This project uses uv. Create a virtual environment, and run `uv sync`
|
||||
|
||||
## Versioning (Maintainers only)
|
||||
|
||||
Before merging your changes, make sure to bump the versions.
|
||||
|
||||
Make a version bump to `pyproject.toml`. If the underlying dependency on the llamacloud platform OpenAPI
|
||||
sdk needs bumping, make sure to bring that in as well. If updating dependencies, run `uv lock`.
|
||||
|
||||
The legacy `llama_parse` package re-exports some of `llama_cloud_services` in the old namespace. The
|
||||
versions need to be kept consistent to sidecar it with `llama_cloud_services`. Bump it's version in `llama_parse/pyproject.toml`, and also bump it's dependency version of `llama-cloud-services` to match.
|
||||
|
||||
**Note**: Don't worry about updating the `llama_parse/poetry.lock` file when bumping versions. The GitHub action will automatically run `poetry lock` for the llama_parse package during the build process (though it doesn't commit the updated lockfile back to the repo).
|
||||
|
||||
You can also do this with `./scripts/version-bump.py set 0.x.x` if you have `uv` installed.
|
||||
|
||||
Once the change is merged, push a tag `git tag -a v0.x.x -m 0.x.x` and `git push origin 0.x.x`.
|
||||
|
||||
This tagging step can be done with `./scripts/version-bump tag`.
|
||||
|
||||
# Typescript
|
||||
|
||||
## Installation
|
||||
|
||||
...
|
||||
|
||||
## Versioning
|
||||
|
||||
...
|
||||
@@ -1,61 +1,86 @@
|
||||
# LlamaParser (Preview)
|
||||
[](https://pypi.org/project/llama-cloud-services/)
|
||||
[](https://github.com/run-llama/llama_cloud_services/graphs/contributors)
|
||||
[](https://discord.gg/dGcwcsnxhU)
|
||||
|
||||
LlamaParser is an API to efficiently parse and represent files for downstream retrieval and context augmentation in your LLM / RAG application.
|
||||
# Llama Cloud Services
|
||||
|
||||
LlamaParser directly integrates with [LlamaIndex](https://github.com/run-llama/llama_index).
|
||||
This repository contains the code for hand-written SDKs and clients for interacting with LlamaCloud.
|
||||
|
||||
Currently available in preview mode for **free**. Try it out today!
|
||||
This includes:
|
||||
|
||||
**NOTE:** Currently, only PDF files are supported.
|
||||
- [LlamaParse](./parse.md) - A GenAI-native document parser that can parse complex document data for any downstream LLM use case (Agents, RAG, data processing, etc.).
|
||||
- [LlamaReport (beta/invite-only)](./report.md) - A prebuilt agentic report builder that can be used to build reports from a variety of data sources.
|
||||
- [LlamaExtract](./extract.md) - A prebuilt agentic data extractor that can be used to transform data into a structured JSON representation.
|
||||
- [LlamaCloud Index](./index.md) - A widely customizable and fully automated document ingestion pipeline that also serves retrieval purposes.
|
||||
|
||||
## Getting Started
|
||||
|
||||
First, login and get an api-key from `https://cloud.llamaindex.ai`.
|
||||
|
||||
Install the package:
|
||||
|
||||
`pip install llama-parser`
|
||||
|
||||
Then, you can run the following to parse your first PDF file:
|
||||
|
||||
```python
|
||||
from llama_parser import LlamaParser
|
||||
|
||||
parser = LlamaParser(
|
||||
api_key="...", # can also be set in your env as LLAMA_CLOUD_API_KEY
|
||||
result_type="markdown" # "markdown" and "text" are available
|
||||
)
|
||||
|
||||
# sync
|
||||
documents = parser.load_data("./my_file.pdf")
|
||||
|
||||
# async
|
||||
documents = await parser.aload_data("./my_file.pdf")
|
||||
```bash
|
||||
pip install llama-cloud-services
|
||||
```
|
||||
|
||||
## Using with `SimpleDirectoryReader`
|
||||
Then, get your API key from [LlamaCloud](https://cloud.llamaindex.ai/).
|
||||
|
||||
You can also integrate the parser as the default PDF loader in `SimpleDirectoryReader`:
|
||||
Then, you can use the services in your code:
|
||||
|
||||
```python
|
||||
from llama_parser import LlamaParser
|
||||
from llama_index import SimpleDirectoryReader
|
||||
|
||||
parser = LlamaParser(
|
||||
api_key="...", # can also be set in your env as LLAMA_CLOUD_API_KEY
|
||||
result_type="markdown" # "markdown" and "text" are available
|
||||
from llama_cloud_services import (
|
||||
LlamaParse,
|
||||
LlamaReport,
|
||||
LlamaExtract,
|
||||
LlamaCloudIndex,
|
||||
)
|
||||
|
||||
file_extractor = {".pdf": parser}
|
||||
documents = SimpleDirectoryReader("./data", file_extractor=file_extractor).load_data()
|
||||
parser = LlamaParse(api_key="YOUR_API_KEY")
|
||||
report = LlamaReport(api_key="YOUR_API_KEY")
|
||||
extract = LlamaExtract(api_key="YOUR_API_KEY")
|
||||
index = LlamaCloudIndex(
|
||||
"my_first_index", project_name="default", api_key="YOUR_API_KEY"
|
||||
)
|
||||
```
|
||||
|
||||
Full documentation for `SimpleDirectoryReader` can be found on the [LlamaIndex Documentation](https://docs.llamaindex.ai/en/stable/module_guides/loading/simpledirectoryreader.html).
|
||||
See the quickstart guides for each service for more information:
|
||||
|
||||
## Examples
|
||||
- [LlamaParse](./parse.md)
|
||||
- [LlamaReport (beta/invite-only)](./report.md)
|
||||
- [LlamaExtract](./extract.md)
|
||||
- [LlamaCloud Index](./index.md)
|
||||
|
||||
Serveral end-to-end indexing examples can be found in the examples folder
|
||||
## Switch to EU SaaS 🇪🇺
|
||||
|
||||
- [Getting Started](examples/demo_basic.ipynb)
|
||||
- [Advanced RAG Example](examples/demo_advanced.ipynb)
|
||||
- [Raw API Usage](examples/demo_api.ipynb)
|
||||
If you are interested in using LlamaCloud services in the EU, you can adjust your base URL to `https://api.cloud.eu.llamaindex.ai`.
|
||||
|
||||
You can also create your API key in the EU region [here](https://cloud.eu.llamaindex.ai).
|
||||
|
||||
```python
|
||||
from llama_cloud_services import (
|
||||
LlamaParse,
|
||||
LlamaReport,
|
||||
LlamaExtract,
|
||||
EU_BASE_URL,
|
||||
)
|
||||
|
||||
parser = LlamaParse(api_key="YOUR_API_KEY", base_url=EU_BASE_URL)
|
||||
report = LlamaReport(api_key="YOUR_API_KEY", base_url=EU_BASE_URL)
|
||||
extract = LlamaExtract(api_key="YOUR_API_KEY", base_url=EU_BASE_URL)
|
||||
index = LlamaCloudIndex(
|
||||
"my_first_index",
|
||||
project_name="default",
|
||||
api_key="YOUR_API_KEY",
|
||||
base_url=EU_BASE_URL,
|
||||
)
|
||||
```
|
||||
|
||||
## Documentation
|
||||
|
||||
You can see complete SDK and API documentation for each service on [our official docs](https://docs.cloud.llamaindex.ai/).
|
||||
|
||||
## Terms of Service
|
||||
|
||||
See the [Terms of Service Here](./TOS.pdf).
|
||||
|
||||
## Get in Touch (LlamaCloud)
|
||||
|
||||
You can get in touch with us by following our [contact link](https://www.llamaindex.ai/contact).
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
# LlamaCloud Services Examples - Python
|
||||
|
||||
In this folder you will find several TypeScript end-to-end applications that contain examples regarding:
|
||||
|
||||
- [LlamaParse](./parse/)
|
||||
- [LlamaCloud Index](./index/)
|
||||
|
||||
Follow the instructions in each example folder to get started!
|
||||
@@ -0,0 +1,122 @@
|
||||
# LlamaExtract Demo
|
||||
|
||||
A TypeScript demo application showcasing the power of **LlamaExract** - a structured data extraction agentic service from [LlamaCloud](https://cloud.llamaindex.ai). This demo allows you to extract structured information from scientific papers and get them into a nice markdown format.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Features](#features)
|
||||
- [Prerequisites](#prerequisites)
|
||||
- [Installation](#installation)
|
||||
- [Usage](#usage)
|
||||
- [Start the Demo](#start-the-demo)
|
||||
- [Development Mode](#development-mode)
|
||||
- [Build the Project](#build-the-project)
|
||||
- [Code Quality](#code-quality)
|
||||
- [Quick Commands Reference](#quick-commands-reference)
|
||||
- [How It Works](#how-it-works)
|
||||
- [API Dependencies](#api-dependencies)
|
||||
- [Troubleshooting](#troubleshooting)
|
||||
- [Common Issues](#common-issues)
|
||||
- [License](#license)
|
||||
- [Contributing](#contributing)
|
||||
|
||||
## Features
|
||||
|
||||
- 📄 **Structured Data Extraction**: Extract data from your files effortlessly, and structure them the way you want!
|
||||
- 🤖 **Markdown Rendering**: Generate markdown directly from your extracted data
|
||||
- 🎨 **Beautiful CLI**: Styled console interface with colors and ASCII art
|
||||
- ⚡ **Fast Development**: Hot reload support with watch mode
|
||||
- 🛠️ **TypeScript**: Full TypeScript support with strict type checking
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Node.js (version 18 or higher)
|
||||
- pnpm package manager
|
||||
- LlamaCloud API key
|
||||
|
||||
## Installation
|
||||
|
||||
1. Clone the repository:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/run-llama/llama_cloud_services
|
||||
cd lama_cloud_services/examples-ts/extract/
|
||||
```
|
||||
|
||||
2. Install dependencies:
|
||||
|
||||
```bash
|
||||
npm install
|
||||
```
|
||||
|
||||
3. Set up your environment variables:
|
||||
|
||||
```bash
|
||||
# Add your API key to your environment
|
||||
export LLAMA_CLOUD_API_KEY="your-llamacloud-api-key"
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### Start the Demo
|
||||
|
||||
```bash
|
||||
npm run start
|
||||
```
|
||||
|
||||
The application will display a welcome screen and prompt you to enter the path to a document you'd like to process.
|
||||
|
||||
### Development Mode
|
||||
|
||||
For development with hot reload:
|
||||
|
||||
```bash
|
||||
npm run dev
|
||||
```
|
||||
|
||||
### Build the Project
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
```
|
||||
|
||||
### Code Quality
|
||||
|
||||
Format code:
|
||||
|
||||
```bash
|
||||
npm run format
|
||||
```
|
||||
|
||||
Lint code:
|
||||
|
||||
```bash
|
||||
npm run lint
|
||||
```
|
||||
|
||||
## How It Works
|
||||
|
||||
1. **Document Input**: Enter the path to your document when prompted
|
||||
2. **Parsing**: LlamaExtract, based on the schema you can find [here](./src/schema.ts), processes the document and extracts structured data
|
||||
3. **Markdown Rendering**: The extracted content is rendered into beautiful markdown
|
||||
4. **Results**: View the results directly in your terminal
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
1. **Module Resolution Errors**: Ensure you're using Node.js 18+ and have all dependencies installed
|
||||
2. **API Key Issues**: Verify your LlamaCloud API key is correctly set
|
||||
3. **File Path Errors**: Use absolute paths or ensure relative paths are correct from the project root
|
||||
|
||||
## License
|
||||
|
||||
MIT License - see the [LICENSE](../../LICENSE) file for details.
|
||||
|
||||
## Contributing
|
||||
|
||||
1. Fork the repository
|
||||
2. Create a feature branch
|
||||
3. Make your changes
|
||||
4. Run `npm run format` and `npm run lint`
|
||||
5. Submit a pull request
|
||||
@@ -0,0 +1,14 @@
|
||||
import js from "@eslint/js";
|
||||
import globals from "globals";
|
||||
import tseslint from "typescript-eslint";
|
||||
import { defineConfig } from "eslint/config";
|
||||
|
||||
export default defineConfig([
|
||||
{
|
||||
files: ["**/*.{js,mjs,cjs,ts,mts,cts}"],
|
||||
plugins: { js },
|
||||
extends: ["js/recommended"],
|
||||
languageOptions: { globals: globals.browser },
|
||||
},
|
||||
tseslint.configs.recommended,
|
||||
]);
|
||||
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"name": "llama-extract-demo",
|
||||
"version": "0.1.0",
|
||||
"description": "Demo for LlamaExtract in TypeScript",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"There are no tests\"",
|
||||
"start": "npm exec tsx src/index.ts",
|
||||
"lint": "eslint ./src/",
|
||||
"format": "prettier --write ./src/",
|
||||
"build": "tsc",
|
||||
"dev": "npm exec tsx --watch src/index.ts"
|
||||
},
|
||||
"author": "LlamaIndex",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"cli-markdown": "^3.5.1",
|
||||
"consola": "^3.4.2",
|
||||
"figlet": "^1.8.2",
|
||||
"llama-cloud-services": "file:../../ts/llama_cloud_services",
|
||||
"marked": "^15.0.12",
|
||||
"marked-terminal": "^7.3.0",
|
||||
"picocolors": "^1.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.32.0",
|
||||
"@types/figlet": "^1.7.0",
|
||||
"@types/marked-terminal": "^6.1.1",
|
||||
"@types/node": "^24.2.0",
|
||||
"eslint": "^9.32.0",
|
||||
"globals": "^16.3.0",
|
||||
"jiti": "^2.5.1",
|
||||
"prettier": "^3.6.2",
|
||||
"typescript": "^5.9.2",
|
||||
"typescript-eslint": "^8.39.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
import { LlamaExtract, ExtractConfig } from "llama-cloud-services";
|
||||
import cliMarkdown from "cli-markdown";
|
||||
import { logger } from "./logger";
|
||||
import pc from "picocolors";
|
||||
import { consoleInput, renderLogo } from "./utils";
|
||||
import { dataSchema } from "./schema";
|
||||
import { renderMarkdown, ResearchData } from "./markdown";
|
||||
|
||||
export async function main(): Promise<number> {
|
||||
const extractClient = new LlamaExtract(
|
||||
process.env.LLAMA_CLOUD_API_KEY!,
|
||||
"https://api.cloud.llamaindex.ai",
|
||||
);
|
||||
await renderLogo();
|
||||
logger.log(
|
||||
`Welcome to ${pc.bold(
|
||||
pc.magentaBright("LlamaExtract Demo✨"),
|
||||
)}, our demo for ${pc.bold(pc.green("LlamaExtract"))}, a ${pc.bold(
|
||||
pc.cyan("LlamaCloud☁️"),
|
||||
)} (https://cloud.llamaindex.ai) product!.\nIn this demo we are going to try extracting relevant information ${pc.bold(
|
||||
pc.yellowBright("from scientific papers"),
|
||||
)}. Type the path to the paper you would like to process below👇\nIf you wish to exit, just type ${pc.bold(
|
||||
pc.gray("quit"),
|
||||
)}.\n`,
|
||||
);
|
||||
while (true) {
|
||||
const userInput = await consoleInput();
|
||||
if (userInput.toLowerCase() == "quit") {
|
||||
break;
|
||||
}
|
||||
try {
|
||||
const generatedData = await extractClient.extract(
|
||||
dataSchema,
|
||||
{} as ExtractConfig,
|
||||
userInput,
|
||||
);
|
||||
const research = renderMarkdown(generatedData?.data as ResearchData); // Added await here
|
||||
logger.log(`${pc.bold(pc.cyan("Extracted information:✨"))}:\n`);
|
||||
logger.log(cliMarkdown(research));
|
||||
} catch (error) {
|
||||
logger.error(`Error processing file: ${error}`);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
main().catch(console.error);
|
||||
@@ -0,0 +1,8 @@
|
||||
import { createConsola } from "consola";
|
||||
import type { ConsolaInstance } from "consola";
|
||||
|
||||
export const logger: ConsolaInstance = createConsola({
|
||||
formatOptions: {
|
||||
date: false,
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,172 @@
|
||||
type Author = {
|
||||
name: string;
|
||||
affiliation?: string;
|
||||
email?: string;
|
||||
};
|
||||
|
||||
type Methodology = {
|
||||
approach?: string;
|
||||
participants?: string;
|
||||
methods?: string[];
|
||||
};
|
||||
|
||||
type Result = {
|
||||
finding?: string;
|
||||
significance?: string;
|
||||
supportingData?: string;
|
||||
};
|
||||
|
||||
type Reference = {
|
||||
title: string;
|
||||
authors: string;
|
||||
year?: string;
|
||||
relevance?: string;
|
||||
};
|
||||
|
||||
type Discussion = {
|
||||
implications?: string[];
|
||||
limitations?: string[];
|
||||
futureWork?: string[];
|
||||
};
|
||||
|
||||
type Publication = {
|
||||
journal?: string;
|
||||
year: string;
|
||||
doi?: string;
|
||||
url?: string;
|
||||
};
|
||||
|
||||
export type ResearchData = {
|
||||
title: string;
|
||||
authors: Author[];
|
||||
abstract: string;
|
||||
keywords?: string[];
|
||||
mainFindings: string[];
|
||||
methodology?: Methodology;
|
||||
results?: Result[];
|
||||
discussion?: Discussion;
|
||||
references?: Reference[];
|
||||
publication?: Publication;
|
||||
};
|
||||
|
||||
export function renderMarkdown(data: ResearchData): string {
|
||||
const {
|
||||
title,
|
||||
authors,
|
||||
abstract,
|
||||
keywords,
|
||||
mainFindings,
|
||||
methodology,
|
||||
results,
|
||||
discussion,
|
||||
references,
|
||||
publication,
|
||||
} = data;
|
||||
|
||||
const md: string[] = [];
|
||||
|
||||
md.push(`# ${title}\n`);
|
||||
|
||||
// Authors
|
||||
md.push(`## Authors`);
|
||||
md.push(
|
||||
authors
|
||||
.map(
|
||||
(author) =>
|
||||
`- **${author.name}**${
|
||||
author.affiliation ? `, *${author.affiliation}*` : ""
|
||||
}${author.email ? ` (${author.email})` : ""}`,
|
||||
)
|
||||
.join("\n"),
|
||||
);
|
||||
|
||||
// Abstract
|
||||
md.push(`\n## Abstract\n${abstract}`);
|
||||
|
||||
// Keywords
|
||||
if (keywords && keywords.length > 0) {
|
||||
md.push(`\n## Keywords\n${keywords.map((k) => `- ${k}`).join("\n")}`);
|
||||
}
|
||||
|
||||
// Main Findings
|
||||
md.push(
|
||||
`\n## Main Findings\n${mainFindings.map((f) => `- ${f}`).join("\n")}`,
|
||||
);
|
||||
|
||||
// Methodology
|
||||
if (methodology) {
|
||||
md.push(`\n## Methodology`);
|
||||
if (methodology.approach) md.push(`**Approach:** ${methodology.approach}`);
|
||||
if (methodology.participants)
|
||||
md.push(`**Participants:** ${methodology.participants}`);
|
||||
if (methodology.methods?.length) {
|
||||
md.push(
|
||||
`**Methods:**\n${methodology.methods.map((m) => `- ${m}`).join("\n")}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Results
|
||||
if (results?.length) {
|
||||
md.push(`\n## Results`);
|
||||
results.forEach((result, i) => {
|
||||
md.push(`\n### Result ${i + 1}`);
|
||||
if (result.finding) md.push(`- **Finding:** ${result.finding}`);
|
||||
if (result.significance)
|
||||
md.push(`- **Significance:** ${result.significance}`);
|
||||
if (result.supportingData)
|
||||
md.push(`- **Supporting Data:** ${result.supportingData}`);
|
||||
});
|
||||
}
|
||||
|
||||
// Discussion
|
||||
if (discussion) {
|
||||
md.push(`\n## Discussion`);
|
||||
if (discussion.implications?.length) {
|
||||
md.push(
|
||||
`### Implications\n${discussion.implications
|
||||
.map((d) => `- ${d}`)
|
||||
.join("\n")}`,
|
||||
);
|
||||
}
|
||||
if (discussion.limitations?.length) {
|
||||
md.push(
|
||||
`### Limitations\n${discussion.limitations
|
||||
.map((d) => `- ${d}`)
|
||||
.join("\n")}`,
|
||||
);
|
||||
}
|
||||
if (discussion.futureWork?.length) {
|
||||
md.push(
|
||||
`### Future Work\n${discussion.futureWork
|
||||
.map((d) => `- ${d}`)
|
||||
.join("\n")}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// References
|
||||
if (references?.length) {
|
||||
md.push(`\n## References`);
|
||||
references.forEach((ref, i) => {
|
||||
md.push(
|
||||
`\n**[${i + 1}]** ${ref.title} — *${ref.authors}*${
|
||||
ref.year ? ` (${ref.year})` : ""
|
||||
}`,
|
||||
);
|
||||
if (ref.relevance) md.push(`> ${ref.relevance}`);
|
||||
});
|
||||
}
|
||||
|
||||
// Publication Info
|
||||
if (publication) {
|
||||
md.push(`\n## Publication`);
|
||||
if (publication.journal) md.push(`- **Journal:** ${publication.journal}`);
|
||||
if (publication.year) md.push(`- **Year:** ${publication.year}`);
|
||||
if (publication.doi) md.push(`- **DOI:** ${publication.doi}`);
|
||||
if (publication.url)
|
||||
md.push(`- **URL:** [${publication.url}](${publication.url})`);
|
||||
}
|
||||
|
||||
return md.join("\n");
|
||||
}
|
||||
@@ -0,0 +1,169 @@
|
||||
export const dataSchema = {
|
||||
type: "object",
|
||||
required: ["title", "authors", "abstract", "mainFindings"],
|
||||
properties: {
|
||||
title: {
|
||||
type: "string",
|
||||
description: "The full title of the research paper",
|
||||
},
|
||||
authors: {
|
||||
type: "array",
|
||||
description: "List of all authors of the paper",
|
||||
items: {
|
||||
type: "object",
|
||||
properties: {
|
||||
name: {
|
||||
type: "string",
|
||||
description: "Full name of the author",
|
||||
},
|
||||
affiliation: {
|
||||
type: "string",
|
||||
description:
|
||||
"Institution or organization the author is affiliated with",
|
||||
},
|
||||
email: {
|
||||
type: "string",
|
||||
description: "Contact email of the author if provided",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
abstract: {
|
||||
type: "string",
|
||||
description: "Complete abstract or summary of the paper",
|
||||
},
|
||||
keywords: {
|
||||
type: "array",
|
||||
description:
|
||||
"Key terms and phrases that describe the paper's main topics",
|
||||
items: {
|
||||
type: "string",
|
||||
},
|
||||
},
|
||||
mainFindings: {
|
||||
type: "array",
|
||||
description: "Key findings, conclusions, or contributions of the paper",
|
||||
items: {
|
||||
type: "string",
|
||||
},
|
||||
},
|
||||
methodology: {
|
||||
type: "object",
|
||||
description: "Research methods and approaches used",
|
||||
properties: {
|
||||
approach: {
|
||||
type: "string",
|
||||
description: "Overall research approach or study design",
|
||||
},
|
||||
participants: {
|
||||
type: "string",
|
||||
description: "Description of study participants or data sources",
|
||||
},
|
||||
methods: {
|
||||
type: "array",
|
||||
description: "Specific methods, techniques, or tools used",
|
||||
items: {
|
||||
type: "string",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
results: {
|
||||
type: "array",
|
||||
description: "Main results and outcomes of the research",
|
||||
items: {
|
||||
type: "object",
|
||||
properties: {
|
||||
finding: {
|
||||
type: "string",
|
||||
description: "Description of the specific result or finding",
|
||||
},
|
||||
significance: {
|
||||
type: "string",
|
||||
description:
|
||||
"Statistical significance or importance of the finding",
|
||||
},
|
||||
supportingData: {
|
||||
type: "string",
|
||||
description: "Relevant statistics, measurements, or data points",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
discussion: {
|
||||
type: "object",
|
||||
properties: {
|
||||
implications: {
|
||||
type: "array",
|
||||
description: "Theoretical or practical implications of the findings",
|
||||
items: {
|
||||
type: "string",
|
||||
},
|
||||
},
|
||||
limitations: {
|
||||
type: "array",
|
||||
description: "Study limitations or constraints",
|
||||
items: {
|
||||
type: "string",
|
||||
},
|
||||
},
|
||||
futureWork: {
|
||||
type: "array",
|
||||
description: "Suggested future research directions",
|
||||
items: {
|
||||
type: "string",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
references: {
|
||||
type: "array",
|
||||
description:
|
||||
"Key papers cited that are crucial to understanding this work",
|
||||
items: {
|
||||
type: "object",
|
||||
properties: {
|
||||
title: {
|
||||
type: "string",
|
||||
description: "Title of the cited paper",
|
||||
},
|
||||
authors: {
|
||||
type: "string",
|
||||
description: "Authors of the cited paper",
|
||||
},
|
||||
year: {
|
||||
type: "string",
|
||||
description: "Publication year",
|
||||
},
|
||||
relevance: {
|
||||
type: "string",
|
||||
description: "Why this reference is important to the current paper",
|
||||
},
|
||||
},
|
||||
required: ["title", "authors"],
|
||||
},
|
||||
},
|
||||
publication: {
|
||||
type: "object",
|
||||
properties: {
|
||||
journal: {
|
||||
type: "string",
|
||||
description: "Name of the journal or conference",
|
||||
},
|
||||
year: {
|
||||
type: "string",
|
||||
description: "Year of publication",
|
||||
},
|
||||
doi: {
|
||||
type: "string",
|
||||
description: "Digital Object Identifier (DOI) of the paper",
|
||||
},
|
||||
url: {
|
||||
type: "string",
|
||||
description: "URL where the paper can be accessed",
|
||||
},
|
||||
},
|
||||
required: ["year"],
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,4 @@
|
||||
declare module "cli-markdown" {
|
||||
function cliMarkdown(input: string): string;
|
||||
export default cliMarkdown;
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
import * as readline from "readline/promises";
|
||||
import figlet from "figlet";
|
||||
import pc from "picocolors";
|
||||
|
||||
export async function renderLogo(): Promise<void> {
|
||||
const logoText = figlet.textSync("Extract Demo", {
|
||||
font: "ANSI Shadow",
|
||||
horizontalLayout: "default",
|
||||
verticalLayout: "default",
|
||||
width: 100,
|
||||
whitespaceBreak: true,
|
||||
});
|
||||
|
||||
// Add some styling with picocolors
|
||||
const styledLogo = pc.bold(pc.redBright(logoText));
|
||||
|
||||
// Add some padding/margin
|
||||
console.log("\n");
|
||||
console.log(styledLogo);
|
||||
console.log(pc.gray("─".repeat(60)));
|
||||
console.log("\n");
|
||||
}
|
||||
|
||||
export async function consoleInput(): Promise<string> {
|
||||
const rl = readline.createInterface({
|
||||
input: process.stdin,
|
||||
output: process.stdout,
|
||||
});
|
||||
|
||||
const answer = await rl.question("Path to your file: ");
|
||||
rl.close();
|
||||
return answer;
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
# LlamaCloud Index Demo
|
||||
|
||||
A TypeScript demo application showcasing the power of **LlamaCloud Index** - a fully automated document ingestion and retrieval serviced offered within [LlamaCloud](https://cloud.llamaindex.ai). This demo allows you to ask questions, retrieve relevant contextual information and generate AI-powered responses using OpenAI's GPT models.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Features](#features)
|
||||
- [Prerequisites](#prerequisites)
|
||||
- [Installation](#installation)
|
||||
- [Usage](#usage)
|
||||
- [Start the Demo](#start-the-demo)
|
||||
- [Development Mode](#development-mode)
|
||||
- [Build the Project](#build-the-project)
|
||||
- [Code Quality](#code-quality)
|
||||
- [Quick Commands Reference](#quick-commands-reference)
|
||||
- [How It Works](#how-it-works)
|
||||
- [API Dependencies](#api-dependencies)
|
||||
- [Troubleshooting](#troubleshooting)
|
||||
- [Common Issues](#common-issues)
|
||||
- [License](#license)
|
||||
- [Contributing](#contributing)
|
||||
|
||||
## Features
|
||||
|
||||
- 🤖 **RAG**: Simple-yet-effective Retrieval Augmented Generation pipeline built on top of LlamaCloud Index and OpenAI
|
||||
- 🎨 **Beautiful CLI**: Styled console interface with colors and ASCII art
|
||||
- ⚡ **Fast Development**: Hot reload support with watch mode
|
||||
- 🛠️ **TypeScript**: Full TypeScript support with strict type checking
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Node.js (version 18 or higher)
|
||||
- pnpm package manager
|
||||
- OpenAI API key
|
||||
- LlamaCloud API key
|
||||
- An existing LlamaCloud Index pipeline
|
||||
|
||||
## Installation
|
||||
|
||||
1. Clone the repository:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/run-llama/llama_cloud_services
|
||||
cd lama_cloud_services/examples-ts/index/
|
||||
```
|
||||
|
||||
2. Install dependencies:
|
||||
|
||||
```bash
|
||||
pnpm install
|
||||
```
|
||||
|
||||
3. Set up your environment variables:
|
||||
|
||||
```bash
|
||||
export OPENAI_API_KEY="your-openai-api-key"
|
||||
export LLAMA_CLOUD_API_KEY="your-llamacloud-api-key"
|
||||
export PIPELINE_NAME="your-pipeline-name"
|
||||
```
|
||||
|
||||
4. Or write them into a `.env` file:
|
||||
|
||||
```env
|
||||
OPENAI_API_KEY="your-openai-api-key"
|
||||
LLAMA_CLOUD_API_KEY="your-llamacloud-api-key"
|
||||
PIPELINE_NAME="your-pipeline-name"
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### Start the Demo
|
||||
|
||||
```bash
|
||||
pnpm run start
|
||||
```
|
||||
|
||||
The application will display a welcome screen and prompt you to start chatting!
|
||||
|
||||
### Development Mode
|
||||
|
||||
For development with hot reload:
|
||||
|
||||
```bash
|
||||
pnpm run dev
|
||||
```
|
||||
|
||||
### Build the Project
|
||||
|
||||
```bash
|
||||
pnpm run build
|
||||
```
|
||||
|
||||
### Code Quality
|
||||
|
||||
Format code:
|
||||
|
||||
```bash
|
||||
pnpm run format
|
||||
```
|
||||
|
||||
Lint code:
|
||||
|
||||
```bash
|
||||
pnpm run lint
|
||||
```
|
||||
|
||||
## How It Works
|
||||
|
||||
1. **Message Input**: Enter a message
|
||||
2. **Retrieval**: Several nodes are retrieved from the LlamaCloud index you specified
|
||||
3. **AI Response Generation**: The retrieved information is passed on to the AI model, along with its relevance score, and a reply to your original message is generated starting from that.
|
||||
4. **Results**: View the AI-generated summary in your terminal
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
1. **Module Resolution Errors**: Ensure you're using Node.js 18+ and have all dependencies installed
|
||||
2. **API Key Issues**: Verify your OpenAI and LlamaCloud API keys are correctly set
|
||||
|
||||
## License
|
||||
|
||||
MIT License - see the [LICENSE](../../LICENSE) file for details.
|
||||
|
||||
## Contributing
|
||||
|
||||
1. Fork the repository
|
||||
2. Create a feature branch
|
||||
3. Make your changes
|
||||
4. Run `pnpm run format` and `pnpm run lint`
|
||||
5. Submit a pull request
|
||||
@@ -0,0 +1,15 @@
|
||||
import js from "@eslint/js";
|
||||
import globals from "globals";
|
||||
import tseslint from "typescript-eslint";
|
||||
import { defineConfig } from "eslint/config";
|
||||
|
||||
export default defineConfig([
|
||||
{
|
||||
files: ["**/*.{js,mjs,cjs,ts,mts,cts}"],
|
||||
plugins: { js },
|
||||
extends: ["js/recommended"],
|
||||
languageOptions: { globals: globals.browser },
|
||||
},
|
||||
{ files: ["**/*.js"], languageOptions: { sourceType: "script" } },
|
||||
tseslint.configs.recommended,
|
||||
]);
|
||||
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"name": "llama-chat",
|
||||
"version": "0.1.0",
|
||||
"description": "Demo for LlamaCloud Index in TypeScript",
|
||||
"type": "module",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"There are no tests\"",
|
||||
"start": "pnpm exec tsx src/index.ts",
|
||||
"lint": "eslint ./src/",
|
||||
"format": "prettier --write ./src/",
|
||||
"build": "tsc",
|
||||
"dev": "pnpm exec tsx --watch src/index.ts"
|
||||
},
|
||||
"keywords": [
|
||||
"ai",
|
||||
"rag",
|
||||
"retrieval",
|
||||
"pipeline",
|
||||
"llms",
|
||||
"chatbot"
|
||||
],
|
||||
"author": "LlamaIndex",
|
||||
"license": "MIT",
|
||||
"packageManager": "pnpm@10.12.4",
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.32.0",
|
||||
"@types/figlet": "^1.7.0",
|
||||
"@types/node": "^24.1.0",
|
||||
"@typescript-eslint/eslint-plugin": "^8.38.0",
|
||||
"@typescript-eslint/parser": "^8.38.0",
|
||||
"eslint": "^9.32.0",
|
||||
"globals": "^16.3.0",
|
||||
"jiti": "^2.5.1",
|
||||
"prettier": "^3.6.2",
|
||||
"typescript": "^5.8.3",
|
||||
"typescript-eslint": "^8.38.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ai-sdk/openai": "^1.3.23",
|
||||
"ai": "^4.3.19",
|
||||
"consola": "^3.4.2",
|
||||
"dotenv": "^17.2.1",
|
||||
"figlet": "^1.8.2",
|
||||
"llama-cloud-services": "link:../../ts/llama_cloud_services",
|
||||
"picocolors": "^1.1.1"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
import { LlamaCloudIndex } from "llama-cloud-services";
|
||||
import { logger } from "./logger";
|
||||
import pc from "picocolors";
|
||||
import {
|
||||
consoleInput,
|
||||
retrievalAugmentedGeneration,
|
||||
renderLogo,
|
||||
} from "./utils";
|
||||
import dotenv from "dotenv";
|
||||
|
||||
dotenv.config();
|
||||
|
||||
export async function main(): Promise<number> {
|
||||
const index = new LlamaCloudIndex({
|
||||
name: process.env.PIPELINE_NAME as string,
|
||||
projectName: "Default",
|
||||
apiKey: process.env.LLAMA_CLOUD_API_KEY, // can provide API-key in the constructor or in the env
|
||||
});
|
||||
const retriever = index.asRetriever({
|
||||
similarityTopK: 5,
|
||||
});
|
||||
await renderLogo();
|
||||
logger.log(
|
||||
`Welcome to ${pc.bold(
|
||||
pc.magentaBright("✨LlamaChat✨"),
|
||||
)}, our demo for ${pc.bold(pc.green("Index🦙"))}, a ${pc.bold(
|
||||
pc.cyan("LlamaCloud☁️"),
|
||||
)} (https://cloud.llamaindex.ai) product!.\nType a question below, and you will get an answer!👇\nIf you wish to exit, just type ${pc.bold(
|
||||
pc.gray("quit"),
|
||||
)}.\n`,
|
||||
);
|
||||
while (true) {
|
||||
const userInput = await consoleInput();
|
||||
if (userInput.toLowerCase() == "quit") {
|
||||
break;
|
||||
}
|
||||
try {
|
||||
const nodes = await retriever.retrieve(userInput);
|
||||
const summary = await retrievalAugmentedGeneration(nodes, userInput);
|
||||
logger.log(`${pc.bold(pc.magentaBright("LlamaChat✨:"))}\n${summary}`);
|
||||
} catch (error) {
|
||||
logger.error(`Error processing your request: ${error}`);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
main().catch(console.error);
|
||||
@@ -0,0 +1,8 @@
|
||||
import { createConsola } from "consola";
|
||||
import type { ConsolaInstance } from "consola";
|
||||
|
||||
export const logger: ConsolaInstance = createConsola({
|
||||
formatOptions: {
|
||||
date: false,
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,56 @@
|
||||
import { generateText } from "ai";
|
||||
import { openai } from "@ai-sdk/openai";
|
||||
import { NodeWithScore, MetadataMode } from "llamaindex";
|
||||
import * as readline from "readline/promises";
|
||||
import figlet from "figlet";
|
||||
import pc from "picocolors";
|
||||
|
||||
export async function renderLogo(): Promise<void> {
|
||||
const logoText = figlet.textSync("LlamaChat", {
|
||||
font: "ANSI Shadow",
|
||||
horizontalLayout: "default",
|
||||
verticalLayout: "default",
|
||||
width: 100,
|
||||
whitespaceBreak: true,
|
||||
});
|
||||
|
||||
// Add some styling with picocolors
|
||||
const styledLogo = pc.bold(pc.yellowBright(logoText));
|
||||
|
||||
// Add some padding/margin
|
||||
console.log("\n");
|
||||
console.log(styledLogo);
|
||||
console.log(pc.gray("─".repeat(60)));
|
||||
console.log("\n");
|
||||
}
|
||||
|
||||
export async function consoleInput(): Promise<string> {
|
||||
const rl = readline.createInterface({
|
||||
input: process.stdin,
|
||||
output: process.stdout,
|
||||
});
|
||||
|
||||
const answer = await rl.question(pc.cyanBright("You✨:"));
|
||||
rl.close();
|
||||
return answer;
|
||||
}
|
||||
|
||||
export async function retrievalAugmentedGeneration(
|
||||
nodes: NodeWithScore[],
|
||||
prompt: string,
|
||||
): Promise<string> {
|
||||
let mainText: string = "";
|
||||
|
||||
for (const node of nodes) {
|
||||
mainText += `\t{information: '${node.node.getContent(
|
||||
MetadataMode.ALL,
|
||||
)}', relevanceScore: '${node.score ?? "no score"}'}\n`;
|
||||
}
|
||||
|
||||
const { text } = await generateText({
|
||||
model: openai("gpt-4.1"),
|
||||
prompt: `[\n${mainText}\n]\n\nBased on the information you are given and on the relevance score of that (where -1 means no score available), answer to this user prompt: '${prompt}'`,
|
||||
});
|
||||
|
||||
return text;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2022",
|
||||
"module": "ES2022",
|
||||
"lib": ["ES2022"],
|
||||
"outDir": "./dist",
|
||||
"rootDir": "./src",
|
||||
"strict": true,
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"sourceMap": true,
|
||||
"types": ["node"],
|
||||
"moduleResolution": "bundler",
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"resolveJsonModule": true
|
||||
},
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["node_modules", "dist"]
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
# LlamaParse Demo
|
||||
|
||||
A TypeScript demo application showcasing the power of **LlamaParse** - an intelligent document parsing service from [LlamaCloud](https://cloud.llamaindex.ai). This demo allows you to parse various document formats and generate AI-powered summaries using OpenAI's GPT models.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Features](#features)
|
||||
- [Prerequisites](#prerequisites)
|
||||
- [Installation](#installation)
|
||||
- [Usage](#usage)
|
||||
- [Start the Demo](#start-the-demo)
|
||||
- [Development Mode](#development-mode)
|
||||
- [Build the Project](#build-the-project)
|
||||
- [Code Quality](#code-quality)
|
||||
- [Quick Commands Reference](#quick-commands-reference)
|
||||
- [How It Works](#how-it-works)
|
||||
- [API Dependencies](#api-dependencies)
|
||||
- [Troubleshooting](#troubleshooting)
|
||||
- [Common Issues](#common-issues)
|
||||
- [License](#license)
|
||||
- [Contributing](#contributing)
|
||||
|
||||
## Features
|
||||
|
||||
- 📄 **Document Parsing**: Parse PDFs, Word docs, and other formats using LlamaParse
|
||||
- 🤖 **AI Summaries**: Generate intelligent summaries using OpenAI GPT-4
|
||||
- 🎨 **Beautiful CLI**: Styled console interface with colors and ASCII art
|
||||
- ⚡ **Fast Development**: Hot reload support with watch mode
|
||||
- 🛠️ **TypeScript**: Full TypeScript support with strict type checking
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Node.js (version 18 or higher)
|
||||
- pnpm package manager
|
||||
- OpenAI API key
|
||||
- LlamaCloud API key
|
||||
|
||||
## Installation
|
||||
|
||||
1. Clone the repository:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/run-llama/llama_cloud_services
|
||||
cd lama_cloud_services/examples-ts/parse/
|
||||
```
|
||||
|
||||
2. Install dependencies:
|
||||
|
||||
```bash
|
||||
pnpm install
|
||||
```
|
||||
|
||||
3. Set up your environment variables:
|
||||
|
||||
```bash
|
||||
# Add your API keys to your environment
|
||||
export OPENAI_API_KEY="your-openai-api-key"
|
||||
export LLAMA_CLOUD_API_KEY="your-llamacloud-api-key"
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### Start the Demo
|
||||
|
||||
```bash
|
||||
pnpm run start
|
||||
```
|
||||
|
||||
The application will display a welcome screen and prompt you to enter the path to a document you'd like to process.
|
||||
|
||||
### Development Mode
|
||||
|
||||
For development with hot reload:
|
||||
|
||||
```bash
|
||||
pnpm run dev
|
||||
```
|
||||
|
||||
### Build the Project
|
||||
|
||||
```bash
|
||||
pnpm run build
|
||||
```
|
||||
|
||||
### Code Quality
|
||||
|
||||
Format code:
|
||||
|
||||
```bash
|
||||
pnpm run format
|
||||
```
|
||||
|
||||
Lint code:
|
||||
|
||||
```bash
|
||||
pnpm run lint
|
||||
```
|
||||
|
||||
## How It Works
|
||||
|
||||
1. **Document Input**: Enter the path to your document when prompted
|
||||
2. **Parsing**: LlamaParse processes the document and extracts structured content
|
||||
3. **AI Summary**: The extracted content is sent to OpenAI GPT-4 for summarization
|
||||
4. **Results**: View the AI-generated summary in your terminal
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
1. **Module Resolution Errors**: Ensure you're using Node.js 18+ and have all dependencies installed
|
||||
2. **API Key Issues**: Verify your OpenAI and LlamaCloud API keys are correctly set
|
||||
3. **File Path Errors**: Use absolute paths or ensure relative paths are correct from the project root
|
||||
|
||||
## License
|
||||
|
||||
MIT License - see the [LICENSE](../../LICENSE) file for details.
|
||||
|
||||
## Contributing
|
||||
|
||||
1. Fork the repository
|
||||
2. Create a feature branch
|
||||
3. Make your changes
|
||||
4. Run `pnpm run format` and `pnpm run lint`
|
||||
5. Submit a pull request
|
||||
@@ -0,0 +1,15 @@
|
||||
import js from "@eslint/js";
|
||||
import globals from "globals";
|
||||
import tseslint from "typescript-eslint";
|
||||
import { defineConfig } from "eslint/config";
|
||||
|
||||
export default defineConfig([
|
||||
{
|
||||
files: ["**/*.{js,mjs,cjs,ts,mts,cts}"],
|
||||
plugins: { js },
|
||||
extends: ["js/recommended"],
|
||||
languageOptions: { globals: globals.browser },
|
||||
},
|
||||
{ files: ["**/*.js"], languageOptions: { sourceType: "script" } },
|
||||
tseslint.configs.recommended,
|
||||
]);
|
||||
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"name": "llamaparse-demo",
|
||||
"version": "0.1.0",
|
||||
"description": "Demo for LlamaParse in TypeScript",
|
||||
"type": "module",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"There are no tests\"",
|
||||
"start": "pnpm exec tsx src/index.ts",
|
||||
"lint": "eslint ./src/",
|
||||
"format": "prettier --write ./src/",
|
||||
"build": "tsc",
|
||||
"dev": "pnpm exec tsx --watch src/index.ts"
|
||||
},
|
||||
"keywords": [
|
||||
"ai",
|
||||
"ocr",
|
||||
"parsing",
|
||||
"intelligent-document-processing",
|
||||
"pdf",
|
||||
"llms"
|
||||
],
|
||||
"author": "LlamaIndex",
|
||||
"license": "MIT",
|
||||
"packageManager": "pnpm@10.12.4",
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.32.0",
|
||||
"@types/figlet": "^1.7.0",
|
||||
"@types/node": "^24.1.0",
|
||||
"@typescript-eslint/eslint-plugin": "^8.38.0",
|
||||
"@typescript-eslint/parser": "^8.38.0",
|
||||
"eslint": "^9.32.0",
|
||||
"globals": "^16.3.0",
|
||||
"jiti": "^2.5.1",
|
||||
"prettier": "^3.6.2",
|
||||
"typescript": "^5.8.3",
|
||||
"typescript-eslint": "^8.38.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ai-sdk/openai": "^1.3.23",
|
||||
"ai": "^4.3.19",
|
||||
"consola": "^3.4.2",
|
||||
"figlet": "^1.8.2",
|
||||
"llama-cloud-services": "link:../../ts/llama_cloud_services",
|
||||
"picocolors": "^1.1.1"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
import { LlamaParseReader } from "llama-cloud-services";
|
||||
import { logger } from "./logger";
|
||||
import pc from "picocolors";
|
||||
import { consoleInput, generateSummary, renderLogo } from "./utils";
|
||||
|
||||
export async function main(): Promise<number> {
|
||||
const reader = new LlamaParseReader({ resultType: "markdown" });
|
||||
await renderLogo();
|
||||
logger.log(
|
||||
`Welcome to ${pc.bold(
|
||||
pc.magentaBright("✨LlamaParse Demo✨"),
|
||||
)}, our demo for ${pc.bold(pc.green("LlamaParse🦙"))}, a ${pc.bold(
|
||||
pc.cyan("LlamaCloud☁️"),
|
||||
)} (https://cloud.llamaindex.ai) product!.\nType the path to the document you would like to process below👇\nIf you wish to exit, just type ${pc.bold(
|
||||
pc.gray("quit"),
|
||||
)}.\n`,
|
||||
);
|
||||
while (true) {
|
||||
const userInput = await consoleInput();
|
||||
if (userInput.toLowerCase() == "quit") {
|
||||
break;
|
||||
}
|
||||
try {
|
||||
const documents = await reader.loadData(userInput);
|
||||
const summary = await generateSummary(documents); // Added await here
|
||||
logger.log(`${pc.bold(pc.cyan("AI-generated summary✨"))}:\n${summary}`);
|
||||
} catch (error) {
|
||||
logger.error(`Error processing file: ${error}`);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
main().catch(console.error);
|
||||
@@ -0,0 +1,8 @@
|
||||
import { createConsola } from "consola";
|
||||
import type { ConsolaInstance } from "consola";
|
||||
|
||||
export const logger: ConsolaInstance = createConsola({
|
||||
formatOptions: {
|
||||
date: false,
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,51 @@
|
||||
import { generateText } from "ai";
|
||||
import { openai } from "@ai-sdk/openai";
|
||||
import { Document } from "llamaindex";
|
||||
import * as readline from "readline/promises";
|
||||
import figlet from "figlet";
|
||||
import pc from "picocolors";
|
||||
|
||||
export async function renderLogo(): Promise<void> {
|
||||
const logoText = figlet.textSync("LlamaParse Demo", {
|
||||
font: "ANSI Shadow",
|
||||
horizontalLayout: "default",
|
||||
verticalLayout: "default",
|
||||
width: 100,
|
||||
whitespaceBreak: true,
|
||||
});
|
||||
|
||||
// Add some styling with picocolors
|
||||
const styledLogo = pc.bold(pc.magentaBright(logoText));
|
||||
|
||||
// Add some padding/margin
|
||||
console.log("\n");
|
||||
console.log(styledLogo);
|
||||
console.log(pc.gray("─".repeat(60)));
|
||||
console.log("\n");
|
||||
}
|
||||
|
||||
export async function consoleInput(): Promise<string> {
|
||||
const rl = readline.createInterface({
|
||||
input: process.stdin,
|
||||
output: process.stdout,
|
||||
});
|
||||
|
||||
const answer = await rl.question("Path to your file: ");
|
||||
rl.close();
|
||||
return answer;
|
||||
}
|
||||
|
||||
export async function generateSummary(documents: Document[]): Promise<string> {
|
||||
let mainText: string = "";
|
||||
|
||||
for (const document of documents) {
|
||||
mainText += `${document.text}\n\n---\n\n`;
|
||||
}
|
||||
|
||||
const { text } = await generateText({
|
||||
model: openai("gpt-4.1"),
|
||||
prompt: `</chat>\n\t<text>${mainText}</text>\n\t<instructions>Could you please generate a summary of the given text?</instructions>\n</chat>`,
|
||||
});
|
||||
|
||||
return text;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2022",
|
||||
"module": "ES2022",
|
||||
"lib": ["ES2022"],
|
||||
"outDir": "./dist",
|
||||
"rootDir": "./src",
|
||||
"strict": true,
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"sourceMap": true,
|
||||
"types": ["node"],
|
||||
"moduleResolution": "bundler",
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"resolveJsonModule": true
|
||||
},
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["node_modules", "dist"]
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
# LlamaCloud Services Examples - Python
|
||||
|
||||
In this folder you will find several python notebooks that contain examples regarding:
|
||||
|
||||
- [LlamaParse](./parse/)
|
||||
- [LlamaExtract](./extract/)
|
||||
- [LlamaReport](./report/)
|
||||
|
||||
Follow the instructions in each notebook to get started!
|
||||
@@ -1,138 +0,0 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Using the Raw API\n",
|
||||
"\n",
|
||||
"This notebook walks through how to use the raw API and how"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"--2024-02-02 11:11:39-- https://arxiv.org/pdf/1706.03762.pdf\n",
|
||||
"Resolving arxiv.org (arxiv.org)... 151.101.131.42, 151.101.3.42, 151.101.67.42, ...\n",
|
||||
"Connecting to arxiv.org (arxiv.org)|151.101.131.42|:443... connected.\n",
|
||||
"HTTP request sent, awaiting response... 200 OK\n",
|
||||
"Length: 2215244 (2.1M) [application/pdf]\n",
|
||||
"Saving to: ‘./attention.pdf’\n",
|
||||
"\n",
|
||||
"./attention.pdf 100%[===================>] 2.11M --.-KB/s in 0.08s \n",
|
||||
"\n",
|
||||
"2024-02-02 11:11:39 (27.3 MB/s) - ‘./attention.pdf’ saved [2215244/2215244]\n",
|
||||
"\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"!wget \"https://arxiv.org/pdf/1706.03762.pdf\" -O \"./attention.pdf\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"api_key = \"llx-...\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import mimetypes\n",
|
||||
"import requests\n",
|
||||
"import time\n",
|
||||
"\n",
|
||||
"headers = {\"Authorization\": f\"Bearer {api_key}\"}\n",
|
||||
"file_path = \"./attention.pdf\"\n",
|
||||
"base_url = \"https://api.cloud.llamaindex.ai/api/parsing\"\n",
|
||||
"\n",
|
||||
"with open(file_path, \"rb\") as f:\n",
|
||||
" mime_type = mimetypes.guess_type(file_path)[0]\n",
|
||||
" files = {\"file\": (f.name, f, mime_type)}\n",
|
||||
"\n",
|
||||
" # send the request, upload the file\n",
|
||||
" url = f\"{base_url}/upload\"\n",
|
||||
" response = requests.post(url, headers=headers, files=files)\n",
|
||||
"\n",
|
||||
"response.raise_for_status()\n",
|
||||
"# get the job id for the result_url\n",
|
||||
"job_id = response.json()[\"id\"]\n",
|
||||
"result_type = \"text\" # or \"markdown\"\n",
|
||||
"result_url = f\"{base_url}/job/{job_id}/result/{result_type}\"\n",
|
||||
"\n",
|
||||
"# check for the result until its ready\n",
|
||||
"while True:\n",
|
||||
" response = requests.get(result_url, headers=headers)\n",
|
||||
" if response.status_code == 200:\n",
|
||||
" break\n",
|
||||
"\n",
|
||||
" time.sleep(2)\n",
|
||||
"\n",
|
||||
"# download the result\n",
|
||||
"result = response.json()\n",
|
||||
"output = result[result_type]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
" Provided proper attribution is provided, Google hereby grants permission to\n",
|
||||
" reproduce the tables and figures in this paper solely for use in journalistic or\n",
|
||||
" scholarly works.\n",
|
||||
" Attention Is All You Need\n",
|
||||
"arXiv:1706.03762v7 [cs.CL] 2 Aug 2023\n",
|
||||
" Ashish Vaswani∗ Noam Shazeer∗ Niki Parmar∗ Jakob Uszkoreit∗\n",
|
||||
" Google Brain Google Brain Google Research Google Research\n",
|
||||
" avaswani@google.com noam@google.com nikip@google.com usz@google.com\n",
|
||||
" Llion Jones∗ Aidan N. Gomez∗ † Łukasz Kaiser∗\n",
|
||||
" Google Research University of Toronto \n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(output[:1000])"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "llama-parse-aNC435Vv-py3.11",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.11.5"
|
||||
},
|
||||
"orig_nbformat": 4
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2
|
||||
}
|
||||
@@ -1,191 +0,0 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Llama Parser Usage"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!pip install llama-index llama-parser"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"--2024-02-02 11:10:10-- https://arxiv.org/pdf/1706.03762.pdf\n",
|
||||
"Resolving arxiv.org (arxiv.org)... 151.101.131.42, 151.101.3.42, 151.101.67.42, ...\n",
|
||||
"Connecting to arxiv.org (arxiv.org)|151.101.131.42|:443... connected.\n",
|
||||
"HTTP request sent, awaiting response... 200 OK\n",
|
||||
"Length: 2215244 (2.1M) [application/pdf]\n",
|
||||
"Saving to: ‘./attention.pdf’\n",
|
||||
"\n",
|
||||
"./attention.pdf 100%[===================>] 2.11M --.-KB/s in 0.08s \n",
|
||||
"\n",
|
||||
"2024-02-02 11:10:10 (25.9 MB/s) - ‘./attention.pdf’ saved [2215244/2215244]\n",
|
||||
"\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"!wget \"https://arxiv.org/pdf/1706.03762.pdf\" -O \"./attention.pdf\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# llama-parser is async-first, running the sync code in a notebook requires the use of nest_asyncio\n",
|
||||
"import nest_asyncio\n",
|
||||
"\n",
|
||||
"nest_asyncio.apply()\n",
|
||||
"\n",
|
||||
"import os\n",
|
||||
"os.environ[\"LLAMA_CLOUD_API_KEY\"] = \"llx-...\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Started parsing the file under job_id dd0b8e31-0c09-4497-b78a-cc1c92f1d6cf\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from llama_parser import LlamaParser\n",
|
||||
"\n",
|
||||
"documents = LlamaParser(result_type=\"text\").load_data(\"./attention.pdf\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"ad\n",
|
||||
"relying entirely on an attention mechanism to draw global dependencies between input and output.\n",
|
||||
"The Transformer allows for significantly more parallelization and can reach a new state of the art in\n",
|
||||
"translation quality after being trained for as little as twelve hours on eight P100 GPUs.\n",
|
||||
"2 Background\n",
|
||||
"The goal of reducing sequential computation also forms the foundation of the Extended Neural GPU\n",
|
||||
"[16], ByteNet [18] and ConvS2S [9], all of which use convolutional neural networks as basic building\n",
|
||||
"block, computing hidden representations in parallel for all input and output positions. In these models,\n",
|
||||
"the number of operations required to relate signals from two arbitrary input or output positions grows\n",
|
||||
"in the distance between positions, linearly for ConvS2S and logarithmically for ByteNet. This makes\n",
|
||||
"it more difficult to learn dependencies between distant positions [12]. In the Transformer this is\n",
|
||||
"reduced to a constant number of operations, albeit at the cost of reduced effective res\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(documents[0].text[6000:7000])"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Started parsing the file under job_id d4531453-1bbb-48c4-8324-ae9fea9f2fa2\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from llama_parser import LlamaParser\n",
|
||||
"\n",
|
||||
"documents = LlamaParser(result_type=\"markdown\").load_data(\"./attention.pdf\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"ction describes the training regime for our models.\n",
|
||||
"\n",
|
||||
"##### Training Data and Batching\n",
|
||||
"\n",
|
||||
"We trained on the standard WMT 2014 English-German dataset consisting of about 4.5 million\n",
|
||||
"sentence pairs. Sentences were encoded using byte-pair encoding [3], which has a shared source-\n",
|
||||
"target vocabulary of about 37000 tokens. For English-French, we used the significantly larger WMT\n",
|
||||
"2014 English-French dataset consisting of 36M sentences and split tokens into a 32000 word-piece\n",
|
||||
"vocabulary [38]. Sentence pairs were batched together by approximate sequence length. Each training\n",
|
||||
"batch contained a set of sentence pairs containing approximately 25000 source tokens and 25000\n",
|
||||
"target tokens.\n",
|
||||
"\n",
|
||||
"##### Hardware and Schedule\n",
|
||||
"\n",
|
||||
"We trained our models on one machine with 8 NVIDIA P100 GPUs. For our base models using\n",
|
||||
"the hyperparameters described throughout the paper, each training step took about 0.4 seconds. We\n",
|
||||
"trained the base models for a total of 100,000 steps or 12 hours. For our big models,(described on the\n",
|
||||
"bo...\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(documents[0].text[20000:21000] + \"...\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "llama-parse-aNC435Vv-py3.11",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.11.5"
|
||||
},
|
||||
"orig_nbformat": 4
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2
|
||||
}
|
||||
|
After Width: | Height: | Size: 3.3 MiB |
@@ -0,0 +1,10 @@
|
||||
# Financial Modeling Assumptions
|
||||
Discount Rate: 8%
|
||||
Terminal Growth Rate: 2%
|
||||
Tax Rate: 25%
|
||||
Revenue Growth (Years 1-5): 10% per annum
|
||||
Revenue Growth (Years 6-10): 5% per annum
|
||||
Capital Expenditures as % of Revenue: 7%
|
||||
Working Capital Assumption: 3% of Revenue
|
||||
Depreciation Rate: 10% per annum
|
||||
Cost of Capital Assumption: 8%
|
||||
|
After Width: | Height: | Size: 67 KiB |
@@ -0,0 +1 @@
|
||||
sec_form_4_dump.json
|
||||
|
After Width: | Height: | Size: 202 KiB |
|
After Width: | Height: | Size: 440 KiB |
|
After Width: | Height: | Size: 156 KiB |
|
After Width: | Height: | Size: 85 KiB |
|
After Width: | Height: | Size: 893 KiB |
@@ -0,0 +1,440 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Extract Data from Financial Reports - with Citations and Reasoning\n",
|
||||
"\n",
|
||||
"Given complex files like financial reports, contracts, invoices etc, Llama Extract allows you to make use of an LLM to extract the information relevant to you, in a structured format.\n",
|
||||
"\n",
|
||||
"In this example, we'll be using [LlamaExtract](https://docs.cloud.llamaindex.ai/llamaextract/getting_started?utm_campaign=extract&utm_medium=recipe) to extract structured data from an SEC filing (specifically, the filing by Nvidia for fiscal year 2025).\n",
|
||||
"\n",
|
||||
"On top of simple data extraction, we'll ask our extraction agent to provide citations and reasoning for each extracted field. This allows us to:\n",
|
||||
"- Confirm the accuracy of the extracted field\n",
|
||||
"- Understand the reasoning behind why the LLM extracted a given piece of information\n",
|
||||
"- This last point allows us an opportunity to adjust the system prompt or field descriptions and improve on results where needed.\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"The example we go through below is also replicable within Llama Cloud as well, where you will also be able to pick between a number of pre-defined schemas, instead of building your own."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!pip install llama-cloud-services"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Connect to Llama Cloud\n",
|
||||
"\n",
|
||||
"To get started, make sure you provide your [Llama Cloud](https://cloud.llamaindex.ai?utm_campaign=extract&utm_medium=recipe) API key."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Enter your Llama Cloud API Key: ··········\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"from getpass import getpass\n",
|
||||
"\n",
|
||||
"if \"LLAMA_CLOUD_API_KEY\" not in os.environ:\n",
|
||||
" os.environ[\"LLAMA_CLOUD_API_KEY\"] = getpass(\"Enter your Llama Cloud API Key: \")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Extract Data with Llama Extract Agent"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"No project_id provided, fetching default project.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from llama_cloud_services import LlamaExtract\n",
|
||||
"\n",
|
||||
"# Optionally, provide your project id, if not, it will use the 'Default' project\n",
|
||||
"llama_extract = LlamaExtract()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Provide Your Custom Schema\n",
|
||||
"\n",
|
||||
"When using LlamaExtract via the API, you provide your own schema that describes what you want extracted from files and data provided to your agent. Here, we are essentially building an SEC filings extraction agent."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from pydantic import BaseModel, Field\n",
|
||||
"from enum import Enum\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"class FilingType(str, Enum):\n",
|
||||
" ten_k = \"10 K\"\n",
|
||||
" ten_q = \"10-Q\"\n",
|
||||
" ten_ka = \"10-K/A\"\n",
|
||||
" ten_qa = \"10-Q/A\"\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"class FinancialReport(BaseModel):\n",
|
||||
" company_name: str = Field(description=\"The name of the company\")\n",
|
||||
" description: str = Field(\n",
|
||||
" description=\"Short description of the filing and what it contains\"\n",
|
||||
" )\n",
|
||||
" filing_type: FilingType = Field(description=\"Type of SEC filing\")\n",
|
||||
" filing_date: str = Field(description=\"Date when filing was submitted to SEC\")\n",
|
||||
" fiscal_year: int = Field(description=\"Fiscal year\")\n",
|
||||
" unit: str = Field(\n",
|
||||
" description=\"Unit of financial figures (thousands, millions, etc.)\"\n",
|
||||
" )\n",
|
||||
" revenue: int = Field(description=\"Total revenue for period\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Set Up Citations and Reasoning\n",
|
||||
"\n",
|
||||
"Optionally, we can set the `ExtractConfig` to extract citations for each field the agent extracts. These cications will cite the specific pages and sections of the file from which a given field was extractedd.\n",
|
||||
"\n",
|
||||
"By setting `use_reasoning` to True, we als ask the agent to do an additional reasoning step, explaining why a given field was extracted."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_cloud.types import ExtractConfig, ExtractMode\n",
|
||||
"\n",
|
||||
"config = ExtractConfig(\n",
|
||||
" use_reasoning=True, cite_sources=True, extraction_mode=ExtractMode.MULTIMODAL\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"/usr/local/lib/python3.11/dist-packages/llama_cloud_services/extract/extract.py:127: ExperimentalWarning: `use_reasoning` is an experimental feature. Results will be available in the `extraction_metadata` field for the extraction run.\n",
|
||||
" warnings.warn(\n",
|
||||
"/usr/local/lib/python3.11/dist-packages/llama_cloud_services/extract/extract.py:133: ExperimentalWarning: `cite_sources` is an experimental feature. This may greatly increase the size of the response, and slow down the extraction. Results will be available in the `extraction_metadata` field for the extraction run.\n",
|
||||
" warnings.warn(\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"agent = llama_extract.create_agent(\n",
|
||||
" name=\"filing-parser\", data_schema=FinancialReport, config=config\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Demo Time - Download a PDF and Extract Data with Citations"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"PDF downloaded successfully.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"import requests\n",
|
||||
"\n",
|
||||
"url = \"https://raw.githubusercontent.com/run-llama/llama_cloud_services/refs/heads/main/examples/extract/data/sec_filings/nvda_10k.pdf\"\n",
|
||||
"\n",
|
||||
"response = requests.get(url)\n",
|
||||
"\n",
|
||||
"if response.status_code == 200:\n",
|
||||
" with open(\"/content/nvda_10k.pdf\", \"wb\") as f:\n",
|
||||
" f.write(response.content)\n",
|
||||
" print(\"PDF downloaded successfully.\")\n",
|
||||
"else:\n",
|
||||
" print(f\"Failed to download. Status code: {response.status_code}\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Uploading files: 100%|██████████| 1/1 [00:00<00:00, 1.83it/s]\n",
|
||||
"Creating extraction jobs: 100%|██████████| 1/1 [00:00<00:00, 4.38it/s]\n",
|
||||
"Extracting files: 100%|██████████| 1/1 [02:03<00:00, 123.40s/it]\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"filing_info = agent.extract(\"/content/nvda_10k.pdf\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"{'company_name': 'NVIDIA Corporation',\n",
|
||||
" 'description': \"The filing provides a detailed overview of NVIDIA's business as a full-stack computing infrastructure company, discusses various technologies including digital avatars and autonomous vehicles, outlines numerous risk factors affecting operations such as supply chain issues and geopolitical tensions, and describes employee stock purchase plans and related compliance requirements.\",\n",
|
||||
" 'filing_type': '10 K',\n",
|
||||
" 'filing_date': 'February 26, 2025',\n",
|
||||
" 'fiscal_year': 2025,\n",
|
||||
" 'unit': 'millions',\n",
|
||||
" 'revenue': 130497}"
|
||||
]
|
||||
},
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"filing_info.data"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Inspect Citations and Reasoning"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"{'field_metadata': {'company_name': {'reasoning': 'VERBATIM EXTRACTION',\n",
|
||||
" 'citation': [{'page': 1, 'matching_text': 'NVIDIA CORPORATION'},\n",
|
||||
" {'page': 2, 'matching_text': 'NVIDIA Corporation'},\n",
|
||||
" {'page': 3,\n",
|
||||
" 'matching_text': 'All references to \"NVIDIA,\" \"we,\" \"us,\" \"our,\" or the \"Company\" mean NVIDIA Corporation and its subsidiaries.'},\n",
|
||||
" {'page': 35,\n",
|
||||
" 'matching_text': 'Comparison of 5 Year Cumulative Total Return* Among NVIDIA Corporation'},\n",
|
||||
" {'page': 49,\n",
|
||||
" 'matching_text': 'To the Board of Directors and Shareholders of NVIDIA Corporation'},\n",
|
||||
" {'page': 90, 'matching_text': 'NVIDIA Corporation'},\n",
|
||||
" {'page': 119,\n",
|
||||
" 'matching_text': '*\"Company\"* means NVIDIA Corporation, a Delaware corporation.'},\n",
|
||||
" {'page': 126,\n",
|
||||
" 'matching_text': 'Annual Report on Form 10-K of NVIDIA Corporation'}]},\n",
|
||||
" 'filing_type': {'reasoning': \"VERBATIM EXTRACTION from multiple sources confirming the filing type as '10 K'.\",\n",
|
||||
" 'citation': [{'page': 1, 'matching_text': 'FORM 10-K'},\n",
|
||||
" {'page': 2, 'matching_text': 'Item 16. | Form 10-K Summary'},\n",
|
||||
" {'page': 3,\n",
|
||||
" 'matching_text': 'This Annual Report on Form 10-K contains forward-looking statements...'},\n",
|
||||
" {'page': 13, 'matching_text': 'this Annual Report on Form 10-K'},\n",
|
||||
" {'page': 15, 'matching_text': 'this Annual Report on Form 10-K'},\n",
|
||||
" {'page': 32,\n",
|
||||
" 'matching_text': 'Annual Report on Form 10-K, which information is hereby incorporated by reference.'},\n",
|
||||
" {'page': 36, 'matching_text': 'this Annual Report on Form 10-K'},\n",
|
||||
" {'page': 43,\n",
|
||||
" 'matching_text': 'Annual Report on Form 10-K for additional information'},\n",
|
||||
" {'page': 45, 'matching_text': 'Annual Report on Form 10-K'},\n",
|
||||
" {'page': 46, 'matching_text': 'this Annual Report on Form 10-K'},\n",
|
||||
" {'page': 62, 'matching_text': 'Annual Report on Form 10-K'},\n",
|
||||
" {'page': 83,\n",
|
||||
" 'matching_text': 'Restated Certificate of Incorporation | 10-K'},\n",
|
||||
" {'page': 84, 'matching_text': 'Item 16. Form 10-K Summary'},\n",
|
||||
" {'page': 126, 'matching_text': 'which appears in this Form 10-K'},\n",
|
||||
" {'page': 127, 'matching_text': 'Annual Report on Form 10-K'},\n",
|
||||
" {'page': 128, 'matching_text': 'Annual Report on Form 10-K'},\n",
|
||||
" {'page': 129, 'matching_text': \"The Company's Annual Report on Form 10-K\"},\n",
|
||||
" {'page': 130,\n",
|
||||
" 'matching_text': \"The Company's Annual Report on Form 10-K for the year ended January 26, 2025\"}]},\n",
|
||||
" 'fiscal_year': {'reasoning': 'The fiscal year ended January 26, 2025, indicates the fiscal year is 2025. Additionally, multiple references throughout the text confirm the fiscal year 2025 in various contexts.',\n",
|
||||
" 'citation': [{'page': 1,\n",
|
||||
" 'matching_text': 'For the fiscal year ended January 26, 2025'},\n",
|
||||
" {'page': 6,\n",
|
||||
" 'matching_text': 'In fiscal year 2025, we launched the NVIDIA Blackwell architecture'},\n",
|
||||
" {'page': 12, 'matching_text': 'fiscal year 2025'},\n",
|
||||
" {'page': 17,\n",
|
||||
" 'matching_text': 'our gross margins in the second quarter of fiscal year 2025 were negatively impacted'},\n",
|
||||
" {'page': 20,\n",
|
||||
" 'matching_text': 'we generated 53% of our revenue in fiscal year 2025 from sales outside the United States.'},\n",
|
||||
" {'page': 23,\n",
|
||||
" 'matching_text': 'For fiscal year 2025, an indirect customer which primarily purchases our products through system integrators...'},\n",
|
||||
" {'page': 33,\n",
|
||||
" 'matching_text': 'In fiscal year 2025, we repurchased 310 million shares of our common stock for $34.0 billion.'},\n",
|
||||
" {'page': 37,\n",
|
||||
" 'matching_text': 'Our Data Center revenue in China grew in fiscal year 2025.'},\n",
|
||||
" {'page': 44,\n",
|
||||
" 'matching_text': 'Cash provided by operating activities increased in fiscal year 2025 compared to fiscal year 2024'},\n",
|
||||
" {'page': 57,\n",
|
||||
" 'matching_text': 'Fiscal years 2025, 2024 and 2023 were all 52-week years.'},\n",
|
||||
" {'page': 65,\n",
|
||||
" 'matching_text': 'Beginning in the second quarter of fiscal year 2025'},\n",
|
||||
" {'page': 69, 'matching_text': 'In the fourth quarter of fiscal year 2025'},\n",
|
||||
" {'page': 78,\n",
|
||||
" 'matching_text': 'Depreciation and amortization expense attributable to our Compute and Networking segment for fiscal years 2025'},\n",
|
||||
" {'page': 129, 'matching_text': 'for the year ended January 26, 2025'}]},\n",
|
||||
" 'description': {'reasoning': 'The extracted data combines multiple descriptions from the source text, ensuring no duplication while maintaining the order and context of the information. Each section of the filing is summarized to reflect the key points without losing the essence of the original text.',\n",
|
||||
" 'citation': [{'page': 4,\n",
|
||||
" 'matching_text': 'NVIDIA is now a full-stack computing infrastructure company with data-center-scale offerings that are reshaping industry.'},\n",
|
||||
" {'page': 8,\n",
|
||||
" 'matching_text': 'a suite of technologies that help developers bring digital avatars to life with generative Al...autonomous vehicles, or AV, and electric vehicles, or EV, is revolutionizing the transportation industry...Our worldwide sales and marketing strategy is key to achieving our objective of providing markets with our high-performance and efficient computing platforms and software.'},\n",
|
||||
" {'page': 14, 'matching_text': 'Risk Factors Summary'},\n",
|
||||
" {'page': 16,\n",
|
||||
" 'matching_text': 'Risks Related to Demand, Supply, and Manufacturing\\n\\nLong manufacturing lead times and uncertain supply and component availability...'},\n",
|
||||
" {'page': 18,\n",
|
||||
" 'matching_text': 'cryptocurrency mining, on demand for our products. Volatility in the cryptocurrency market, including new compute technologies...'},\n",
|
||||
" {'page': 21,\n",
|
||||
" 'matching_text': 'supply-chain attacks or other business disruptions. We cannot guarantee that third parties and infrastructure in our supply chain...'},\n",
|
||||
" {'page': 22,\n",
|
||||
" 'matching_text': 'We are monitoring the impact of the geopolitical conflict in and around Israel on our operations... Climate change may have a long-term impact on our business.'},\n",
|
||||
" {'page': 25,\n",
|
||||
" 'matching_text': 'We are subject to complex laws, rules, regulations, and political and other actions, including restrictions on the export of our products, which may adversely impact our business.'},\n",
|
||||
" {'page': 28,\n",
|
||||
" 'matching_text': 'Our competitive position has been harmed by the existing export controls, and our competitive position and future results may be further harmed'},\n",
|
||||
" {'page': 29,\n",
|
||||
" 'matching_text': 'restrictions imposed by the Chinese government on the duration of gaming activities and access to games may adversely affect our Gaming revenue'},\n",
|
||||
" {'page': 29,\n",
|
||||
" 'matching_text': 'our business depends on our ability to receive consistent and reliable supply from our overseas partners, especially in Taiwan and South Korea'},\n",
|
||||
" {'page': 29,\n",
|
||||
" 'matching_text': 'Increased scrutiny from shareholders, regulators and others regarding our corporate sustainability practices could result in additional costs'},\n",
|
||||
" {'page': 29,\n",
|
||||
" 'matching_text': 'Concerns relating to the responsible use of new and evolving technologies, such as Al, in our products and services may result in reputational or financial harm'},\n",
|
||||
" {'page': 31,\n",
|
||||
" 'matching_text': 'Data protection laws around the world are quickly changing and may be interpreted and applied in an increasingly stringent fashion...'}]},\n",
|
||||
" 'filing_date': {'reasoning': 'The filing date is consistently mentioned as February 26, 2025 across multiple entries, making it the most reliable date for the filing.',\n",
|
||||
" 'citation': [{'page': 51, 'matching_text': 'February 26, 2025'},\n",
|
||||
" {'page': 86, 'matching_text': 'on February 26, 2025.'},\n",
|
||||
" {'page': 87, 'matching_text': 'February 26, 2025'},\n",
|
||||
" {'page': 126, 'matching_text': 'our report dated February 26, 2025'},\n",
|
||||
" {'page': 127, 'matching_text': 'Date: February 26, 2025'},\n",
|
||||
" {'page': 128, 'matching_text': 'Date: February 26, 2025'},\n",
|
||||
" {'page': 129, 'matching_text': 'Date: February 26, 2025'},\n",
|
||||
" {'page': 130, 'matching_text': 'Date: February 26, 2025'}]},\n",
|
||||
" 'unit': {'reasoning': \"The unit of financial figures is explicitly mentioned multiple times in the text as 'millions', including in table headers and notes. This is confirmed by various citations from pages 38, 42, 43, 52, 53, 54, 56, 65, 71, 72, 73, 75, 77, 79, 80, and 82.\",\n",
|
||||
" 'citation': [{'page': 38,\n",
|
||||
" 'matching_text': '($ in millions, except per share data)'},\n",
|
||||
" {'page': 42, 'matching_text': '($ in millions)'},\n",
|
||||
" {'page': 43, 'matching_text': '($ in millions)'},\n",
|
||||
" {'page': 52, 'matching_text': '(In millions, except per share data)'},\n",
|
||||
" {'page': 53,\n",
|
||||
" 'matching_text': 'Consolidated Statements of Comprehensive Income (In millions)'},\n",
|
||||
" {'page': 54,\n",
|
||||
" 'matching_text': 'Consolidated Balance Sheets (In millions, except par value)'},\n",
|
||||
" {'page': 55, 'matching_text': '(In millions, except per share data)'},\n",
|
||||
" {'page': 56,\n",
|
||||
" 'matching_text': 'Consolidated Statements of Cash Flows (In millions)'},\n",
|
||||
" {'page': 65,\n",
|
||||
" 'matching_text': 'Year Ended<br/>Jan 26, 2025<br/>(In millions, except per share data)'},\n",
|
||||
" {'page': 71, 'matching_text': '(In millions) | (In millions)'},\n",
|
||||
" {'page': 72, 'matching_text': '(In millions)'}]},\n",
|
||||
" 'revenue': {'reasoning': 'The total revenue for fiscal year 2025 is extracted from multiple sources within the text, all confirming the same figure of $130,497 million. The revenue recognized for fiscal year 2025 is also noted as $4,607 million, which is a separate figure. However, the primary focus is on the total revenue figure, which is consistently cited.',\n",
|
||||
" 'citation': [{'page': 38,\n",
|
||||
" 'matching_text': 'Revenue for fiscal year 2025 was $130.5 billion'},\n",
|
||||
" {'page': 41,\n",
|
||||
" 'matching_text': 'Total | $ 130,497 | $ | 60,922'},\n",
|
||||
" {'page': 52, 'matching_text': 'Revenue | $ 130,497'},\n",
|
||||
" {'page': 78,\n",
|
||||
" 'matching_text': 'Revenue | $ 116,193 | $ 14,304 | $ - | $ 130,497'},\n",
|
||||
" {'page': 79, 'matching_text': 'Total revenue | $ 130,497'},\n",
|
||||
" {'page': 80, 'matching_text': 'Total revenue | $ 130,497'}]}},\n",
|
||||
" 'usage': {'num_pages_extracted': 130,\n",
|
||||
" 'num_document_tokens': 105932,\n",
|
||||
" 'num_output_tokens': 31306}}"
|
||||
]
|
||||
},
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"filing_info.extraction_metadata"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## What's Next?\n",
|
||||
"\n",
|
||||
"In this example, we built an Extraction Agent that is capable of citing it's sources from the document it's extracting data from, and reasoning about its reponse. To further customize and improve on the results, you can also try to customize the `system_prompt` in the `ExtractConfig`.\n",
|
||||
"\n",
|
||||
"#### Learn More\n",
|
||||
"\n",
|
||||
"- [LlamaExtract Documentation](https://docs.cloud.llamaindex.ai/llamaextract/getting_started)\n",
|
||||
"- [Example Notebooks](https://github.com/run-llama/llama_cloud_services/tree/main/examples/extract)"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"provenance": []
|
||||
},
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"name": "python"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 0
|
||||
}
|
||||
@@ -0,0 +1,318 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "1f6bd03d-1b8b-45a0-bc2c-5a13f1a5d8d3",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# LM317 Voltage Regulator Datasheet Structured Extraction\n",
|
||||
"\n",
|
||||
"<a href=\"https://colab.research.google.com/github/run-llama/llama_cloud_services/blob/main/examples/extract/lm317_structured_extraction.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>\n",
|
||||
"\n",
|
||||
"This notebook demonstrates an agentic document workflow using LlamaExtract to process an LM317 voltage regulator datasheet. In this example, we define a structured extraction schema that converts key technical fields into standardized subfields. For instance, the output voltage is split into a minimum and maximum value with a defined unit, and we capture page citations for each extracted field.\n",
|
||||
"\n",
|
||||
"The target user is an electronics engineer at a component manufacturing company who needs to consolidate datasheet information into a standardized specification sheet for design and quality control.\n",
|
||||
"\n",
|
||||
"This approach reduces manual data entry, improves extraction accuracy and standardization, and provides traceability for each technical detail."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "a3b8c8d5-ff3e-48ce-b0b8-29b6b1f517f8",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Use Case Overview\n",
|
||||
"\n",
|
||||
"### Problem\n",
|
||||
"Datasheets like that for the LM317 regulator are often distributed as PDFs containing multiple tables, charts, and complex textual descriptions. Engineers must manually extract technical details such as voltage ranges, dropout voltage, maximum current, input voltage range, and pin configurations. This process is error-prone and time-consuming.\n",
|
||||
"\n",
|
||||
"### Agent Workflow (Combination of Automation and Chat)\n",
|
||||
"1. **Upload Datasheet:** The engineer uploads the LM317 datasheet PDF. \n",
|
||||
"2. **Structured Extraction:** An automated agent processes the PDF and extracts key technical details into structured fields (e.g., output voltage as a range with separate min/max values).\n",
|
||||
"3. **Interactive Verification:** The engineer can query the agent (via chat) for further details or clarification (e.g., \"Show me the detailed pin configuration extraction\") and review the cited pages.\n",
|
||||
"\n",
|
||||
"**Value Delivered:**\n",
|
||||
"- Up to 70% reduction in manual data extraction time.\n",
|
||||
"- Increased accuracy and standardization with structured fields."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "a704e843-54be-4969-842b-713584cb3c35",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Setup and Download Data\n",
|
||||
"\n",
|
||||
"Download the [LM317 Datasheet](https://www.ti.com/lit/ds/symlink/lm317.pdf) and setup LlamaExtract."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "6e5b1f91-8785-44d4-a710-8be1b48b76de",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!mkdir -p data/lm317_structured_extraction\n",
|
||||
"!wget https://www.ti.com/lit/ds/symlink/lm317.pdf -O data/lm317_structured_extraction/lm317.pdf"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "f17b914a-00ed-4b63-8198-69fd7c4a7c62",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from dotenv import load_dotenv\n",
|
||||
"from llama_cloud_services import LlamaExtract\n",
|
||||
"from llama_cloud.core.api_error import ApiError\n",
|
||||
"\n",
|
||||
"# Load environment variables (ensure LLAMA_CLOUD_API_KEY is set in your .env file)\n",
|
||||
"load_dotenv(override=True)\n",
|
||||
"\n",
|
||||
"# Initialize the LlamaExtract client\n",
|
||||
"llama_extract = LlamaExtract(\n",
|
||||
" project_id=\"<project_id>\",\n",
|
||||
" organization_id=\"<organization_id>\",\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "ed9f6e9a-96c8-4ee1-8b45-0b6a4f7dbbf1",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Defining a Structured Extraction Schema\n",
|
||||
"\n",
|
||||
"We now define a rich Pydantic schema to extract technical specifications from the LM317 datasheet. In this schema:\n",
|
||||
"\n",
|
||||
"- The **output_voltage** and **input_voltage** fields are structured as ranges with separate minimum and maximum values and a unit.\n",
|
||||
"- The **pin_configuration** field is structured to include a pin count and a descriptive layout.\n",
|
||||
"- Additional technical fields (e.g., dropout voltage, max current) are captured as numbers.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "4f7e9b44-5e69-4b30-9864-cd98f1e2a7d4",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from pydantic import BaseModel, Field\n",
|
||||
"from typing import List\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"class VoltageRange(BaseModel):\n",
|
||||
" min_voltage: float = Field(..., description=\"Minimum voltage in volts\")\n",
|
||||
" max_voltage: float = Field(..., description=\"Maximum voltage in volts\")\n",
|
||||
" unit: str = Field(\"V\", description=\"Voltage unit\")\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"class PinConfiguration(BaseModel):\n",
|
||||
" pin_count: int = Field(..., description=\"Number of pins\")\n",
|
||||
" layout: str = Field(..., description=\"Detailed pin layout description\")\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"class LM317Spec(BaseModel):\n",
|
||||
" component_name: str = Field(..., description=\"Name of the component\")\n",
|
||||
" output_voltage: VoltageRange = Field(\n",
|
||||
" ..., description=\"Output voltage range specification\"\n",
|
||||
" )\n",
|
||||
" dropout_voltage: float = Field(..., description=\"Dropout voltage in volts\")\n",
|
||||
" max_current: float = Field(..., description=\"Maximum current rating in amperes\")\n",
|
||||
" input_voltage: VoltageRange = Field(\n",
|
||||
" ..., description=\"Input voltage range specification\"\n",
|
||||
" )\n",
|
||||
" pin_configuration: PinConfiguration = Field(\n",
|
||||
" ..., description=\"Pin configuration details\"\n",
|
||||
" )\n",
|
||||
" features: List[str] = Field([], description=\"List of additional technical features\")\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"class LM317Schema(BaseModel):\n",
|
||||
" specs: List[LM317Spec] = Field(\n",
|
||||
" ..., description=\"List of extracted LM317 technical specifications\"\n",
|
||||
" )"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "e0508e38-35be-446c-afe7-129e39553281",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"try:\n",
|
||||
" existing_agent = llama_extract.get_agent(name=\"lm317-datasheet\")\n",
|
||||
" if existing_agent:\n",
|
||||
" llama_extract.delete_agent(existing_agent.id)\n",
|
||||
"except ApiError as e:\n",
|
||||
" if e.status_code == 404:\n",
|
||||
" pass\n",
|
||||
" else:\n",
|
||||
" raise"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "bb197dfd-dd37-459e-8953-cc1b12f25bdd",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Here we use our balanced extraction mode."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "e3defc0a-c685-4fbd-bbb1-1270f1442e72",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_cloud import ExtractConfig\n",
|
||||
"\n",
|
||||
"extract_config = ExtractConfig(\n",
|
||||
" extraction_mode=\"BALANCED\",\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"agent = llama_extract.create_agent(\n",
|
||||
" name=\"lm317-datasheet\", data_schema=LM317Schema, config=extract_config\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "c0a0f9f9-2ef3-4a38-bd74-68d2c2e9e2d8",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Extracting Information from the LM317 Datasheet\n",
|
||||
"\n",
|
||||
"For this demonstration, please download a publicly available LM317 voltage regulator datasheet (for example, from Texas Instruments) and save it as `lm317.pdf` in the `./data` directory. Then run the cell below to extract the structured technical specifications."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "c58e8b7a-8f9b-46f3-8f72-3c2f96b49e8f",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Uploading files: 100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:01<00:00, 1.08s/it]\n",
|
||||
"Creating extraction jobs: 100%|████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 1.96it/s]\n",
|
||||
"Extracting files: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [01:27<00:00, 87.38s/it]\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# Path to the LM317 datasheet PDF\n",
|
||||
"lm317_pdf = \"./data/lm317_structured_extraction/lm317.pdf\"\n",
|
||||
"\n",
|
||||
"# Extract structured technical specifications from the datasheet\n",
|
||||
"lm317_extract = agent.extract(lm317_pdf)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "1a2e2e44-6c48-4a38-a6de-5f2f3c7d4d8b",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Assessing the Extraction Results\n",
|
||||
"\n",
|
||||
"The output will be a consolidated list of LM317 technical specifications. For each entry, you should see structured fields including:\n",
|
||||
"\n",
|
||||
"- **component_name**\n",
|
||||
"- **output_voltage** as a range (with separate `min_voltage` and `max_voltage` plus `unit`)\n",
|
||||
"- **dropout_voltage** and **max_current** as numbers\n",
|
||||
"- **input_voltage** as a structured range\n",
|
||||
"- **pin_configuration** with a `pin_count` and `layout`\n",
|
||||
"- **features** (if available)\n",
|
||||
"\n",
|
||||
"This structured approach makes it easier to standardize the information for downstream integration and verification. Engineers can click on the cited page numbers (in a UI that supports it) to validate the extraction."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "fb2abc44-7c9b-4b19-958e-d0d7b390ae57",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"{'specs': [{'component_name': 'LM317',\n",
|
||||
" 'output_voltage': {'min_voltage': 1.25, 'max_voltage': 37.0, 'unit': 'V'},\n",
|
||||
" 'dropout_voltage': 0.0,\n",
|
||||
" 'max_current': 1.5,\n",
|
||||
" 'input_voltage': {'min_voltage': 4.25, 'max_voltage': 40.0, 'unit': 'V'},\n",
|
||||
" 'pin_configuration': {'pin_count': 3,\n",
|
||||
" 'layout': '1: ADJUST, 2: OUTPUT, 3: INPUT'},\n",
|
||||
" 'features': ['Output voltage range adjustable from 1.25 V to 37 V',\n",
|
||||
" 'Output current greater than 1.5 A',\n",
|
||||
" 'Internal short-circuit current limiting',\n",
|
||||
" 'Thermal overload protection',\n",
|
||||
" 'Output safe-area compensation']}]}"
|
||||
]
|
||||
},
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# Display the extraction results\n",
|
||||
"lm317_extract.data"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "c7a2a523-095e-40bf-b713-f509c13a7747",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"You can also see the output result in the UI."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "dc22dfa5-b667-4fb0-8dbe-24e401b12389",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "e0e0c12a-9f89-4bb3-b40d-3e9f7c6d2fef",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Conclusion\n",
|
||||
"\n",
|
||||
"This notebook demonstrated how to use LlamaExtract with a structured extraction schema for the LM317 voltage regulator datasheet. By defining detailed subfields (such as splitting voltage ranges into minimum and maximum values, and structuring the pin configuration), we ensure that the extracted data is standardized and traceable through page citations. This approach minimizes manual effort and improves accuracy, providing a robust example of an agentic document workflow for technical documentation processing.\n",
|
||||
"\n",
|
||||
"Feel free to modify or extend the schema to capture additional technical details or to suit your own use cases."
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "llama_parse",
|
||||
"language": "python",
|
||||
"name": "llama_parse"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
@@ -0,0 +1,834 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Extracting data from Resumes\n",
|
||||
"\n",
|
||||
"Let us assume that we are running a hiring process for a company and we have received a list of resumes from candidates. We want to extract structured data from the resumes so that we can run a screening process and shortlist candidates. \n",
|
||||
"\n",
|
||||
"Take a look at one of the resumes in the `data/resumes` directory. "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"\n",
|
||||
" <iframe\n",
|
||||
" width=\"600\"\n",
|
||||
" height=\"400\"\n",
|
||||
" src=\"./data/resumes/ai_researcher.pdf\"\n",
|
||||
" frameborder=\"0\"\n",
|
||||
" allowfullscreen\n",
|
||||
" \n",
|
||||
" ></iframe>\n",
|
||||
" "
|
||||
],
|
||||
"text/plain": [
|
||||
"<IPython.lib.display.IFrame at 0x109a7dcd0>"
|
||||
]
|
||||
},
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from IPython.display import IFrame\n",
|
||||
"\n",
|
||||
"IFrame(src=\"./data/resumes/ai_researcher.pdf\", width=600, height=400)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"You will notice that all the resumes have different layouts but contain common information like name, email, experience, education, etc. \n",
|
||||
"\n",
|
||||
"With LlamaExtract, we will show you how to:\n",
|
||||
"- *Define* a data schema to extract the information of interest. \n",
|
||||
"- *Iterate* over the data schema to generalize the schema for multiple resumes.\n",
|
||||
"- *Finalize* the schema and schedule extractions for multiple resumes.\n",
|
||||
"\n",
|
||||
"We will start by defining a `LlamaExtract` client which provides a Python interface to the LlamaExtract API. "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from dotenv import load_dotenv\n",
|
||||
"from llama_cloud_services import LlamaExtract\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"# Load environment variables (put LLAMA_CLOUD_API_KEY in your .env file)\n",
|
||||
"load_dotenv(override=True)\n",
|
||||
"\n",
|
||||
"# Optionally, add your project id/organization id\n",
|
||||
"llama_extract = LlamaExtract()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Defining the data schema\n",
|
||||
"\n",
|
||||
"Next, let us try to extract two fields from the resume: `name` and `email`. We can either use a Python dictionary structure to define the `data_schema` as a JSON or use a Pydantic model instead, for brevity and convenience. In either case, our output is guaranteed to validate against this schema."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from pydantic import BaseModel, Field\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"class Resume(BaseModel):\n",
|
||||
" name: str = Field(description=\"The name of the candidate\")\n",
|
||||
" email: str = Field(description=\"The email address of the candidate\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Uploading files: 100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:02<00:00, 2.20s/it]\n",
|
||||
"Creating extraction jobs: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:02<00:00, 2.93s/it]\n",
|
||||
"Extracting files: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:02<00:00, 2.94s/it]\n",
|
||||
"Uploading files: 100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 1.13it/s]\n",
|
||||
"Creating extraction jobs: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 1.80it/s]\n",
|
||||
"Extracting files: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:15<00:00, 15.18s/it]\n",
|
||||
"Uploading files: 100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 1.16it/s]\n",
|
||||
"Creating extraction jobs: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 2.33it/s]\n",
|
||||
"Extracting files: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:32<00:00, 32.86s/it]\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from llama_cloud.core.api_error import ApiError\n",
|
||||
"\n",
|
||||
"try:\n",
|
||||
" existing_agent = llama_extract.get_agent(name=\"resume-screening\")\n",
|
||||
" if existing_agent:\n",
|
||||
" llama_extract.delete_agent(existing_agent.id)\n",
|
||||
"except ApiError as e:\n",
|
||||
" if e.status_code == 404:\n",
|
||||
" pass\n",
|
||||
" else:\n",
|
||||
" raise\n",
|
||||
"\n",
|
||||
"agent = llama_extract.create_agent(name=\"resume-screening\", data_schema=Resume)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"[ExtractionAgent(id=1fef43b5-8230-43b4-9e80-c1cddf53889c, name=resume-screening),\n",
|
||||
" ExtractionAgent(id=93f8508b-3570-46f0-ae62-6315b40043bd, name=receipt/noisebridge_receipt.pdf_56db3d92),\n",
|
||||
" ExtractionAgent(id=08315f0e-7146-430b-99b8-9701cb3ace6a, name=receipt/noisebridge_receipt.pdf_5c4730a7),\n",
|
||||
" ExtractionAgent(id=cfcd7756-015d-4dbd-b142-a3eefcb16cd3, name=resume/software_architect_resume.html_4a11cf15),\n",
|
||||
" ExtractionAgent(id=17cb83d9-601e-4f5c-a7aa-286e3045bcb4, name=resume/software_architect_resume.html_0b7d84a8),\n",
|
||||
" ExtractionAgent(id=adc8e88c-44d3-4613-a5aa-d666ef007494, name=slide/saas_slide.pdf_bcc627a5),\n",
|
||||
" ExtractionAgent(id=189f14cd-6370-4476-a6ad-36eafbc62618, name=slide/saas_slide.pdf_065aa22b),\n",
|
||||
" ExtractionAgent(id=b9938ca5-6225-43cb-89ea-b0065237792f, name=test2),\n",
|
||||
" ExtractionAgent(id=574d37b8-59dc-41e9-bde0-5c506a8eb670, name=test)]"
|
||||
]
|
||||
},
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"llama_extract.list_agents()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"{'name': 'Dr. Rachel Zhang', 'email': 'rachel.zhang@email.com'}"
|
||||
]
|
||||
},
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"resume = agent.extract(\"./data/resumes/ai_researcher.pdf\")\n",
|
||||
"resume.data"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Iterating over the data schema\n",
|
||||
"\n",
|
||||
"Now that we have created a data schema, let us add more fields to the schema. We will add `experience` and `education` fields to the schema. \n",
|
||||
"- We can create a new Pydantic model for each of these fields and represent `experience` and `education` as lists of these models. Doing this will allow us to extract multiple entities from the resume without having to pre-define how many experiences or education the candidate has. \n",
|
||||
"- We have added a `description` parameter to provide more context for extraction. We can use `description` to provide example inputs/outputs for the extraction. \n",
|
||||
"- Note that we have annotated the `start_date` and `end_date` fields with `Optional[str]` to indicate that these fields are optional. This is *important* because the schema will be used to extract data from multiple resumes and not all resumes will have the same format. A field must only be required if it is guaranteed to be present in all the resumes. \n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from typing import List, Optional\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"class Education(BaseModel):\n",
|
||||
" institution: str = Field(description=\"The institution of the candidate\")\n",
|
||||
" degree: str = Field(description=\"The degree of the candidate\")\n",
|
||||
" start_date: Optional[str] = Field(\n",
|
||||
" default=None, description=\"The start date of the candidate's education\"\n",
|
||||
" )\n",
|
||||
" end_date: Optional[str] = Field(\n",
|
||||
" default=None, description=\"The end date of the candidate's education\"\n",
|
||||
" )\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"class Experience(BaseModel):\n",
|
||||
" company: str = Field(description=\"The name of the company\")\n",
|
||||
" title: str = Field(description=\"The title of the candidate\")\n",
|
||||
" description: Optional[str] = Field(\n",
|
||||
" default=None, description=\"The description of the candidate's experience\"\n",
|
||||
" )\n",
|
||||
" start_date: Optional[str] = Field(\n",
|
||||
" default=None, description=\"The start date of the candidate's experience\"\n",
|
||||
" )\n",
|
||||
" end_date: Optional[str] = Field(\n",
|
||||
" default=None, description=\"The end date of the candidate's experience\"\n",
|
||||
" )\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"class Resume(BaseModel):\n",
|
||||
" name: str = Field(description=\"The name of the candidate\")\n",
|
||||
" email: str = Field(description=\"The email address of the candidate\")\n",
|
||||
" links: List[str] = Field(\n",
|
||||
" description=\"The links to the candidate's social media profiles\"\n",
|
||||
" )\n",
|
||||
" experience: List[Experience] = Field(description=\"The candidate's experience\")\n",
|
||||
" education: List[Education] = Field(description=\"The candidate's education\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Next, we will update the `data_schema` for the `resume-screening` agent to use the new `Resume` model. "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"{'name': 'Dr. Rachel Zhang',\n",
|
||||
" 'email': 'rachel.zhang@email.com',\n",
|
||||
" 'links': ['linkedin.com/in/rachelzhang',\n",
|
||||
" 'github.com/rzhang-ai',\n",
|
||||
" 'scholar.google.com/rachelzhang'],\n",
|
||||
" 'experience': [{'company': 'DeepMind',\n",
|
||||
" 'title': 'Senior Research Scientist',\n",
|
||||
" 'description': '- Lead researcher on large-scale multi-task learning systems, developing novel architectures that improve cross-task generalization by 40%\\n- Pioneered new approach to zero-shot learning using contrastive training, published in NeurIPS 2023\\n- Built and led team of 6 researchers working on foundational ML models\\n- Developed novel regularization techniques for large language models, reducing catastrophic forgetting by 35%',\n",
|
||||
" 'start_date': '2019',\n",
|
||||
" 'end_date': 'Present'},\n",
|
||||
" {'company': 'Google Research',\n",
|
||||
" 'title': 'Research Scientist',\n",
|
||||
" 'description': '- Developed probabilistic frameworks for robust ML, published in ICML 2018\\n- Created novel attention mechanisms for computer vision models, improving accuracy by 25%\\n- Led collaboration with Google Brain team on efficient training methods for transformer models\\n- Mentored 4 PhD interns and collaborated with academic institutions',\n",
|
||||
" 'start_date': '2015',\n",
|
||||
" 'end_date': '2019'},\n",
|
||||
" {'company': 'Columbia University',\n",
|
||||
" 'title': 'Research Assistant Professor',\n",
|
||||
" 'description': '- Published seminal work on Bayesian optimization methods (cited 1000+ times)\\n- Taught graduate-level courses in Machine Learning and Statistical Learning Theory\\n- Supervised 5 PhD students and 3 MSc students\\n- Secured $500K in research grants for probabilistic ML research',\n",
|
||||
" 'start_date': '2011',\n",
|
||||
" 'end_date': '2015'}],\n",
|
||||
" 'education': [{'institution': 'Columbia University',\n",
|
||||
" 'degree': 'Ph.D. in Computer Science',\n",
|
||||
" 'start_date': '2007',\n",
|
||||
" 'end_date': '2011'},\n",
|
||||
" {'institution': 'Stanford University',\n",
|
||||
" 'degree': 'M.S. in Computer Science',\n",
|
||||
" 'start_date': '2005',\n",
|
||||
" 'end_date': '2007'}]}"
|
||||
]
|
||||
},
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"agent.data_schema = Resume\n",
|
||||
"resume = agent.extract(\"./data/resumes/ai_researcher.pdf\")\n",
|
||||
"resume.data"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"This is a good start. Let us add a few more fields to the schema and re-run the extraction. "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"class TechnicalSkills(BaseModel):\n",
|
||||
" programming_languages: List[str] = Field(\n",
|
||||
" description=\"The programming languages the candidate is proficient in.\"\n",
|
||||
" )\n",
|
||||
" frameworks: List[str] = Field(\n",
|
||||
" description=\"The tools/frameworks the candidate is proficient in, e.g. React, Django, PyTorch, etc.\"\n",
|
||||
" )\n",
|
||||
" skills: List[str] = Field(\n",
|
||||
" description=\"Other general skills the candidate is proficient in, e.g. Data Engineering, Machine Learning, etc.\"\n",
|
||||
" )\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"class Resume(BaseModel):\n",
|
||||
" name: str = Field(description=\"The name of the candidate\")\n",
|
||||
" email: str = Field(description=\"The email address of the candidate\")\n",
|
||||
" links: List[str] = Field(\n",
|
||||
" description=\"The links to the candidate's social media profiles\"\n",
|
||||
" )\n",
|
||||
" experience: List[Experience] = Field(description=\"The candidate's experience\")\n",
|
||||
" education: List[Education] = Field(description=\"The candidate's education\")\n",
|
||||
" technical_skills: TechnicalSkills = Field(\n",
|
||||
" description=\"The candidate's technical skills\"\n",
|
||||
" )\n",
|
||||
" key_accomplishments: str = Field(\n",
|
||||
" description=\"Summarize the candidates highest achievements.\"\n",
|
||||
" )"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"{'name': 'Dr. Rachel Zhang, Ph.D.',\n",
|
||||
" 'email': 'rachel.zhang@email.com',\n",
|
||||
" 'links': ['linkedin.com/in/rachelzhang',\n",
|
||||
" 'github.com/rzhang-ai',\n",
|
||||
" 'scholar.google.com/rachelzhang'],\n",
|
||||
" 'experience': [{'company': 'DeepMind',\n",
|
||||
" 'title': 'Senior Research Scientist',\n",
|
||||
" 'description': 'Lead researcher on large-scale multi-task learning systems, developing novel architectures that improve cross-task generalization by 40%\\nPioneered new approach to zero-shot learning using contrastive training, published in NeurIPS 2023\\nBuilt and led team of 6 researchers working on foundational ML models\\nDeveloped novel regularization techniques for large language models, reducing catastrophic forgetting by 35%',\n",
|
||||
" 'start_date': '2019',\n",
|
||||
" 'end_date': 'Present'},\n",
|
||||
" {'company': 'Google Research',\n",
|
||||
" 'title': 'Research Scientist',\n",
|
||||
" 'description': 'Developed probabilistic frameworks for robust ML, published in ICML 2018\\nCreated novel attention mechanisms for computer vision models, improving accuracy by 25%\\nLed collaboration with Google Brain team on efficient training methods for transformer models\\nMentored 4 PhD interns and collaborated with academic institutions',\n",
|
||||
" 'start_date': '2015',\n",
|
||||
" 'end_date': '2019'},\n",
|
||||
" {'company': 'Columbia University',\n",
|
||||
" 'title': 'Research Assistant Professor',\n",
|
||||
" 'description': 'Published seminal work on Bayesian optimization methods (cited 1000+ times)\\nTaught graduate-level courses in Machine Learning and Statistical Learning Theory\\nSupervised 5 PhD students and 3 MSc students\\nSecured $500K in research grants for probabilistic ML research',\n",
|
||||
" 'start_date': '2011',\n",
|
||||
" 'end_date': '2015'}],\n",
|
||||
" 'education': [{'institution': 'Columbia University',\n",
|
||||
" 'degree': 'Ph.D. in Computer Science',\n",
|
||||
" 'start_date': '2007',\n",
|
||||
" 'end_date': '2011'},\n",
|
||||
" {'institution': 'Stanford University',\n",
|
||||
" 'degree': 'M.S. in Computer Science',\n",
|
||||
" 'start_date': '2005',\n",
|
||||
" 'end_date': '2007'}],\n",
|
||||
" 'technical_skills': {'programming_languages': ['Python',\n",
|
||||
" 'C++',\n",
|
||||
" 'Julia',\n",
|
||||
" 'CUDA'],\n",
|
||||
" 'frameworks': ['PyTorch', 'TensorFlow', 'JAX', 'Ray'],\n",
|
||||
" 'skills': ['Deep Learning',\n",
|
||||
" 'Reinforcement Learning',\n",
|
||||
" 'Probabilistic Models',\n",
|
||||
" 'Multi-Task Learning',\n",
|
||||
" 'Zero-Shot Learning',\n",
|
||||
" 'Neural Architecture Search']},\n",
|
||||
" 'key_accomplishments': 'AI researcher with 12+ years of experience spanning classical machine learning, deep learning, and probabilistic modeling. Led groundbreaking research in reinforcement learning, generative models, and multi-task learning. Published 25+ papers in top-tier conferences (NeurIPS, ICML, ICLR). Strong track record of transitioning theoretical advances into practical applications in both academic and industrial settings.'}"
|
||||
]
|
||||
},
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"agent.data_schema = Resume\n",
|
||||
"resume = agent.extract(\"./data/resumes/ai_researcher.pdf\")\n",
|
||||
"resume.data"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Finalizing the schema\n",
|
||||
"\n",
|
||||
"This is great! We have extracted a lot of key information from the resume that is well-typed and can be used downstream for further processing. Until now, this data is ephemeral and will be lost if we close the session. Let us save the state of our extraction and use it to extract data from multiple resumes. "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"agent.save()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"{'type': 'object',\n",
|
||||
" 'required': ['name',\n",
|
||||
" 'email',\n",
|
||||
" 'links',\n",
|
||||
" 'experience',\n",
|
||||
" 'education',\n",
|
||||
" 'technical_skills',\n",
|
||||
" 'key_accomplishments'],\n",
|
||||
" 'properties': {'name': {'type': 'string',\n",
|
||||
" 'description': 'The name of the candidate'},\n",
|
||||
" 'email': {'type': 'string',\n",
|
||||
" 'description': 'The email address of the candidate'},\n",
|
||||
" 'links': {'type': 'array',\n",
|
||||
" 'items': {'type': 'string'},\n",
|
||||
" 'description': \"The links to the candidate's social media profiles\"},\n",
|
||||
" 'education': {'type': 'array',\n",
|
||||
" 'items': {'type': 'object',\n",
|
||||
" 'required': ['institution', 'degree', 'start_date', 'end_date'],\n",
|
||||
" 'properties': {'degree': {'type': 'string',\n",
|
||||
" 'description': 'The degree of the candidate'},\n",
|
||||
" 'end_date': {'anyOf': [{'type': 'string'}, {'type': 'null'}],\n",
|
||||
" 'description': \"The end date of the candidate's education\"},\n",
|
||||
" 'start_date': {'anyOf': [{'type': 'string'}, {'type': 'null'}],\n",
|
||||
" 'description': \"The start date of the candidate's education\"},\n",
|
||||
" 'institution': {'type': 'string',\n",
|
||||
" 'description': 'The institution of the candidate'}},\n",
|
||||
" 'additionalProperties': False},\n",
|
||||
" 'description': \"The candidate's education\"},\n",
|
||||
" 'experience': {'type': 'array',\n",
|
||||
" 'items': {'type': 'object',\n",
|
||||
" 'required': ['company', 'title', 'description', 'start_date', 'end_date'],\n",
|
||||
" 'properties': {'title': {'type': 'string',\n",
|
||||
" 'description': 'The title of the candidate'},\n",
|
||||
" 'company': {'type': 'string', 'description': 'The name of the company'},\n",
|
||||
" 'end_date': {'anyOf': [{'type': 'string'}, {'type': 'null'}],\n",
|
||||
" 'description': \"The end date of the candidate's experience\"},\n",
|
||||
" 'start_date': {'anyOf': [{'type': 'string'}, {'type': 'null'}],\n",
|
||||
" 'description': \"The start date of the candidate's experience\"},\n",
|
||||
" 'description': {'anyOf': [{'type': 'string'}, {'type': 'null'}],\n",
|
||||
" 'description': \"The description of the candidate's experience\"}},\n",
|
||||
" 'additionalProperties': False},\n",
|
||||
" 'description': \"The candidate's experience\"},\n",
|
||||
" 'technical_skills': {'type': 'object',\n",
|
||||
" 'required': ['programming_languages', 'frameworks', 'skills'],\n",
|
||||
" 'properties': {'skills': {'type': 'array',\n",
|
||||
" 'items': {'type': 'string'},\n",
|
||||
" 'description': 'Other general skills the candidate is proficient in, e.g. Data Engineering, Machine Learning, etc.'},\n",
|
||||
" 'frameworks': {'type': 'array',\n",
|
||||
" 'items': {'type': 'string'},\n",
|
||||
" 'description': 'The tools/frameworks the candidate is proficient in, e.g. React, Django, PyTorch, etc.'},\n",
|
||||
" 'programming_languages': {'type': 'array',\n",
|
||||
" 'items': {'type': 'string'},\n",
|
||||
" 'description': 'The programming languages the candidate is proficient in.'}},\n",
|
||||
" 'description': \"The candidate's technical skills\",\n",
|
||||
" 'additionalProperties': False},\n",
|
||||
" 'key_accomplishments': {'type': 'string',\n",
|
||||
" 'description': 'Summarize the candidates highest achievements.'}},\n",
|
||||
" 'additionalProperties': False}"
|
||||
]
|
||||
},
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"agent = llama_extract.get_agent(\"resume-screening\")\n",
|
||||
"agent.data_schema # Latest schema should be returned"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Queueing extractions"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"For multiple resumes, we can use the `queue_extraction` method to run extractions asynchronously. This is ideal for processing batch extraction jobs."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Uploading files: 100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 3/3 [00:01<00:00, 2.13it/s]\n",
|
||||
"Creating extraction jobs: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 3/3 [00:00<00:00, 5.83it/s]\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"\n",
|
||||
"# All resumes in the data/resumes directory\n",
|
||||
"resumes = []\n",
|
||||
"\n",
|
||||
"with os.scandir(\"./data/resumes\") as entries:\n",
|
||||
" for entry in entries:\n",
|
||||
" if entry.is_file():\n",
|
||||
" resumes.append(entry.path)\n",
|
||||
"\n",
|
||||
"jobs = await agent.queue_extraction(resumes)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"To get the latest status of the extractions for any `job_id`, we can use the `get_extraction_job` method. \n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"[<StatusEnum.PENDING: 'PENDING'>,\n",
|
||||
" <StatusEnum.PENDING: 'PENDING'>,\n",
|
||||
" <StatusEnum.PENDING: 'PENDING'>]"
|
||||
]
|
||||
},
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"[agent.get_extraction_job(job_id=job.id).status for job in jobs]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"We notice that all extraction runs are in a PENDING state. We can check back again to see if the extractions have completed. "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"[<StatusEnum.SUCCESS: 'SUCCESS'>,\n",
|
||||
" <StatusEnum.SUCCESS: 'SUCCESS'>,\n",
|
||||
" <StatusEnum.SUCCESS: 'SUCCESS'>]"
|
||||
]
|
||||
},
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"[agent.get_extraction_job(job_id=job.id).status for job in jobs]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Retrieving results\n",
|
||||
"\n",
|
||||
"Let us now retrieve the results of the extractions. If the status of the extraction is `SUCCESS`, we can retrieve the data from the `data` field. In case there are errors (status = `ERROR`), we can retrieve the error message from the `error` field. \n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"results = []\n",
|
||||
"for job in jobs:\n",
|
||||
" extract_run = agent.get_extraction_run_for_job(job.id)\n",
|
||||
" if extract_run.status == \"SUCCESS\":\n",
|
||||
" results.append(extract_run.data)\n",
|
||||
" else:\n",
|
||||
" print(f\"Extraction status for job {job.id}: {extract_run.status}\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"{'name': 'Dr. Rachel Zhang, Ph.D.',\n",
|
||||
" 'email': 'rachel.zhang@email.com',\n",
|
||||
" 'links': ['linkedin.com/in/rachelzhang',\n",
|
||||
" 'github.com/rzhang-ai',\n",
|
||||
" 'scholar.google.com/rachelzhang'],\n",
|
||||
" 'education': [{'degree': 'Ph.D. in Computer Science',\n",
|
||||
" 'end_date': '2011',\n",
|
||||
" 'start_date': '2007',\n",
|
||||
" 'institution': 'Columbia University'},\n",
|
||||
" {'degree': 'M.S. in Computer Science',\n",
|
||||
" 'end_date': '2007',\n",
|
||||
" 'start_date': '2005',\n",
|
||||
" 'institution': 'Stanford University'}],\n",
|
||||
" 'experience': [{'title': 'Senior Research Scientist',\n",
|
||||
" 'company': 'DeepMind',\n",
|
||||
" 'end_date': None,\n",
|
||||
" 'start_date': '2019',\n",
|
||||
" 'description': '- Lead researcher on large-scale multi-task learning systems, developing novel architectures that improve cross-task generalization by 40%\\n- Pioneered new approach to zero-shot learning using contrastive training, published in NeurIPS 2023\\n- Built and led team of 6 researchers working on foundational ML models\\n- Developed novel regularization techniques for large language models, reducing catastrophic forgetting by 35%'},\n",
|
||||
" {'title': 'Research Scientist',\n",
|
||||
" 'company': 'Google Research',\n",
|
||||
" 'end_date': '2019',\n",
|
||||
" 'start_date': '2015',\n",
|
||||
" 'description': '- Developed probabilistic frameworks for robust ML, published in ICML 2018\\n- Created novel attention mechanisms for computer vision models, improving accuracy by 25%\\n- Led collaboration with Google Brain team on efficient training methods for transformer models\\n- Mentored 4 PhD interns and collaborated with academic institutions'},\n",
|
||||
" {'title': 'Research Assistant Professor',\n",
|
||||
" 'company': 'Columbia University',\n",
|
||||
" 'end_date': '2015',\n",
|
||||
" 'start_date': '2011',\n",
|
||||
" 'description': '- Published seminal work on Bayesian optimization methods (cited 1000+ times)\\n- Taught graduate-level courses in Machine Learning and Statistical Learning Theory\\n- Supervised 5 PhD students and 3 MSc students\\n- Secured $500K in research grants for probabilistic ML research'}],\n",
|
||||
" 'technical_skills': {'skills': ['Deep Learning',\n",
|
||||
" 'Reinforcement Learning',\n",
|
||||
" 'Probabilistic Models',\n",
|
||||
" 'Multi-Task Learning',\n",
|
||||
" 'Zero-Shot Learning',\n",
|
||||
" 'Neural Architecture Search'],\n",
|
||||
" 'frameworks': ['PyTorch', 'TensorFlow', 'JAX', 'Ray'],\n",
|
||||
" 'programming_languages': ['Python', 'C++', 'Julia', 'CUDA']},\n",
|
||||
" 'key_accomplishments': 'AI researcher with 12+ years of experience spanning classical machine learning, deep learning, and probabilistic modeling. Led groundbreaking research in reinforcement learning, generative models, and multi-task learning. Published 25+ papers in top-tier conferences (NeurIPS, ICML, ICLR). Strong track record of transitioning theoretical advances into practical applications in both academic and industrial settings.'}"
|
||||
]
|
||||
},
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"results[0]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"{'name': 'Alex Park',\n",
|
||||
" 'email': 'alex park@email.com',\n",
|
||||
" 'links': ['linkedin.com/in/alexpark'],\n",
|
||||
" 'education': [{'degree': 'M.S. Computer Science',\n",
|
||||
" 'end_date': None,\n",
|
||||
" 'start_date': None,\n",
|
||||
" 'institution': 'University of California, Berkeley'},\n",
|
||||
" {'degree': 'B.S. Computer Science',\n",
|
||||
" 'end_date': None,\n",
|
||||
" 'start_date': None,\n",
|
||||
" 'institution': 'University of California, Berkeley'}],\n",
|
||||
" 'experience': [{'title': 'Senior Machine Learning Engineer',\n",
|
||||
" 'company': 'SearchTech AI',\n",
|
||||
" 'end_date': None,\n",
|
||||
" 'start_date': None,\n",
|
||||
" 'description': 'Led development of next-generation learning-to-rank system using BER\\nArchitected and deployed real-time personalization system processing 10\\nIncreasing CTR by 15%\\nImproving search relevance by 24% (NDCG@10)'},\n",
|
||||
" {'title': '',\n",
|
||||
" 'company': 'Commerce Corp',\n",
|
||||
" 'end_date': None,\n",
|
||||
" 'start_date': None,\n",
|
||||
" 'description': 'Developed semantic search system using transformer models and approximate nearest neighbors, reducing null search results by 35%'},\n",
|
||||
" {'title': 'Machine Learning Engineer',\n",
|
||||
" 'company': 'Tech Solutions Inc',\n",
|
||||
" 'end_date': None,\n",
|
||||
" 'start_date': None,\n",
|
||||
" 'description': 'Implemented query understanding pipeline'},\n",
|
||||
" {'title': 'Software Engineer',\n",
|
||||
" 'company': '',\n",
|
||||
" 'end_date': None,\n",
|
||||
" 'start_date': None,\n",
|
||||
" 'description': 'Built data pipelines and Flasticsearch'}],\n",
|
||||
" 'technical_skills': {'skills': ['Elasticsearch',\n",
|
||||
" 'Solr',\n",
|
||||
" 'Lucene',\n",
|
||||
" 'Python',\n",
|
||||
" 'SQL',\n",
|
||||
" 'Java',\n",
|
||||
" 'Scala',\n",
|
||||
" 'Shell Scripting'],\n",
|
||||
" 'frameworks': ['PyTorch',\n",
|
||||
" 'TensorFlow',\n",
|
||||
" 'Scikit-learn',\n",
|
||||
" 'BERT',\n",
|
||||
" 'Word2Vec',\n",
|
||||
" 'FastAI',\n",
|
||||
" 'BM25',\n",
|
||||
" 'FAISS',\n",
|
||||
" 'Docker',\n",
|
||||
" 'Kubernetes'],\n",
|
||||
" 'programming_languages': []},\n",
|
||||
" 'key_accomplishments': 'Machine Learning Engineer with 5 years of experience building and deploying large-scale search and relevance systems: Specialized in developing personalized search algorithms, learning-to-rank models; and recommendation systems. Strong track record of improving search relevance metrics and user engagement through ML-driven solutions:'}"
|
||||
]
|
||||
},
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"results[1]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"{'name': 'Sarah Chen',\n",
|
||||
" 'email': 'sarah.chen@email.com',\n",
|
||||
" 'links': [],\n",
|
||||
" 'education': [{'degree': 'Master of Science in Computer Science',\n",
|
||||
" 'end_date': '2013',\n",
|
||||
" 'start_date': None,\n",
|
||||
" 'institution': 'Stanford University'},\n",
|
||||
" {'degree': 'Bachelor of Science in Computer Engineering',\n",
|
||||
" 'end_date': '2011',\n",
|
||||
" 'start_date': None,\n",
|
||||
" 'institution': 'University of California, Berkeley'}],\n",
|
||||
" 'experience': [{'title': 'Senior Software Architect',\n",
|
||||
" 'company': 'TechCorp Solutions',\n",
|
||||
" 'end_date': None,\n",
|
||||
" 'start_date': '2020',\n",
|
||||
" 'description': '- Led architectural design and implementation of a cloud-native platform serving 2M+ users\\n- Established architectural guidelines and best practices adopted across 12 development teams\\n- Reduced system latency by 40% through implementation of event-driven architecture\\n- Mentored 15+ senior developers in cloud-native development practices'},\n",
|
||||
" {'title': 'Lead Software Engineer',\n",
|
||||
" 'company': 'DataFlow Systems',\n",
|
||||
" 'end_date': '2020',\n",
|
||||
" 'start_date': '2016',\n",
|
||||
" 'description': '- Architected and led development of distributed data processing platform handling 5TB daily\\n- Designed microservices architecture reducing deployment time by 65%\\n- Led migration of legacy monolith to cloud-native architecture\\n- Managed team of 8 engineers across 3 international locations'},\n",
|
||||
" {'title': 'Senior Software Engineer',\n",
|
||||
" 'company': 'InnovateTech',\n",
|
||||
" 'end_date': '2016',\n",
|
||||
" 'start_date': '2013',\n",
|
||||
" 'description': '- Developed high-performance trading platform processing 100K transactions per second\\n- Implemented real-time analytics engine reducing processing latency by 75%\\n- Led adoption of container orchestration reducing deployment costs by 35%'}],\n",
|
||||
" 'technical_skills': {'skills': ['Architecture & Design',\n",
|
||||
" 'Microservices',\n",
|
||||
" 'Event-Driven Architecture',\n",
|
||||
" 'Domain-Driven Design',\n",
|
||||
" 'REST APIs',\n",
|
||||
" 'Cloud Platforms'],\n",
|
||||
" 'frameworks': ['AWS (Advanced)', 'Azure', 'Google Cloud Platform'],\n",
|
||||
" 'programming_languages': ['Java', 'Python', 'Go', 'JavaScript/TypeScript']},\n",
|
||||
" 'key_accomplishments': '- Co-inventor on three patents for distributed systems architecture\\n- Published paper on \"Scalable Microservices Architecture\" at IEEE Cloud Computing Conference 2022\\n- Keynote Speaker, CloudCon 2023: \"Future of Cloud-Native Architecture\"\\n- Regular presenter at local tech meetups and conferences'}"
|
||||
]
|
||||
},
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"results[2]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Congratulations! You now have an agent that can extract structured data from resumes. \n",
|
||||
"- You can now use this agent to extract data from more resumes and use the extracted data for further processing. \n",
|
||||
"- To update the schema, you can simply update the `data_schema` attribute of the agent and re-run the extraction. \n",
|
||||
"- You can also use the `save` method to save the state of the agent and persist changes to the schema for future use. \n",
|
||||
"\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
||||
@@ -0,0 +1,450 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "00f6713b-2a32-4f8f-80e5-9a7d9b6e3b90",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Solar Panel Datasheet Comparison Workflow\n",
|
||||
"\n",
|
||||
"<a href=\"https://colab.research.google.com/github/run-llama/llama_cloud_services/blob/main/examples/extract/solar_panel_e2e_comparison.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"This notebook demonstrates an end‑to‑end agentic workflow using LlamaExtract and the LlamaIndex event‑driven workflow framework. In this workflow, we:\n",
|
||||
"\n",
|
||||
"1. **Extract** structured technical specifications from a solar panel datasheet (e.g. a PDF downloaded from a vendor).\n",
|
||||
"2. **Load** design requirements (provided as a text blob) for a lab‑grade solar panel.\n",
|
||||
"3. **Generate** a detailed comparison report by triggering an event that injects both the extracted data and the requirements into an LLM prompt.\n",
|
||||
"\n",
|
||||
"The workflow is designed for renewable energy engineers who need to quickly validate that a solar panel meets specific design criteria.\n",
|
||||
"\n",
|
||||
"The following notebook uses the event‑driven syntax (with custom events, steps, and a workflow class) adapted from the technical datasheet and contract review examples."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "36d8e34e-ed98-46ac-b744-1642f6e253d5",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Setup and Load Data\n",
|
||||
"\n",
|
||||
"We download the [Honey M TSM-DE08M.08(II) datasheet](https://static.trinasolar.com/sites/default/files/EU_Datasheet_HoneyM_DE08M.08%28II%29_2021_A.pdf) as a PDF.\n",
|
||||
"\n",
|
||||
"**NOTE**: The design requirements are already stored in `data/solar_panel_e2e_comparison/design_reqs.txt`."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "1de7b1b3-c285-492c-8b2e-b37974b4fc63",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"--2025-04-01 14:47:56-- https://static.trinasolar.com/sites/default/files/EU_Datasheet_HoneyM_DE08M.08%28II%29_2021_A.pdf\n",
|
||||
"Resolving static.trinasolar.com (static.trinasolar.com)... 47.246.23.232, 47.246.23.234, 47.246.23.227, ...\n",
|
||||
"Connecting to static.trinasolar.com (static.trinasolar.com)|47.246.23.232|:443... connected.\n",
|
||||
"WARNING: cannot verify static.trinasolar.com's certificate, issued by ‘CN=DigiCert Global G2 TLS RSA SHA256 2020 CA1,O=DigiCert Inc,C=US’:\n",
|
||||
" Unable to locally verify the issuer's authority.\n",
|
||||
"HTTP request sent, awaiting response... 200 OK\n",
|
||||
"Length: 1888183 (1.8M) [application/pdf]\n",
|
||||
"Saving to: ‘data/solar_panel_e2e_comparison/datasheet.pdf’\n",
|
||||
"\n",
|
||||
"data/solar_panel_e2 100%[===================>] 1.80M 7.47MB/s in 0.2s \n",
|
||||
"\n",
|
||||
"2025-04-01 14:47:56 (7.47 MB/s) - ‘data/solar_panel_e2e_comparison/datasheet.pdf’ saved [1888183/1888183]\n",
|
||||
"\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"!wget https://static.trinasolar.com/sites/default/files/EU_Datasheet_HoneyM_DE08M.08%28II%29_2021_A.pdf -O data/solar_panel_e2e_comparison/datasheet.pdf --no-check-certificate"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "89d2f4c9-f785-424d-a409-3381796c457c",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Define the Structured Extraction Schema\n",
|
||||
"\n",
|
||||
"We define a new, rich schema called `SolarPanelSchema` to capture key technical details from the datasheet. This schema includes:\n",
|
||||
"\n",
|
||||
"- **PowerRange:** Structured as minimum and maximum power output (in Watts).\n",
|
||||
"- **SolarPanelSpec:** Includes module name, power output range, maximum efficiency, certifications, and a mapping of page citations.\n",
|
||||
"\n",
|
||||
"This schema replaces the earlier LM317 schema and will be used when creating our extraction agent."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "bfb40d48-36e0-4b1c-97a1-32a1704c582b",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from pydantic import BaseModel, Field\n",
|
||||
"from typing import List\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"class PowerRange(BaseModel):\n",
|
||||
" min_power: float = Field(..., description=\"Minimum power output in Watts\")\n",
|
||||
" max_power: float = Field(..., description=\"Maximum power output in Watts\")\n",
|
||||
" unit: str = Field(\"W\", description=\"Power unit\")\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"class SolarPanelSpec(BaseModel):\n",
|
||||
" module_name: str = Field(..., description=\"Name or model of the solar panel module\")\n",
|
||||
" power_output: PowerRange = Field(..., description=\"Power output range\")\n",
|
||||
" maximum_efficiency: float = Field(\n",
|
||||
" ..., description=\"Maximum module efficiency in percentage\"\n",
|
||||
" )\n",
|
||||
" temperature_coefficient: float = Field(\n",
|
||||
" ..., description=\"Temperature coefficient in %/°C\"\n",
|
||||
" )\n",
|
||||
" certifications: List[str] = Field([], description=\"List of certifications\")\n",
|
||||
" page_citations: dict = Field(\n",
|
||||
" ..., description=\"Mapping of each extracted field to its page numbers\"\n",
|
||||
" )\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"class SolarPanelSchema(BaseModel):\n",
|
||||
" specs: List[SolarPanelSpec] = Field(\n",
|
||||
" ..., description=\"List of extracted solar panel specifications\"\n",
|
||||
" )"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "19dc309e-7cec-43c1-8f6c-72e14df58f8f",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Initialize Extraction Agent\n",
|
||||
"\n",
|
||||
"Here we initialize our extraction agent that will be responsible for extracting the schema from the solar panel datasheet."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "c9d9f4a2-2e14-493d-8a7e-d01159d38b8f",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from dotenv import load_dotenv\n",
|
||||
"from llama_cloud_services import LlamaExtract\n",
|
||||
"from llama_cloud.core.api_error import ApiError\n",
|
||||
"from llama_cloud import ExtractConfig\n",
|
||||
"\n",
|
||||
"# Initialize the LlamaExtract client\n",
|
||||
"llama_extract = LlamaExtract(\n",
|
||||
" project_id=\"2fef999e-1073-40e6-aeb3-1f3c0e64d99b\",\n",
|
||||
" organization_id=\"43b88c8f-e488-46f6-9013-698e3d2e374a\",\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "ec0eb2a7-6e02-45da-a6af-227e2f7c81f2",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"try:\n",
|
||||
" existing_agent = llama_extract.get_agent(name=\"solar-panel-datasheet\")\n",
|
||||
" if existing_agent:\n",
|
||||
" llama_extract.delete_agent(existing_agent.id)\n",
|
||||
"except ApiError as e:\n",
|
||||
" if e.status_code == 404:\n",
|
||||
" pass\n",
|
||||
" else:\n",
|
||||
" raise\n",
|
||||
"\n",
|
||||
"extract_config = ExtractConfig(\n",
|
||||
" extraction_mode=\"BALANCED\",\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"agent = llama_extract.create_agent(\n",
|
||||
" name=\"solar-panel-datasheet\", data_schema=SolarPanelSchema, config=extract_config\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "b4d7bb60-0456-4a2d-8d48-14f9bb3e71d2",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Workflow Overview\n",
|
||||
"\n",
|
||||
"The workflow consists of four main steps:\n",
|
||||
"\n",
|
||||
"1. **parse_datasheet:** Reads the solar panel datasheet (PDF) and converts its content into text (with page citations).\n",
|
||||
"2. **load_requirements:** Loads the design requirements (as a text blob) that will be injected into the prompt.\n",
|
||||
"3. **generate_comparison_report:** Constructs a prompt using the extracted datasheet content and design requirements and triggers the LLM to generate a comparison report.\n",
|
||||
"4. **output_result:** Logs and returns the final report as the workflow’s result.\n",
|
||||
"\n",
|
||||
"Each step is implemented as an asynchronous function decorated with `@step`, and the workflow is built by subclassing `Workflow`."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "7c482e3a-66b4-4e1b-8d2d-9a9c6b3967f3",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.core.workflow import (\n",
|
||||
" Event,\n",
|
||||
" StartEvent,\n",
|
||||
" StopEvent,\n",
|
||||
" Context,\n",
|
||||
" Workflow,\n",
|
||||
" step,\n",
|
||||
")\n",
|
||||
"from llama_index.llms.openai import OpenAI\n",
|
||||
"from llama_index.core.prompts import ChatPromptTemplate\n",
|
||||
"from llama_cloud_services import LlamaExtract\n",
|
||||
"from llama_cloud.core.api_error import ApiError\n",
|
||||
"from pydantic import BaseModel, Field\n",
|
||||
"from typing import List\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"# Define output schema for the comparison report (for reference)\n",
|
||||
"class ComparisonReportOutput(BaseModel):\n",
|
||||
" component_name: str = Field(\n",
|
||||
" ..., description=\"The name of the component being evaluated.\"\n",
|
||||
" )\n",
|
||||
" meets_requirements: bool = Field(\n",
|
||||
" ...,\n",
|
||||
" description=\"Overall indicator of whether the component meets the design criteria.\",\n",
|
||||
" )\n",
|
||||
" summary: str = Field(..., description=\"A brief summary of the evaluation results.\")\n",
|
||||
" details: dict = Field(\n",
|
||||
" ..., description=\"Detailed comparisons for each key parameter.\"\n",
|
||||
" )\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"# Define custom events\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"class DatasheetParseEvent(Event):\n",
|
||||
" datasheet_content: dict\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"class RequirementsLoadEvent(Event):\n",
|
||||
" requirements_text: str\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"class ComparisonReportEvent(Event):\n",
|
||||
" report: ComparisonReportOutput\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"class LogEvent(Event):\n",
|
||||
" msg: str\n",
|
||||
" delta: bool = False\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"# For our demonstration, we assume that LlamaExtract is used to parse the datasheet into text.\n",
|
||||
"# We'll also use OpenAI (via LlamaIndex) as our LLM for generating the report.\n",
|
||||
"\n",
|
||||
"llm = OpenAI(model=\"gpt-4o\") # or your preferred model"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "67a0c391-c7f5-4b93-8d6b-9e31b2d7a817",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"class SolarPanelComparisonWorkflow(Workflow):\n",
|
||||
" \"\"\"\n",
|
||||
" Workflow to extract data from a solar panel datasheet and generate a comparison report\n",
|
||||
" against provided design requirements.\n",
|
||||
" \"\"\"\n",
|
||||
"\n",
|
||||
" def __init__(self, agent: LlamaExtract, requirements_path: str, **kwargs):\n",
|
||||
" super().__init__(**kwargs)\n",
|
||||
" self.agent = agent\n",
|
||||
" # Load design requirements from file as a text blob\n",
|
||||
" with open(requirements_path, \"r\") as f:\n",
|
||||
" self.requirements_text = f.read()\n",
|
||||
"\n",
|
||||
" @step\n",
|
||||
" async def parse_datasheet(\n",
|
||||
" self, ctx: Context, ev: StartEvent\n",
|
||||
" ) -> DatasheetParseEvent:\n",
|
||||
" # datasheet_path is provided in the StartEvent\n",
|
||||
" datasheet_path = (\n",
|
||||
" ev.datasheet_path\n",
|
||||
" ) # e.g., \"./data/solar_panel_comparison/datasheet.pdf\"\n",
|
||||
" extraction_result = await self.agent.aextract(datasheet_path)\n",
|
||||
" datasheet_dict = (\n",
|
||||
" extraction_result.data\n",
|
||||
" ) # assumed to be a string with page citations\n",
|
||||
" await ctx.set(\"datasheet_content\", datasheet_dict)\n",
|
||||
" ctx.write_event_to_stream(LogEvent(msg=\"Datasheet parsed successfully.\"))\n",
|
||||
" return DatasheetParseEvent(datasheet_content=datasheet_dict)\n",
|
||||
"\n",
|
||||
" @step\n",
|
||||
" async def load_requirements(\n",
|
||||
" self, ctx: Context, ev: DatasheetParseEvent\n",
|
||||
" ) -> RequirementsLoadEvent:\n",
|
||||
" # Use the pre-loaded requirements text from __init__\n",
|
||||
" req_text = self.requirements_text\n",
|
||||
" ctx.write_event_to_stream(LogEvent(msg=\"Design requirements loaded.\"))\n",
|
||||
" return RequirementsLoadEvent(requirements_text=req_text)\n",
|
||||
"\n",
|
||||
" @step\n",
|
||||
" async def generate_comparison_report(\n",
|
||||
" self, ctx: Context, ev: RequirementsLoadEvent\n",
|
||||
" ) -> StopEvent:\n",
|
||||
" # Build a prompt that injects both the extracted datasheet content and the design requirements\n",
|
||||
" datasheet_content = await ctx.get(\"datasheet_content\")\n",
|
||||
" prompt_str = \"\"\"\n",
|
||||
"You are an expert renewable energy engineer.\n",
|
||||
"\n",
|
||||
"Compare the following solar panel datasheet information with the design requirements.\n",
|
||||
"\n",
|
||||
"Design Requirements:\n",
|
||||
"{requirements_text}\n",
|
||||
"\n",
|
||||
"Extracted Datasheet Information:\n",
|
||||
"{datasheet_content}\n",
|
||||
"\n",
|
||||
"Generate a detailed comparison report in JSON format with the following schema:\n",
|
||||
" - component_name: string\n",
|
||||
" - meets_requirements: boolean\n",
|
||||
" - summary: string\n",
|
||||
" - details: dictionary of comparisons for each parameter\n",
|
||||
"\n",
|
||||
"For each parameter (Maximum Power, Open-Circuit Voltage, Short-Circuit Current, Efficiency, Temperature Coefficient),\n",
|
||||
"indicate PASS or FAIL and provide brief explanations and recommendations.\n",
|
||||
"\"\"\"\n",
|
||||
"\n",
|
||||
" # extract from contract\n",
|
||||
" prompt = ChatPromptTemplate.from_messages([(\"user\", prompt_str)])\n",
|
||||
"\n",
|
||||
" # Call the LLM to generate the report using the prompt\n",
|
||||
" report_output = await llm.astructured_predict(\n",
|
||||
" ComparisonReportOutput,\n",
|
||||
" prompt,\n",
|
||||
" requirements_text=ev.requirements_text,\n",
|
||||
" datasheet_content=str(datasheet_content),\n",
|
||||
" )\n",
|
||||
" ctx.write_event_to_stream(LogEvent(msg=\"Comparison report generated.\"))\n",
|
||||
" return StopEvent(\n",
|
||||
" result={\"report\": report_output, \"datasheet_content\": datasheet_content}\n",
|
||||
" )"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "d205f532-1a11-4a48-b5a8-87a7f85e9ce7",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Running the Workflow\n",
|
||||
"\n",
|
||||
"Below, we instantiate and run the workflow. We inject the design requirements as a text blob (no custom code to load) and pass the path to the solar panel datasheet (the HoneyM datasheet from Trina).\n",
|
||||
"\n",
|
||||
"The design requirements are:\n",
|
||||
"\n",
|
||||
"```\n",
|
||||
"Solar Panel Design Requirements:\n",
|
||||
"- Power Output Range: ≥ 350 W\n",
|
||||
"- Maximum Efficiency: ≥ 18%\n",
|
||||
"- Certifications: Must include IEC61215 and UL1703\n",
|
||||
"```\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "6b24fa61-a2f5-4ebb-84eb-1c9b48683b1b",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import nest_asyncio\n",
|
||||
"\n",
|
||||
"nest_asyncio.apply()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "be3ebad5-1f70-4671-a2ec-17bf9e4d788f",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Path to design requirements file (e.g., a text file with design criteria for solar panels)\n",
|
||||
"requirements_path = \"./data/solar_panel_e2e_comparison/design_reqs.txt\"\n",
|
||||
"\n",
|
||||
"# Instantiate the workflow\n",
|
||||
"workflow = SolarPanelComparisonWorkflow(\n",
|
||||
" agent=agent, requirements_path=requirements_path, verbose=True, timeout=120\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"# Run the workflow; pass the datasheet path in the StartEvent\n",
|
||||
"result = await workflow.run(\n",
|
||||
" datasheet_path=\"./data/solar_panel_e2e_comparison/datasheet.pdf\"\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "e1e61f1e-8701-4acc-8f99-cc89d8aae535",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\n",
|
||||
"********Final Comparison Report:********\n",
|
||||
"\n",
|
||||
"{\n",
|
||||
" \"component_name\": \"TSM-DE08M.08(II)\",\n",
|
||||
" \"meets_requirements\": true,\n",
|
||||
" \"summary\": \"The solar panel TSM-DE08M.08(II) meets all the design requirements, making it a suitable choice for the intended application.\",\n",
|
||||
" \"details\": {\n",
|
||||
" \"Maximum Power Output\": \"PASS - The panel's power output ranges from 360 W to 385 W, exceeding the minimum requirement of 350 W.\",\n",
|
||||
" \"Open-Circuit Voltage\": \"PASS - The datasheet does not specify Voc, but the panel meets other critical requirements. Verification of Voc is recommended.\",\n",
|
||||
" \"Short-Circuit Current\": \"PASS - The datasheet does not specify Isc, but the panel meets other critical requirements. Verification of Isc is recommended.\",\n",
|
||||
" \"Efficiency\": \"PASS - The panel's efficiency is 21.0%, which is above the required 18%.\",\n",
|
||||
" \"Temperature Coefficient\": \"PASS - The temperature coefficient is -0.34%/°C, which is better than the maximum allowable -0.5%/°C.\"\n",
|
||||
" }\n",
|
||||
"}\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(\"\\n********Final Comparison Report:********\\n\")\n",
|
||||
"print(result[\"report\"].model_dump_json(indent=4))\n",
|
||||
"# print(\"\\n********Datasheet Content:********\\n\", result[\"datasheet_content\"])"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "llama_parse",
|
||||
"language": "python",
|
||||
"name": "llama_parse"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
|
After Width: | Height: | Size: 6.9 MiB |
@@ -0,0 +1,454 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# LlamaParse Agent\n",
|
||||
"\n",
|
||||
"This demo walks through using an OpenAI Agent with [LlamaParse](https://cloud.llamaindex.ai).\n",
|
||||
"\n",
|
||||
"Status:\n",
|
||||
"| Last Executed | Version | State |\n",
|
||||
"|---------------|---------|------------|\n",
|
||||
"| Aug-19-2025 | 0.6.61 | Maintained |"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Setup"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!pip install llama-cloud-services \"llama-index>=0.13.0<0.14.0\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"\n",
|
||||
"os.environ[\"LLAMA_CLOUD_API_KEY\"] = \"llx-...\"\n",
|
||||
"os.environ[\"OPENAI_API_KEY\"] = \"sk-...\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.core import Settings\n",
|
||||
"from llama_index.embeddings.openai import OpenAIEmbedding\n",
|
||||
"from llama_index.llms.openai import OpenAI\n",
|
||||
"\n",
|
||||
"Settings.embed_model = OpenAIEmbedding(model=\"text-embedding-3-small\")\n",
|
||||
"Settings.llm = OpenAI(model=\"gpt-5-mini\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Parsing \n",
|
||||
"\n",
|
||||
"For parsing, lets use a [recent paper](https://huggingface.co/papers/2403.09611) on Multi-Modal pretraining"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!wget https://arxiv.org/pdf/2403.09611.pdf -O paper.pdf"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Below, we can tell the parser to skip content we don't want. In this case, the references section will just add noise to a RAG system."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_cloud_services import LlamaParse\n",
|
||||
"from sympy import O\n",
|
||||
"\n",
|
||||
"parser = LlamaParse(\n",
|
||||
" parse_mode=\"parse_page_with_agent\",\n",
|
||||
" model=\"openai-gpt-4-1-mini\",\n",
|
||||
" high_res_ocr=True,\n",
|
||||
" adaptive_long_table=True,\n",
|
||||
" outlined_table_extraction=True,\n",
|
||||
" output_tables_as_HTML=True,\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Started parsing the file under job_id cd1958b0-b260-4a63-aa74-bf829a0c125f\n",
|
||||
".."
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"result = await parser.aparse(\"paper.pdf\")\n",
|
||||
"documents = result.get_markdown_documents(split_by_page=False)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.core.node_parser import SentenceSplitter\n",
|
||||
"\n",
|
||||
"# Chain splitters to ensure chunk size requirements are met\n",
|
||||
"nodes = SentenceSplitter(chunk_size=2048, chunk_overlap=256).get_nodes_from_documents(\n",
|
||||
" documents\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Chat over the paper, lets find out what it is about!"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.core import VectorStoreIndex, SummaryIndex\n",
|
||||
"\n",
|
||||
"vector_index = VectorStoreIndex(nodes=nodes)\n",
|
||||
"summary_index = SummaryIndex(nodes=nodes)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.core.agent import FunctionAgent\n",
|
||||
"from llama_index.core.tools import QueryEngineTool\n",
|
||||
"\n",
|
||||
"tools = [\n",
|
||||
" QueryEngineTool.from_defaults(\n",
|
||||
" vector_index.as_query_engine(\n",
|
||||
" similarity_top_k=4,\n",
|
||||
" ),\n",
|
||||
" name=\"query\",\n",
|
||||
" description=\"Send a query that requires only a subset of the top-k documents to be considered\",\n",
|
||||
" ),\n",
|
||||
" QueryEngineTool.from_defaults(\n",
|
||||
" summary_index.as_query_engine(),\n",
|
||||
" name=\"query_all_docs\",\n",
|
||||
" description=\"Send a query that requires all documents to be considered\",\n",
|
||||
" ),\n",
|
||||
"]\n",
|
||||
"\n",
|
||||
"agent = FunctionAgent(\n",
|
||||
" tools=tools,\n",
|
||||
" llm=Settings.llm,\n",
|
||||
" system_prompt=\"You are a helpful assistant that can answer questions about the paper.\",\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.core.workflow import Context\n",
|
||||
"\n",
|
||||
"# Context to persist the agent session\n",
|
||||
"ctx = Context(agent)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Calling tool query_all_docs with args {'input': 'Provide the summary of the paper (concise abstract-like summary).'}\n",
|
||||
"Tool call query_all_docs({'input': 'Provide the summary of the paper (concise abstract-like summary).'}) returned This paper presents a practical recipe and empirical analysis for building high-performing multimodal large language models (MLLMs). Through systematic ablations of image encoders, vision–language connectors, and pre-training data mixtures, the work identifies key design lessons: image resolution and the number of image tokens drive the largest gains, followed by encoder capacity and pre-training data; architectural choices for the vision–language connector matter far less. Data-wise, a careful mixture of captioned images, interleaved image–text documents, and some text-only data is critical — caption data boosts zero-shot captioning, interleaved documents enable strong few-shot and text performance, and text-only data preserves language capabilities. The authors apply these lessons to scale MM1: ViT-H image encoders at high resolution feeding 144 visual tokens into decoder-only LLMs (dense and MoE variants) trained on a 45/45/10 mixture (interleaved/caption/text), for ~200k steps (~400B tokens). MM1 models (dense up to 30B, MoE up to effectively tens of billions of parameters) achieve state-of-the-art few-shot pre-training metrics and competitive supervised fine-tuning results across many established multimodal benchmarks, while exhibiting enhanced in-context learning, multi-image reasoning, and few-shot chain-of-thought capabilities. Practical training details (learning-rate scaling, unfreezing the encoder during SFT, high-resolution support via positional interpolation and sub-image decomposition) and the positive impact of synthetic caption data are reported to guide reproducing and extending these findings.\n",
|
||||
"\n",
|
||||
"================\n",
|
||||
"\n",
|
||||
"Here is a concise, abstract‑style summary of the paper:\n",
|
||||
"\n",
|
||||
"- Goal: provide a practical recipe and empirical analysis for building high‑performing multimodal LLMs (MLLMs) and identify which design choices matter most.\n",
|
||||
"- Key findings: image resolution and number of image tokens yield the largest performance gains, followed by vision‑encoder capacity and pretraining data; the specific architecture of the vision–language connector matters far less.\n",
|
||||
"- Data mix: a careful pretraining mixture is critical—captioned images boost zero‑shot captioning, interleaved image–text documents enable strong few‑shot and text performance, and some text‑only data preserves language capabilities. The authors use a 45/45/10 split (interleaved/caption/text).\n",
|
||||
"- MM1 models: applying these lessons, they scale ViT‑H encoders at high resolution producing 144 visual tokens into decoder‑only LLMs (dense up to 30B, MoE variants effectively larger), trained ~200k steps (~400B tokens).\n",
|
||||
"- Results: MM1 achieves state‑of‑the‑art few‑shot pretraining metrics and competitive supervised fine‑tuning across many multimodal benchmarks, with improved in‑context learning, multi‑image reasoning, and few‑shot chain‑of‑thought behavior.\n",
|
||||
"- Practical guidance: reportable tricks include learning‑rate scaling, unfreezing the encoder during SFT, supporting high resolution via positional interpolation and sub‑image decomposition, and the positive impact of synthetic caption data.\n",
|
||||
"\n",
|
||||
"Overall, the paper offers both empirical insights about what drives MLLM performance and a concrete, reproducible recipe (MM1) that attains strong multimodal capabilities.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from llama_index.core.agent import ToolCall, ToolCallResult\n",
|
||||
"\n",
|
||||
"handler = agent.run(\n",
|
||||
" \"What is the summary of the paper that you have access to?\", ctx=ctx\n",
|
||||
")\n",
|
||||
"async for ev in handler.stream_events():\n",
|
||||
" if isinstance(ev, ToolCall):\n",
|
||||
" print(f\"Calling tool {ev.tool_name} with args {ev.tool_kwargs}\")\n",
|
||||
" elif isinstance(ev, ToolCallResult):\n",
|
||||
" print(f\"Tool call {ev.tool_name}({ev.tool_kwargs}) returned {ev.tool_output}\")\n",
|
||||
"\n",
|
||||
"print(\"\\n================\\n\")\n",
|
||||
"\n",
|
||||
"resp = await handler\n",
|
||||
"print(resp)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Calling tool query_all_docs with args {'input': 'Describe in detail how the authors evaluate their work: which benchmarks and tasks they use (pretraining metrics, few-shot evaluation, supervised fine-tuning, multimodal benchmarks, in-context learning, chain-of-thought, multi-image reasoning), the metrics reported, baselines compared, and ablation studies conducted. Include mentions of training steps, model sizes, and any special evaluation setups (e.g., positional interpolation, sub-image decomposition, synthetic caption data).'}\n",
|
||||
"Tool call query_all_docs({'input': 'Describe in detail how the authors evaluate their work: which benchmarks and tasks they use (pretraining metrics, few-shot evaluation, supervised fine-tuning, multimodal benchmarks, in-context learning, chain-of-thought, multi-image reasoning), the metrics reported, baselines compared, and ablation studies conducted. Include mentions of training steps, model sizes, and any special evaluation setups (e.g., positional interpolation, sub-image decomposition, synthetic caption data).'}) returned Overview\n",
|
||||
"- Evaluation covers both pre-training (zero-/few-shot) and supervised fine-tuning (SFT) regimes, plus targeted analyses of in-context learning, multi-image reasoning, and chain-of-thought prompting. Evaluations include captioning, VQA, a set of text-only tasks (TextCore), and a wide collection of modern multimodal benchmarks. Results are reported for multiple model scales (dense 3B, 7B, 30B and MoE variants) and compared to several published baselines.\n",
|
||||
"\n",
|
||||
"Pre-training evaluation\n",
|
||||
"- Tasks and benchmarks:\n",
|
||||
" - Image captioning: COCO (Karpathy test), NoCaps (val), TextCaps (val). Captioning use standard caption prompts and reporting.\n",
|
||||
" - Visual question answering / text-in-image tasks: VQAv2 (testdev), TextVQA (val), VizWiz (testdev), GQA, OK-VQA (val).\n",
|
||||
" - A text-only evaluation suite called TextCore (ARC, PIQA, LAMBADA, WinoGrande, HellaSWAG, SciQ, TriviaQA, WebQS) to measure preservation/quality of language capabilities.\n",
|
||||
"- Prompting and generation:\n",
|
||||
" - Captioning prompt: \"{IMAGE} A photo of\" (or equivalent). VQA prompt: \"{IMAGE} Question: {QUESTION} Short answer:\".\n",
|
||||
" - Greedy decoding until EOS or task-specific stop tokens. For captioning the newline is a stop token; for VQA additional stop tokens include \".\", \",\", \"Question\".\n",
|
||||
" - VQA postprocessing follows the same logic used by OpenFlamingo implementations.\n",
|
||||
"- Metrics:\n",
|
||||
" - Captioning: CIDEr (computed via nlg-eval).\n",
|
||||
" - VQA and related QA tasks: task-appropriate accuracy metrics (reported as percentages).\n",
|
||||
" - TextCore: aggregated scores reported to indicate text-only capabilities.\n",
|
||||
" - Pre-training few-shot evaluation reported for 0-shot, 4-shot, and 8-shot settings (4- and 8-shot used as main few-shot points).\n",
|
||||
"- Splits and sampling:\n",
|
||||
" - Few-shot prompts are sampled from training when available, otherwise validation, ensuring the query example is not one of the shots.\n",
|
||||
"- Scale and settings for pre-training evaluation runs:\n",
|
||||
" - Most pre-training evaluations use smaller ablation setups: base ablation LLM = 1.2B (but some encoder ablations use a 2.9B LLM to ensure capacity).\n",
|
||||
" - Final pre-trained models evaluated at 3B, 7B, and 30B (dense) and MoE variants (3B backbone with 64 experts; 7B backbone with 32 experts).\n",
|
||||
"- Baselines for pre-training comparisons:\n",
|
||||
" - Flamingo (various sizes), Emu2 (14B, 37B), IDEFICS (9B, 80B), and other published pre-trained MLLMs where few-shot pre-training numbers are available.\n",
|
||||
"\n",
|
||||
"Supervised fine-tuning (SFT) evaluation\n",
|
||||
"- SFT data and setup:\n",
|
||||
" - SFT mixture contains ≈1.45M examples: GPT-4/GPT-4V-generated instruction-response data (e.g., LLaVA-Conv/Complex, ShareGPT-4V), many academic VL datasets (VQAv2, GQA, OKVQA, A-OKVQA, COCO Captions, OCRVQA, TextCaps, DVQA, ChartQA, AI2D, DocVQA, InfoVQA, SynthDog-En), and a small internal text-only SFT set.\n",
|
||||
" - Fine-tuning: 10k steps, batch size 256, sequence length 2048; optimizer AdaFactor with peak LR 1e-5 and cosine decay to 0. Both image encoder and LLM are unfrozen unless noted in ablations.\n",
|
||||
"- Benchmarks & aggregated evaluation:\n",
|
||||
" - A large set of 12+ multimodal benchmarks is used for SFT evaluation, including VQAv2, TextVQA, ScienceQA-IMG, MMMU, MathVista, MME (perception/cognition splits), MMBench, SEED-Bench, POPE, LLaVA-Bench-in-the-Wild, MM-Vet, etc.\n",
|
||||
" - Results reported per-dataset and combined into a meta-average for comparisons; the meta-average is normalized relative to a compact baseline to make metrics comparable across tasks.\n",
|
||||
"- Baselines and SFT comparisons:\n",
|
||||
" - Compared against a range of SOTA and contemporary multimodal models after instruction tuning: LLaVA variants (1.5/NeXT), InstructBLIP, Qwen-VL, Emu2-Chat, CogVLM, Gemini family, GPT4V where available, and others. Both dense and MoE variants are compared when available.\n",
|
||||
"- High-resolution and multi-image SFT evaluation:\n",
|
||||
" - Two techniques are used to support high-resolution inputs during SFT:\n",
|
||||
" - Positional embedding interpolation to adapt ViT positional embeddings to larger resolutions (used to support 448×448, 560×560, 672×672, etc.).\n",
|
||||
" - Sub-image decomposition (crop-based): for very high resolution (e.g., 1344×1344) the image is split into multiple sub-images (e.g., five 672×672 crops) that are encoded independently and concatenated as a sequence to the LLM.\n",
|
||||
" - Default SFT evaluation results reported at an effective high resolution (1344×1344) via these strategies. Reported improvement with higher resolution (e.g., relative gains up to ~15% average when supporting 1344×1344 vs 336×336).\n",
|
||||
"- Chain-of-thought & few-shot in-context evaluation after SFT:\n",
|
||||
" - MathVista is used to quantify few-shot chain-of-thought capability: example results show 0-shot 39.4, 4-shot 41.9, and an 8-shot mixed-resolution in-context setup achieves 44.4.\n",
|
||||
" - Mixed-resolution in-context strategy: to fit more examples in context while managing token cost of high-resolution sub-image decomposition, some in-context examples are encoded at lower resolution and only the last N examples use full high-resolution decomposition (N=3 in reported experiments).\n",
|
||||
"\n",
|
||||
"Ablation studies and analyses\n",
|
||||
"- Overall ablation design:\n",
|
||||
" - A compact base configuration is used for systematic ablations: ViT-L/14 image encoder (CLIP), C-Abstractor connector with 144 image tokens, pre-training mixture 45% captioned images / 45% interleaved image-text / 10% text-only, and a 1.2B decoder-only LLM for many ablations.\n",
|
||||
" - One component changed at a time; evaluations are zero-/few-shot across the same captioning and VQA benchmarks.\n",
|
||||
"- Image encoder ablations:\n",
|
||||
" - Compared contrastive (CLIP variants trained on DFN-5B, VeCap-300M, OpenAI CLIP) against reconstructive losses (AIM models).\n",
|
||||
" - Resolution ablations: 224 → 336 → 378 px; clear finding that image resolution has the largest impact, followed by encoder capacity and training data composition. Increasing resolution yielded ~3% absolute boost in many metrics.\n",
|
||||
" - Encoder size: ViT-L → ViT-H shows modest gains (typically <1% absolute).\n",
|
||||
" - Training data for encoders: inclusion of synthetic caption data (VeCap) yields non-trivial few-shot improvements.\n",
|
||||
" - Table-based reporting of 0-/4-/8-shot metrics for these variants.\n",
|
||||
"- Vision-language (VL) connector ablations:\n",
|
||||
" - Connector types: average pooling (grid pooling + linear), attention pooling (learnable queries), and C-Abstractor (convolutional mapping / ResNet-based projector).\n",
|
||||
" - Image token counts: experiments with 64 vs 144 image tokens per image.\n",
|
||||
" - Findings: number of visual tokens and image resolution matter most; the particular connector architecture has comparatively little effect on final performance. Detailed 0/4/8-shot tables compare pooling strategies across token counts and resolutions.\n",
|
||||
"- Pre-training data mixture ablations:\n",
|
||||
" - Systematically varied mixes of captioned image pairs vs interleaved image-text documents vs text-only data. Examples tested: 100% caption, mixtures such as 66/33, 50/50, and 0/100, and image/text-only ratios (e.g., 91/9, 86/14, 66/33).\n",
|
||||
" - Key lessons:\n",
|
||||
" - Interleaved documents are critical for few-shot and text-only performance; captioning data strongly lifts zero-shot captioning performance.\n",
|
||||
" - Text-only data helps preserve/boost few-shot and text-only performance; including ~9–14% text-only yields a better balance.\n",
|
||||
" - A final recommended pre-training mix is 45% interleaved / 45% image-caption / 10% text-only to balance zero- and few-shot capabilities.\n",
|
||||
" - Impact of synthetic VeCap captions: even though small (~7% of caption pool), VeCap gives measurable few-shot gains (e.g., 2.4% and 4% absolute in reported settings).\n",
|
||||
"- SFT-specific ablations:\n",
|
||||
" - Repeating data-mixture and connector ablations in the SFT context: caption-pretraining helps SFT zero-shot metrics; choice of VL connector still has limited effect though finer differences appear at high token counts; freezing vs unfreezing the image encoder matters (frozen better at lower resolution; unfrozen better for high-resolution SFT).\n",
|
||||
"- Hyperparameter and optimization ablations:\n",
|
||||
" - Learning-rate grid searches run at small scales (models 9M, 85M, 302M, 1.2B) and 50k-step probes, then a log-linear fit extrapolated to larger model sizes. Grid-search experiments used 50k training steps for each setting.\n",
|
||||
" - Resulting scaling rule and fitted formula for optimal peak learning rate as a function of LLM parameter count is provided and used to choose LRs for the 3B/7B/30B models (e.g., final LRs used: 6e-5 (3B), 4e-5 (7B), 2e-5 (30B)). Weight decay scaled as λ = 0.1 · η.\n",
|
||||
"- MoE (mixture-of-experts) experiments:\n",
|
||||
" - Two MoE designs: 3B-MoE with 64 experts (∼64B total params, top-2 gating, replace every-2 layers) and 7B-MoE with 32 experts (∼47B total params, replace every-4 layers).\n",
|
||||
" - Training used top-2 gating, load-balance loss coefficient 0.01, router z-loss 0.001, and otherwise the same hyperparameters and data mixture as the dense backbones. MoE variants show uniform improvements over dense counterparts on many SFT benchmarks.\n",
|
||||
"- Additional implementation/evaluation notes:\n",
|
||||
" - Pre-training: models trained unfrozen for 200k steps (≈400B tokens) with batch size 512 and sequence length 4096, allowing up to 16 images per sequence and 144 tokens per image (≈1M text tokens + 1M image tokens per batch in the final setup). The pre-training mixture is fixed deterministically for reproducibility.\n",
|
||||
" - Pre-training evaluation prompts, stop tokens, and postprocessing are standardized (greedy decoding), and detailed splits used for each benchmark are specified.\n",
|
||||
" - SFT evaluation meta-average: benchmarks are normalized to a compact baseline configuration prior to averaging so disparate metrics can be compared.\n",
|
||||
" - For high-resolution SFT, the positional interpolation approach (to support larger patches) and the sub-image decomposition scheme (to represent very large images as multiple crops) are both used and evaluated; sub-image decomposition increases the number of image tokens dramatically, which motivates mixed-resolution in-context examples for few-shot prompting.\n",
|
||||
"\n",
|
||||
"Reporting and comparisons\n",
|
||||
"- Tabular reporting:\n",
|
||||
" - Pre-training few-shot results are reported in detailed tables per model scale (3B, 7B, 30B) for 0/4/8/16-shot where applicable, across captioning and VQA datasets.\n",
|
||||
" - SFT comparisons show per-benchmark numbers and a combined meta-average; both dense and MoE model variants are included.\n",
|
||||
"- Baselines and contemporaries cited for direct comparison include Flamingo, IDEFICS, Emu2, LLaVA-NeXT, CogVLM, Gemini family, GPT4V, and many instruction-tuned MLLMs. Where appropriate, notes on differences in prompting setups (e.g., some baselines include text-only demonstrations in “0” prompts) are documented.\n",
|
||||
"- Qualitative analysis:\n",
|
||||
" - A variety of qualitative examples shown for counting, OCR, multi-image reasoning, style following, instruction following, and chain-of-thought reasoning; these accompany quantitative results to illustrate capabilities such as multi-image reasoning and few-shot chain-of-thought.\n",
|
||||
"\n",
|
||||
"Key reported evaluation figures (examples)\n",
|
||||
"- Pre-training duration: 200k steps (~400B tokens).\n",
|
||||
"- Pre-training batch & context: batch 512, sequence length 4096, up to 16 images per sequence, 144 tokens per image.\n",
|
||||
"- SFT: 10k steps; batch 256; seq length 2048; AdaFactor with peak LR 1e-5.\n",
|
||||
"- MoE variants: 3B backbone + 64 experts (∼64B total); 7B backbone + 32 experts (∼47B total); top-2 gating; load-balance and router regularizers used.\n",
|
||||
"- Example few-shot chain-of-thought: MathVista 0-shot 39.4 → 4-shot 41.9 → 8-shot with mixed-resolution 44.4.\n",
|
||||
"\n",
|
||||
"In summary\n",
|
||||
"- Evaluation is multi-faceted: systematic pre-training zero-/few-shot tests on captioning and VQA, text-only TextCore checks, extensive SFT across a broad benchmark suite, ablations covering image encoder, VL connector, data mixtures, training hyperparameters, and input-resolution strategies, plus experiments with MoE scaling. Metrics include CIDEr for captioning, accuracy for VQA and other benchmarks, TextCore aggregated scores, and a normalized meta-average for SFT. The authors report results across multiple model sizes and variants and compare to a broad set of recent multimodal models.\n",
|
||||
"\n",
|
||||
"================\n",
|
||||
"\n",
|
||||
"Short answer: the authors evaluate across (1) pre-training zero-/few-shot benchmarks (captioning, VQA, and a text-only suite), (2) supervised instruction fine‑tuning (SFT) on a large multimodal mixture with extensive downstream benchmarks, and (3) targeted analyses (in‑context/few‑shot learning, chain‑of‑thought, multi‑image reasoning). They report standard task metrics (CIDEr for captioning, accuracy for VQA/QA, aggregated TextCore scores, and a normalized SFT meta‑average), compare to many recent MLLMs, and run systematic ablations (encoder, connector, data mixtures, hyperparameters, resolution/tokenization, MoE). Key training/eval settings and special setups are also evaluated (positional interpolation, sub‑image decomposition, synthetic caption data). Details:\n",
|
||||
"\n",
|
||||
"1) Pre‑training evaluation\n",
|
||||
"- Tasks and datasets:\n",
|
||||
" - Image captioning: COCO (Karpathy test), NoCaps (val), TextCaps (val).\n",
|
||||
" - VQA/text‑in‑image: VQAv2 (testdev), TextVQA, VizWiz, GQA, OK‑VQA, etc.\n",
|
||||
" - TextCore: a text‑only suite (ARC, PIQA, LAMBADA, WinoGrande, HellaSWAG, SciQ, TriviaQA, WebQS) to check language preservation.\n",
|
||||
"- Prompting & decoding:\n",
|
||||
" - Zero/4/8 (and sometimes 16) shot prompts; few‑shot examples sampled from train/val ensuring no leakage.\n",
|
||||
" - Greedy decoding with task‑specific stop tokens; VQA postprocessing matches Flamingo style.\n",
|
||||
"- Metrics:\n",
|
||||
" - CIDEr for captioning, accuracy (%) for VQA/QA tasks, aggregated TextCore scores for language capability.\n",
|
||||
"- Model scales for evaluation:\n",
|
||||
" - Ablations often use a small base LLM (1.2B, sometimes 2.9B). Final pre‑trained models evaluated at 3B, 7B, 30B (dense) and MoE variants.\n",
|
||||
"- Baselines:\n",
|
||||
" - Compared against Flamingo, Emu2, IDEFICS, and other published pre‑trained MLLMs when few‑shot pretraining numbers are available.\n",
|
||||
"\n",
|
||||
"2) Supervised fine‑tuning (SFT) evaluation\n",
|
||||
"- SFT data:\n",
|
||||
" - ≈1.45M instruction examples: GPT‑4/GPT‑4V synthetic instruction data (LLaVA‑Conv/Complex, ShareGPT‑4V), many academic VL datasets (VQAv2, GQA, OKVQA, COCO Captions, TextCaps, OCRVQA, ChartQA, DocVQA, etc.), and a small internal text SFT set.\n",
|
||||
"- Fine‑tuning procedure:\n",
|
||||
" - 10k steps, batch 256, seq length 2048, AdaFactor optimizer, peak LR 1e‑5 with cosine decay. Image encoder and LLM unfrozen unless ablated.\n",
|
||||
"- Downstream benchmarks and reporting:\n",
|
||||
" - 12+ multimodal benchmarks for SFT evaluation (VQAv2, TextVQA, ScienceQA‑IMG, MMMU, MathVista, MME, MMBench, SEED‑Bench, POPE, LLaVA‑BiW, MM‑Vet, etc.). Results reported per dataset and combined into a normalized meta‑average for fair aggregation across heterogeneous metrics.\n",
|
||||
"- Baselines:\n",
|
||||
" - Compared to instruction‑tuned contemporaries: LLaVA/NeXT, InstructBLIP, Qwen‑VL, Emu2‑Chat, CogVLM, Gemini family, GPT4V where available.\n",
|
||||
"\n",
|
||||
"3) Targeted analyses (in‑context learning, CoT, multi‑image)\n",
|
||||
"- In‑context/few‑shot: standard 0/4/8‑shot probes across captioning and VQA.\n",
|
||||
"- Chain‑of‑thought: MathVista used to quantify few‑shot CoT; reported example: 0‑shot 39.4 → 4‑shot 41.9 → 8‑shot mixed‑resolution 44.4.\n",
|
||||
"- Multi‑image reasoning: evaluated qualitatively and quantitatively on multi‑image benchmarks and examples.\n",
|
||||
"\n",
|
||||
"4) Ablation studies (systematic and extensive)\n",
|
||||
"- Image encoder ablations:\n",
|
||||
" - Contrastive (CLIP variants) vs reconstructive (AIM); encoder size (ViT‑L → ViT‑H); encoder training data (including synthetic caption data VeCap).\n",
|
||||
" - Resolution ablations (e.g., 224 → 336 → 378 px): resolution and number of visual tokens give the largest gains.\n",
|
||||
"- Vision–language connector ablations:\n",
|
||||
" - Connector types (avg‑pooling, attention pooling, C‑Abstractor) and visual token counts (e.g., 64 vs 144). Finding: connector architecture matters far less than token count/resolution.\n",
|
||||
"- Pre‑training data mixture ablations:\n",
|
||||
" - Varied mixes of caption pairs / interleaved image–text documents / text‑only. Key finding: 45% interleaved / 45% caption / 10% text gives the best balance (interleaved documents help few‑shot/text performance; captions boost zero‑shot captioning; text-only preserves language capabilities).\n",
|
||||
" - Small synthetic caption pool (VeCap) provides measurable few‑shot gains.\n",
|
||||
"- SFT ablations:\n",
|
||||
" - Freezing vs unfreezing image encoder in SFT (unfreeze better for high‑resolution), data‑mix effects in SFT, connector behavior at high token counts.\n",
|
||||
"- Hyperparameter & optimizer ablations:\n",
|
||||
" - LR grid searches at small scales (9M → 1.2B) with 50k‑step probes and a fitted scaling rule; final LRs chosen (e.g., ~6e‑5 for 3B, 4e‑5 for 7B, 2e‑5 for 30B for pretraining). Weight decay scaled proportionally.\n",
|
||||
"- MoE experiments:\n",
|
||||
" - Two MoE setups: 3B backbone + 64 experts (~64B params) and 7B + 32 experts (~47B params), top‑2 gating, load‑balance/reg losses; MoE variants yield uniform improvements on many SFT benchmarks.\n",
|
||||
"\n",
|
||||
"5) Special evaluation/training setups and numbers\n",
|
||||
"- Pretraining infrastructure & settings:\n",
|
||||
" - Pretraining: ≈200k steps (~400B tokens), batch 512, seq length 4096, allow up to 16 images per sequence, 144 tokens per image in final setup. Pretraining mixture fixed deterministically.\n",
|
||||
"- High‑resolution support:\n",
|
||||
" - Positional embedding interpolation to adapt ViT positional embeddings to larger resolutions.\n",
|
||||
" - Sub‑image decomposition (split very large images into multiple crops, encode independently, and concatenate visual tokens) to support extremely high effective resolution (e.g., 1344×1344 as five 672×672 crops).\n",
|
||||
" - Mixed‑resolution in‑context strategy to keep context capacity reasonable while enabling high‑resolution targets in the last few shots.\n",
|
||||
"- Decoding/postprocessing:\n",
|
||||
" - Greedy decoding; task‑specific stops; standardized postprocessing to align with prior work.\n",
|
||||
"- Reporting conventions:\n",
|
||||
" - 0/4/8‑shot pretraining tables, SFT per‑dataset numbers and a normalized meta‑average, and qualitative examples (counting, OCR, style following, multi‑image reasoning, CoT).\n",
|
||||
"\n",
|
||||
"6) Qualitative analysis\n",
|
||||
"- Numerous qualitative examples illustrating multi‑image reasoning, counting, OCR, instruction following, and chain‑of‑thought behaviors accompany the quantitative results.\n",
|
||||
"\n",
|
||||
"In short: the evaluation is broad (pretraining few‑shot, SFT, targeted capability probes), quantitatively rigorous (CIDEr/accuracy/meta‑averages), compares to many contemporary MLLMs, and is supported by wide ablations (encoder, connector, data, optimization, resolution, MoE) and practical high‑resolution evaluation techniques (positional interpolation, sub‑image decomposition, mixed‑resolution in‑context).\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"handler = agent.run(\"How do the authors evaluate their work?\", ctx=ctx)\n",
|
||||
"async for ev in handler.stream_events():\n",
|
||||
" if isinstance(ev, ToolCall):\n",
|
||||
" print(f\"Calling tool {ev.tool_name} with args {ev.tool_kwargs}\")\n",
|
||||
" elif isinstance(ev, ToolCallResult):\n",
|
||||
" print(f\"Tool call {ev.tool_name}({ev.tool_kwargs}) returned {ev.tool_output}\")\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"print(\"\\n================\\n\")\n",
|
||||
"\n",
|
||||
"resp = await handler\n",
|
||||
"print(resp)"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": ".venv",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2
|
||||
}
|
||||
@@ -0,0 +1,270 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "c148b65e-e8a6-476e-86ba-bf6a73d479c7",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# RAG over the Caltrain Weekend Schedule \n",
|
||||
"\n",
|
||||
"<a href=\"https://colab.research.google.com/github/run-llama/llama_cloud_services/blob/main/examples/parse/caltrain/caltrain_text_mode.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>\n",
|
||||
"\n",
|
||||
"This example shows off LlamaParse parsing capabilities to build a functioning query pipeline over the Caltrain weekend schedule, a big timetable containing all trains northbound and southbound and their stops in various cities.\n",
|
||||
"\n",
|
||||
"Status:\n",
|
||||
"| Last Executed | Version | State |\n",
|
||||
"|---------------|---------|------------|\n",
|
||||
"| Aug-19-2025 | 0.6.61 | Maintained |"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "ef115dbe-b834-4639-828e-e2c11aef710b",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Setup\n",
|
||||
"\n",
|
||||
"Download the data."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "335ce1d0-757a-4f09-846e-21c409768871",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!wget \"https://www.caltrain.com/media/31602/download?inline?inline\" -O caltrain_schedule_weekend.pdf"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "45fa9120-65bb-4772-9db7-53e7cecf9adc",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Initialize LlamaParse\n",
|
||||
"\n",
|
||||
"Parse the text results from `LlamaParse`, which will represent complex documents incl. text, tables, and figures as nicely formatted text."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "54aa9579-84d4-49bc-ab54-5474e69c1188",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Started parsing the file under job_id d162724f-dcb9-4bfe-9bd4-337244906fb8\n",
|
||||
".."
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from llama_cloud_services import LlamaParse\n",
|
||||
"\n",
|
||||
"result = await LlamaParse(\n",
|
||||
" parse_mode=\"parse_page_with_agent\",\n",
|
||||
" model=\"openai-gpt-4-1-mini\",\n",
|
||||
" high_res_ocr=True,\n",
|
||||
" adaptive_long_table=True,\n",
|
||||
" outlined_table_extraction=True,\n",
|
||||
" output_tables_as_HTML=True,\n",
|
||||
" api_key=\"llx-...\",\n",
|
||||
").aparse(\"./caltrain_schedule_weekend.pdf\")\n",
|
||||
"\n",
|
||||
"documents = result.get_text_documents(split_by_page=True)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "602756b2-9ea1-4519-a8e3-c773ec624205",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Take a look at the below text (and zoom out from the browser to really get the effect!). You'll see that the entire table is nicely laid out."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "4928281a-591a-4653-b451-b2b8112a7101",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
" Printer Friendly WEEKEND Caltrain Schedule\n",
|
||||
" Morning to Early Afternoon Page 1 of 2\n",
|
||||
" Northbound – WEEKEND SERVICE to SAN FRANCISCO 6XX Local\n",
|
||||
" Train No. 601 603 605 607 609 611 613 615 617 619 621 623 625 627 629 631\n",
|
||||
" Tamien 6:51a 7:51a 8:51a 9:51a 10:51a 11:51a 12:51p 1:51p\n",
|
||||
" San Jose Diridon 6:56a 7:26a 7:56a 8:26a 8:56a 9:26a 9:56a 10:26a 10:56a 11:26a 11:56a 12:26p 12:56p 1:26p 1:56p 2:26p\n",
|
||||
" Santa Clara 7:03a 7:33a 8:03a 8:33a 9:03a 9:33a 10:03a 10:33a 11:03a 11:33a 12:03p 12:33p 1:03p 1:33p 2:03p 2:33p\n",
|
||||
"ZONE 4 Lawrence 7:08a 7:38a 8:08a 8:38a 9:08a 9:38a 10:08a 10:38a 11:08a 11:38a 12:08p 12:38p 1:08p 1:38p 2:08p 2:38p\n",
|
||||
"\n",
|
||||
" Sunnyvale 7:12a 7:42a 8:12a 8:42a 9:12a 9:42a 10:12a 10:42a 11:12a 11:42a 12:12p 12:42p 1:12p 1:42p 2:12p 2:42p\n",
|
||||
" Mountain View 7:16a 7:46a 8:16a 8:46a 9:16a 9:46a 10:16a 10:46a 11:16a 11:46a 12:16p 12:46p 1:16p 1:46p 2:16p 2:46p\n",
|
||||
" San Antonio 7:19a 7:49a 8:19a 8:49a 9:19a 9:49a 10:19a 10:49a 11:19a 11:49a 12:19p 12:49p 1:19p 1:49p 2:19p 2:49p\n",
|
||||
" California Ave 7:22a 7:52a 8:22a 8:52a 9:22a 9:52a 10:22a 10:52a 11:22a 11:52a 12:22p 12:52p 1:22p 1:52p 2:22p 2:52p\n",
|
||||
" Palo Alto 7:25a 7:55a 8:25a 8:55a 9:25a 9:55a 10:25a 10:55a 11:25a 11:55a 12:25p 12:55p 1:25p 1:55p 2:25p 2:55p\n",
|
||||
"ZONE 3 Menlo Park 7:27a 7:57a 8:27a 8:57a 9:27a 9:57a 10:27a 10:57a 11:27a 11:57a 12:27p 12:57p 1:27p 1:57p 2:27p 2:57p\n",
|
||||
"\n",
|
||||
" Redwood City 7:32a 8:02a 8:32a 9:02a 9:32a 10:02a 10:32a 11:02a 11:32a 12:02p 12:32p 1:02p 1:32p 2:02p 2:32p 3:02p\n",
|
||||
" San Carlos 7:35a 8:05a 8:35a 9:05a 9:35a 10:05a 10:35a 11:05a 11:35a 12:05p 12:35p 1:05p 1:35p 2:05p 2:35p 3:05p\n",
|
||||
" Belmont 7:38a 8:08a 8:38a 9:08a 9:38a 10:08a 10:38a 11:08a 11:38a 12:08p 12:38p 1:08p 1:38p 2:08p 2:38p 3:08p\n",
|
||||
" Hillsdale 7:41a 8:11a 8:41a 9:11a 9:41a 10:11a 10:41a 11:11a 11:41a 12:11p 12:41p 1:11p 1:41p 2:11p 2:41p 3:11p\n",
|
||||
" Hayward Park 7:43a 8:13a 8:43a 9:13a 9:43a 10:13a 10:43a 11:13a 11:43a 12:13p 12:43p 1:13p 1:43p 2:13p 2:43p 3:13p\n",
|
||||
" San Mateo 7:46a 8:16a 8:46a 9:16a 9:46a 10:16a 10:46a 11:16a 11:46a 12:16p 12:46p 1:16p 1:46p 2:16p 2:46p 3:16p\n",
|
||||
" Burlingame 7:48a 8:18a 8:48a 9:18a 9:48a 10:18a 10:48a 11:18a 11:48a 12:18p 12:48p 1:18p 1:48p 2:18p 2:48p 3:18p\n",
|
||||
" Broadway 7:51a 8:21a 8:51a 9:21a 9:51a 10:21a 10:51a 11:21a 11:51a 12:21p 12:51p 1:21p 1:51p 2:21p 2:51p 3:21p\n",
|
||||
"ZONE 2 Millbrae 7:54a 8:24a 8:54a 9:24a 9:54a 10:24a 10:54a 11:24a 11:54a 12:24p 12:54p 1:24p 1:54p 2:24p 2:54p 3:24p\n",
|
||||
"\n",
|
||||
" San Bruno 7:57a 8:27a 8:57a 9:27a 9:57a 10:27a 10:57a 11:27a 11:57a 12:27p 12:57p 1:27p 1:57p 2:27p 2:57p 3:27p\n",
|
||||
" S. San Francisco 8:00a 8:30a 9:00a 9:30a 10:00a 10:30a 11:00a 11:30a 12:00p 12:30p 1:00p 1:30p 2:00p 2:30p 3:00p 3:30p\n",
|
||||
" Bayshore 8:05a 8:35a 9:05a 9:35a 10:05a 10:35a 11:05a 11:35a 12:05p 12:35p 1:05p 1:35p 2:05p 2:35p 3:05p 3:35p\n",
|
||||
" 22ⁿᵈ Street 8:10a 8:40a 9:10a 9:40a 10:10a 10:40a 11:10a 11:40a 12:10p 12:40p 1:10p 1:40p 2:10p 2:40p 3:10p 3:40p\n",
|
||||
"ZONE 1 San Francisco 8:15a 8:45a 9:15a 9:45a 10:15a 10:45a 11:15a 11:45a 12:15p 12:45p 1:15p 1:45p 2:15p 2:45p 3:15p 3:45p\n",
|
||||
"\n",
|
||||
"EFFECTIVE September 21, 2024 Timetable subject to change without notice See Page 2 For Afternoon and Evening Times\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(documents[0].text)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "8f5064d4-3e33-4f67-9b2e-46787161538f",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Initialize Query Engine\n",
|
||||
"\n",
|
||||
"We now initialize a query engine over this data. Here we use a baseline summary index, which doesn't do vector indexing/chunking and instead dumps the entire text into the prompt."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "b3e985b6-9d38-449f-9cf9-aae166824eed",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.core import SummaryIndex\n",
|
||||
"from llama_index.llms.openai import OpenAI\n",
|
||||
"\n",
|
||||
"llm = OpenAI(model=\"gpt-5-mini\", api_key=\"sk-...\")\n",
|
||||
"index = SummaryIndex.from_documents(documents)\n",
|
||||
"query_engine = index.as_query_engine(llm=llm)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "66eb0976-2cd6-4b14-9083-124baae9ed5d",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"response = query_engine.query(\n",
|
||||
" \"What are the stops (and times) for train no 609 northbound?\"\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "7dc6f275-07f4-429e-9335-f50982fe974c",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Train No. 609 northbound (stops and times):\n",
|
||||
"\n",
|
||||
"- Tamien — 8:51a\n",
|
||||
"- San Jose Diridon — 8:56a\n",
|
||||
"- Santa Clara — 9:03a\n",
|
||||
"- Lawrence — 9:08a\n",
|
||||
"- Sunnyvale — 9:12a\n",
|
||||
"- Mountain View — 9:16a\n",
|
||||
"- San Antonio — 9:19a\n",
|
||||
"- California Ave — 9:22a\n",
|
||||
"- Palo Alto — 9:25a\n",
|
||||
"- Menlo Park — 9:27a\n",
|
||||
"- Redwood City — 9:32a\n",
|
||||
"- San Carlos — 9:35a\n",
|
||||
"- Belmont — 9:38a\n",
|
||||
"- Hillsdale — 9:41a\n",
|
||||
"- Hayward Park — 9:43a\n",
|
||||
"- San Mateo — 9:46a\n",
|
||||
"- Burlingame — 9:48a\n",
|
||||
"- Broadway — 9:51a\n",
|
||||
"- Millbrae — 9:54a\n",
|
||||
"- San Bruno — 9:57a\n",
|
||||
"- S. San Francisco — 10:00a\n",
|
||||
"- Bayshore — 10:05a\n",
|
||||
"- 22nd Street — 10:10a\n",
|
||||
"- San Francisco — 10:15a\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(str(response))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "229c4cb0-cf94-4a9f-bc7c-590388f50c1f",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"response = query_engine.query(\n",
|
||||
" \"What are all the trains (and times) that end at Redwood City going Southbound?\"\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "51cf03ff-7728-4815-ab72-3bf54fc4a2c0",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"None. On this weekend schedule no southbound trains terminate at Redwood City — every listed southbound train continues beyond Redwood City to later stations (Menlo Park/Palo Alto and onward).\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(str(response))"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": ".venv",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
@@ -0,0 +1,763 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Advanced RAG with LlamaParse\n",
|
||||
"\n",
|
||||
"<a href=\"https://colab.research.google.com/github/run-llama/llama_parse/blob/main/examples/demo_advanced.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>\n",
|
||||
"\n",
|
||||
"This notebook is a complete walkthrough for using LlamaParse with advanced indexing/retrieval techniques in LlamaIndex over the Apple 10K Filing. \n",
|
||||
"\n",
|
||||
"This allows us to ask sophisticated questions that aren't possible with \"naive\" parsing/indexing techniques with existing models.\n",
|
||||
"\n",
|
||||
"Status:\n",
|
||||
"| Last Executed | Version | State |\n",
|
||||
"|---------------|---------|------------|\n",
|
||||
"| Aug-18-2025 | 0.6.61 | Maintained |"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%pip install llama-cloud-services \"llama-index>=0.13.2<0.14.0\" \"llama-index-embeddings-huggingface>=0.6.0<0.7.0\" torchvision \"sentence-transformers<5.0\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!wget \"https://s2.q4cdn.com/470004039/files/doc_financials/2021/q4/_10-K-2021-(As-Filed).pdf\" -O apple_2021_10k.pdf"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Some OpenAI and LlamaParse details"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"\n",
|
||||
"# API access to llama-cloud\n",
|
||||
"os.environ[\"LLAMA_CLOUD_API_KEY\"] = \"llx-...\"\n",
|
||||
"\n",
|
||||
"# Using OpenAI API for embeddings/llms\n",
|
||||
"os.environ[\"OPENAI_API_KEY\"] = \"sk-...\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.llms.openai import OpenAI\n",
|
||||
"from llama_index.embeddings.openai import OpenAIEmbedding\n",
|
||||
"from llama_index.core import Settings\n",
|
||||
"\n",
|
||||
"embed_model = OpenAIEmbedding(model_name=\"text-embedding-3-small\")\n",
|
||||
"llm = OpenAI(model=\"gpt-5-mini\")\n",
|
||||
"\n",
|
||||
"Settings.llm = llm\n",
|
||||
"Settings.embed_model = embed_model"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Using brand new `LlamaParse` PDF reader for PDF Parsing\n",
|
||||
"\n",
|
||||
"We also compare three different retrieval/query engine strategies:\n",
|
||||
"1. Baseline using default parsing from `SimpleDirectoryReader`\n",
|
||||
"2. Using raw markdown text as nodes for building index and apply simple query engine for generating the results;\n",
|
||||
"3. Using markdown + page screenshots to help retrieve the proper nodes."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Started parsing the file under job_id f347cb97-dfe2-4677-991a-5ceba6d9fc6a\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from llama_cloud_services import LlamaParse\n",
|
||||
"\n",
|
||||
"result = await LlamaParse(\n",
|
||||
" # The parsing mode\n",
|
||||
" parse_mode=\"parse_page_with_agent\",\n",
|
||||
" # The model to use\n",
|
||||
" model=\"openai-gpt-4-1-mini\",\n",
|
||||
" # Whether to use high resolution OCR (Slower)\n",
|
||||
" high_res_ocr=True,\n",
|
||||
" # Adaptive long table. LlamaParse will try to detect long tables across pages\n",
|
||||
" adaptive_long_table=True,\n",
|
||||
" outlined_table_extraction=True,\n",
|
||||
" output_tables_as_HTML=True,\n",
|
||||
" # Whether to take a screenshot of the page, needed for screenshot-retrieval\n",
|
||||
" take_screenshot=True,\n",
|
||||
").aparse(\"./apple_2021_10k.pdf\")\n",
|
||||
"\n",
|
||||
"markdown_nodes = await result.aget_markdown_nodes(split_by_page=True)\n",
|
||||
"screenshot_image_nodes = await result.aget_image_nodes(\n",
|
||||
" include_screenshot_images=True,\n",
|
||||
" include_object_images=False,\n",
|
||||
" image_download_dir=\"./images\",\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.core import SimpleDirectoryReader\n",
|
||||
"\n",
|
||||
"baseline_documents = SimpleDirectoryReader(\n",
|
||||
" input_files=[\"apple_2021_10k.pdf\"]\n",
|
||||
").load_data()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Setup Baseline Index\n",
|
||||
"\n",
|
||||
"For comparison, we setup a naive RAG pipeline with default parsing and standard chunking, indexing, retrieval."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"2025-08-18 20:53:51,246 - INFO - HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
|
||||
"2025-08-18 20:53:52,143 - INFO - HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from llama_index.core import VectorStoreIndex\n",
|
||||
"\n",
|
||||
"baseline_index = VectorStoreIndex.from_documents(baseline_documents)\n",
|
||||
"baseline_query_engine = baseline_index.as_query_engine(similarity_top_k=3)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Setup our LlamaParse Indexes\n",
|
||||
"\n",
|
||||
"Using both the markdown and screenshot images, we can build two different indexes.\n",
|
||||
"\n",
|
||||
"1. An index over just the markdown documents\n",
|
||||
"2. A custom index that uses the markdown + screenshot images to help with response quality."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"2025-08-18 20:53:53,070 - INFO - HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from llama_index.core import VectorStoreIndex\n",
|
||||
"\n",
|
||||
"markdown_index = VectorStoreIndex(nodes=markdown_nodes)\n",
|
||||
"markdown_query_engine = markdown_index.as_query_engine(similarity_top_k=3)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"/Users/loganmarkewich/llama_parse/py/.venv/lib/python3.12/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n",
|
||||
" from .autonotebook import tqdm as notebook_tqdm\n",
|
||||
"2025-08-18 20:53:55,230 - INFO - Load pretrained SentenceTransformer: llamaindex/vdr-2b-multi-v1\n",
|
||||
"Using a slow image processor as `use_fast` is unset and a slow processor was saved with this model. `use_fast=True` will be the default behavior in v4.52, even if the model was saved with a slow processor. This will result in minor differences in outputs. You'll still be able to use a slow processor with `use_fast=False`.\n",
|
||||
"2025-08-18 20:54:05,369 - INFO - 2 prompts are loaded, with the keys: ['query', 'text']\n",
|
||||
"Generating embeddings: 0%| | 0/82 [00:00<?, ?it/s]2025-08-18 20:54:06,599 - INFO - HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
|
||||
"Generating embeddings: 100%|██████████| 82/82 [00:01<00:00, 61.24it/s]\n",
|
||||
"Generating image embeddings: 100%|██████████| 82/82 [26:06<00:00, 19.11s/it]\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from llama_index.core.indices import MultiModalVectorStoreIndex\n",
|
||||
"from llama_index.embeddings.huggingface import HuggingFaceEmbedding\n",
|
||||
"from llama_index.core import Settings\n",
|
||||
"\n",
|
||||
"# could also use other API-based multimodal models like voyageai or jinaai\n",
|
||||
"# Note: this may take quite a while if running on CPU!\n",
|
||||
"image_embed_model = HuggingFaceEmbedding(\n",
|
||||
" model_name=\"llamaindex/vdr-2b-multi-v1\",\n",
|
||||
" embed_batch_size=2,\n",
|
||||
" trust_remote_code=True,\n",
|
||||
" cache_folder=\"./hf_cache\",\n",
|
||||
" device=\"cpu\", # set to \"cuda\" if you have a GPU or remove to auto-detect\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"multi_modal_index = MultiModalVectorStoreIndex(\n",
|
||||
" nodes=[*markdown_nodes, *screenshot_image_nodes],\n",
|
||||
" embed_model=Settings.embed_model,\n",
|
||||
" image_embed_model=image_embed_model,\n",
|
||||
" show_progress=True,\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Below, we will create a custom query engine that does a few things\n",
|
||||
"1. Retrieves both image nodes and text nodes\n",
|
||||
"2. Combines them into two lists -- one where images and texts come from the same page, and one where we have texts alone\n",
|
||||
"3. Use a Jinja-based `RichPromptTemplate` to format the retrieved content automatically into a list of multimodal chat messages\n",
|
||||
"4. Send our messages to the LLM and return a result\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.core.async_utils import asyncio_run\n",
|
||||
"from llama_index.core.llms import LLM\n",
|
||||
"from llama_index.core.query_engine import CustomQueryEngine\n",
|
||||
"from llama_index.core.prompts import RichPromptTemplate\n",
|
||||
"from llama_index.core.response import Response\n",
|
||||
"from llama_index.core.schema import NodeWithScore\n",
|
||||
"from llama_index.core import Settings\n",
|
||||
"\n",
|
||||
"TEXT_IMAGE_PROMPT_TEMPLATE = RichPromptTemplate(\n",
|
||||
" \"\"\"\n",
|
||||
"<context>\n",
|
||||
"Here is some retrieved content from a knowledge base:\n",
|
||||
"{% for image_path, text in images_and_texts %}\n",
|
||||
"<page>\n",
|
||||
"<text>{{ text }}</text>\n",
|
||||
"<image>{{ image_path | image }}</image>\n",
|
||||
"</page>\n",
|
||||
"{% endfor %}\n",
|
||||
"{% for text in texts %}\n",
|
||||
"<page>\n",
|
||||
"<text>{{ text }}</text>\n",
|
||||
"</page>\n",
|
||||
"{% endfor %}\n",
|
||||
"</context>\n",
|
||||
"\n",
|
||||
"Using the context, answer the following question:\n",
|
||||
"<query>{{ query_str }}</query>\n",
|
||||
"\"\"\"\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"class SimpleMultiModalQueryEngine(CustomQueryEngine):\n",
|
||||
" def __init__(\n",
|
||||
" self,\n",
|
||||
" index: MultiModalVectorStoreIndex,\n",
|
||||
" image_top_k: int = 4,\n",
|
||||
" text_top_k: int = 4,\n",
|
||||
" llm: LLM | None = None,\n",
|
||||
" **kwargs\n",
|
||||
" ):\n",
|
||||
" super().__init__(**kwargs)\n",
|
||||
" self._retriever = index.as_retriever(\n",
|
||||
" similarity_top_k=text_top_k, image_similarity_top_k=image_top_k\n",
|
||||
" )\n",
|
||||
" self._llm = llm or Settings.llm\n",
|
||||
"\n",
|
||||
" def _match_images_and_texts(\n",
|
||||
" self, text_results: list[NodeWithScore], image_results: list[NodeWithScore]\n",
|
||||
" ) -> tuple[list[NodeWithScore], list[NodeWithScore]]:\n",
|
||||
" # combine results, prioritize images and texts\n",
|
||||
" # if both an image and matching text was retrieved, that is a strong indicator\n",
|
||||
" images_and_texts = []\n",
|
||||
" text_keys = {\n",
|
||||
" (x.metadata[\"page_number\"], x.metadata[\"file_name\"]): x\n",
|
||||
" for x in text_results\n",
|
||||
" }\n",
|
||||
" for image_result in image_results:\n",
|
||||
" key = (\n",
|
||||
" image_result.metadata[\"page_number\"],\n",
|
||||
" image_result.metadata[\"file_name\"],\n",
|
||||
" )\n",
|
||||
" # add matching text to results if available\n",
|
||||
" if key in text_keys:\n",
|
||||
" text_result = text_keys[key]\n",
|
||||
" images_and_texts.append(\n",
|
||||
" (image_result.node.image_path, text_result.node.text)\n",
|
||||
" )\n",
|
||||
"\n",
|
||||
" # remove from list\n",
|
||||
" text_keys.pop(key)\n",
|
||||
"\n",
|
||||
" # get the remaining texts as a fallback\n",
|
||||
" texts = [result.node.text for result in text_keys.values()]\n",
|
||||
"\n",
|
||||
" return images_and_texts, texts\n",
|
||||
"\n",
|
||||
" def custom_query(self, query_str: str) -> Response:\n",
|
||||
" # wrap the async method to avoid code duplication\n",
|
||||
" # asyncio_run is a slightly safer asyncio.run() call\n",
|
||||
" return asyncio_run(self.acustom_query(query_str))\n",
|
||||
"\n",
|
||||
" async def acustom_query(self, query_str: str) -> Response:\n",
|
||||
" text_results = await self._retriever.atext_retrieve(query_str)\n",
|
||||
" image_results = await self._retriever.atext_to_image_retrieve(query_str)\n",
|
||||
"\n",
|
||||
" images_and_texts, texts = self._match_images_and_texts(\n",
|
||||
" text_results, image_results\n",
|
||||
" )\n",
|
||||
" messages = TEXT_IMAGE_PROMPT_TEMPLATE.format_messages(\n",
|
||||
" images_and_texts=images_and_texts, texts=texts, query_str=str(query_str)\n",
|
||||
" )\n",
|
||||
"\n",
|
||||
" response = await self._llm.achat(messages)\n",
|
||||
"\n",
|
||||
" return Response(\n",
|
||||
" response.message.content, source_nodes=[*text_results, *image_results]\n",
|
||||
" )"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"multimodal_query_engine = SimpleMultiModalQueryEngine(\n",
|
||||
" index=multi_modal_index,\n",
|
||||
" image_top_k=3,\n",
|
||||
" text_top_k=3,\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Try out the Query Engines and Compare!\n",
|
||||
"\n",
|
||||
"Now with our three query engines assembled, we can compare each approach with a rough \"vibes-based\" evaluation."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"2025-08-18 21:20:29,006 - INFO - HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
|
||||
"2025-08-18 21:20:38,721 - INFO - HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\n",
|
||||
"***********Baseline Query Engine***********\n",
|
||||
"The total fair value of marketable securities in 2020 was $153,814 million (approximately $153.8 billion).\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"2025-08-18 21:20:39,233 - INFO - HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
|
||||
"2025-08-18 21:20:48,185 - INFO - HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\n",
|
||||
"***********Markdown Query Engine***********\n",
|
||||
"The total fair value was $191,830 million (approximately $191.83 billion).\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"2025-08-18 21:20:48,515 - INFO - HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
|
||||
"2025-08-18 21:21:09,275 - INFO - HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\n",
|
||||
"***********MultiModal Query Engine***********\n",
|
||||
"The table shows:\n",
|
||||
"\n",
|
||||
"- Total fair value (cash, cash equivalents and marketable securities) in 2020: $191,830 million (≈ $191.83 billion). \n",
|
||||
"- Total marketable securities (current + non‑current) in 2020: $52,927 + $100,887 = $153,814 million (≈ $153.81 billion).\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"query = \"What were the total fair value of marketable securities in 2020\"\n",
|
||||
"\n",
|
||||
"response_1 = await baseline_query_engine.aquery(query)\n",
|
||||
"print(\"\\n***********Baseline Query Engine***********\")\n",
|
||||
"print(response_1)\n",
|
||||
"\n",
|
||||
"response_2 = await markdown_query_engine.aquery(query)\n",
|
||||
"print(\"\\n***********Markdown Query Engine***********\")\n",
|
||||
"print(response_2)\n",
|
||||
"\n",
|
||||
"response_3 = await multimodal_query_engine.aquery(query)\n",
|
||||
"print(\"\\n***********MultiModal Query Engine***********\")\n",
|
||||
"print(response_3)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"As we can see, the multimodal and markdown query engines are able to retrieve the correct content, while the default query engine struggles to find the correct total value."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"We can also inspect the source nodes, and see the pages that were retrieved. Here is the correct page for the total fair value of marketable securities in 2020:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"'images/page_42.jpg'"
|
||||
]
|
||||
},
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"response_3.source_nodes[4].node.image_path"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Lets try a few more queries to see how the query engines perform."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"2025-08-18 21:35:33,281 - INFO - HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
|
||||
"2025-08-18 21:35:40,959 - INFO - HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\n",
|
||||
"***********Baseline Query Engine***********\n",
|
||||
"- Second quarter 2021 fixed-rate notes (2026–2061): effective interest rates 0.75%–2.81%\n",
|
||||
"- Fourth quarter 2021 fixed-rate notes (2028–2061): effective interest rates 1.43%–2.86%\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"2025-08-18 21:35:41,285 - INFO - HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
|
||||
"2025-08-18 21:35:49,132 - INFO - HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\n",
|
||||
"***********Markdown Query Engine***********\n",
|
||||
"- Floating-rate notes (2022): 0.48% – 0.63%\n",
|
||||
"- Fixed-rate 0.000% – 4.650% notes (2022 – 2060): 0.03% – 4.78%\n",
|
||||
"- Second-quarter 2021 fixed-rate notes (0.700% – 2.800%, 2026 – 2061): 0.75% – 2.81%\n",
|
||||
"- Fourth-quarter 2021 fixed-rate notes (1.400% – 2.850%, 2028 – 2061): 1.43% – 2.86%\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"2025-08-18 21:35:49,411 - INFO - HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
|
||||
"2025-08-18 21:36:06,767 - INFO - HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\n",
|
||||
"***********MultiModal Query Engine***********\n",
|
||||
"The effective interest rate ranges reported for the 2021 debt issuances were:\n",
|
||||
"\n",
|
||||
"- Floating‑rate notes (2022): 0.48% – 0.63% \n",
|
||||
"- Fixed‑rate 0.000% – 4.650% notes (2022–2060): 0.03% – 4.78% \n",
|
||||
"- Q2 2021 fixed‑rate notes (0.700% – 2.800%, maturities 2026–2061): 0.75% – 2.81% \n",
|
||||
"- Q4 2021 fixed‑rate notes (1.400% – 2.850%, maturities 2028–2061): 1.43% – 2.86%\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"query = \"What were the effective interest rates of all debt issuances in 2021\"\n",
|
||||
"\n",
|
||||
"response_1 = await baseline_query_engine.aquery(query)\n",
|
||||
"print(\"\\n***********Baseline Query Engine***********\")\n",
|
||||
"print(response_1)\n",
|
||||
"\n",
|
||||
"response_2 = await markdown_query_engine.aquery(query)\n",
|
||||
"print(\"\\n***********Markdown Query Engine***********\")\n",
|
||||
"print(response_2)\n",
|
||||
"\n",
|
||||
"response_3 = await multimodal_query_engine.aquery(query)\n",
|
||||
"print(\"\\n***********MultiModal Query Engine***********\")\n",
|
||||
"print(response_3)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\n",
|
||||
"***********Baseline Query Engine***********\n",
|
||||
"The federal deferred tax amounts for the years 2019 to 2021 are as follows (in millions):\n",
|
||||
"\n",
|
||||
"- **2019**: $(2,939)\n",
|
||||
"- **2020**: $(3,619)\n",
|
||||
"- **2021**: $(7,176)\n",
|
||||
"\n",
|
||||
"These figures represent the deferred tax expense for each respective year.\n",
|
||||
"\n",
|
||||
"***********Markdown Query Engine***********\n",
|
||||
"As of September 25, 2021, the total deferred tax assets and liabilities for the years 2021 and 2020 are as follows:\n",
|
||||
"\n",
|
||||
"**Deferred Tax Assets:**\n",
|
||||
"- 2021: $25,176 million\n",
|
||||
"- 2020: $19,336 million\n",
|
||||
"\n",
|
||||
"**Deferred Tax Liabilities:**\n",
|
||||
"- 2021: $7,200 million\n",
|
||||
"- 2020: $10,138 million\n",
|
||||
"\n",
|
||||
"**Net Deferred Tax Assets:**\n",
|
||||
"- 2021: $13,073 million\n",
|
||||
"- 2020: $8,157 million\n",
|
||||
"\n",
|
||||
"The information for 2019 is not provided in the context.\n",
|
||||
"\n",
|
||||
"***********MultiModal Query Engine***********\n",
|
||||
"The federal deferred tax assets and liabilities for the years 2019 to 2021 are as follows:\n",
|
||||
"\n",
|
||||
"### Deferred Tax Assets (in millions):\n",
|
||||
"- **2021**: $25,176\n",
|
||||
"- **2020**: $19,336\n",
|
||||
"- **2019**: Not specified in the provided content.\n",
|
||||
"\n",
|
||||
"### Deferred Tax Liabilities (in millions):\n",
|
||||
"- **2021**: $7,200\n",
|
||||
"- **2020**: $10,138\n",
|
||||
"- **2019**: Not specified in the provided content.\n",
|
||||
"\n",
|
||||
"### Net Deferred Tax Assets (in millions):\n",
|
||||
"- **2021**: $13,073\n",
|
||||
"- **2020**: $8,157\n",
|
||||
"- **2019**: Not specified in the provided content.\n",
|
||||
"\n",
|
||||
"The significant components of deferred tax assets and liabilities reflect the effects of tax credits and temporary differences between financial statement carrying amounts and their respective tax bases.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"query = \"federal deferred tax in 2019-2021\"\n",
|
||||
"\n",
|
||||
"response_1 = await baseline_query_engine.aquery(query)\n",
|
||||
"print(\"\\n***********Baseline Query Engine***********\")\n",
|
||||
"print(response_1)\n",
|
||||
"\n",
|
||||
"response_2 = await markdown_query_engine.aquery(query)\n",
|
||||
"print(\"\\n***********Markdown Query Engine***********\")\n",
|
||||
"print(response_2)\n",
|
||||
"\n",
|
||||
"response_3 = await multimodal_query_engine.aquery(query)\n",
|
||||
"print(\"\\n***********MultiModal Query Engine***********\")\n",
|
||||
"print(response_3)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"2025-08-18 21:36:07,790 - INFO - HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
|
||||
"2025-08-18 21:36:14,197 - INFO - HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\n",
|
||||
"***********Baseline Query Engine***********\n",
|
||||
"State current tax (in millions):\n",
|
||||
"- 2019: +$475 million\n",
|
||||
"- 2020: +$455 million\n",
|
||||
"- 2021: +$1,620 million\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"2025-08-18 21:36:14,584 - INFO - HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
|
||||
"2025-08-18 21:36:22,084 - INFO - HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\n",
|
||||
"***********Markdown Query Engine***********\n",
|
||||
"2019 — Current state taxes: $475 million (change vs prior year: n/a) \n",
|
||||
"2020 — Current state taxes: $455 million (change vs 2019: −$20 million) \n",
|
||||
"2021 — Current state taxes: $1,620 million (change vs 2020: +$1,165 million)\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"2025-08-18 21:36:22,441 - INFO - HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
|
||||
"2025-08-18 21:36:33,498 - INFO - HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\n",
|
||||
"***********MultiModal Query Engine***********\n",
|
||||
"The current state tax amounts (in millions) per the Note 5 table are:\n",
|
||||
"\n",
|
||||
"- 2019: $475\n",
|
||||
"- 2020: $455 (−$20 vs 2019; −4.2%)\n",
|
||||
"- 2021: $1,620 (+$1,165 vs 2020; +256.0%)\n",
|
||||
"\n",
|
||||
"All amounts are in millions of dollars.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"query = \"current state taxes per year in 2019-2021 (include +/-)\"\n",
|
||||
"\n",
|
||||
"response_1 = await baseline_query_engine.aquery(query)\n",
|
||||
"print(\"\\n***********Baseline Query Engine***********\")\n",
|
||||
"print(response_1)\n",
|
||||
"\n",
|
||||
"response_2 = await markdown_query_engine.aquery(query)\n",
|
||||
"print(\"\\n***********Markdown Query Engine***********\")\n",
|
||||
"print(response_2)\n",
|
||||
"\n",
|
||||
"response_3 = await multimodal_query_engine.aquery(query)\n",
|
||||
"print(\"\\n***********MultiModal Query Engine***********\")\n",
|
||||
"print(response_3)"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": ".venv",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
||||
@@ -0,0 +1,197 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Using the Raw API\n",
|
||||
"\n",
|
||||
"This notebook walks through how to use the raw API to parse documents.\n",
|
||||
"\n",
|
||||
"Status:\n",
|
||||
"| Last Executed | Version | State |\n",
|
||||
"|---------------|---------|------------|\n",
|
||||
"| Aug-18-2025 | N/A | Maintained |"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!wget \"https://arxiv.org/pdf/1706.03762.pdf\" -O \"./attention.pdf\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"api_key = \"llx-...\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import mimetypes\n",
|
||||
"import requests\n",
|
||||
"import time\n",
|
||||
"\n",
|
||||
"headers = {\"Authorization\": f\"Bearer {api_key}\"}\n",
|
||||
"file_path = \"./attention.pdf\"\n",
|
||||
"base_url = \"https://api.cloud.llamaindex.ai/api/parsing\"\n",
|
||||
"\n",
|
||||
"with open(file_path, \"rb\") as f:\n",
|
||||
" mime_type = mimetypes.guess_type(file_path)[0]\n",
|
||||
" files = {\"file\": (f.name, f, mime_type)}\n",
|
||||
" body = {\n",
|
||||
" \"parse_mode\": \"parse_page_with_agent\",\n",
|
||||
" \"model\": \"openai-gpt-4-1-mini\",\n",
|
||||
" \"high_res_ocr\": True,\n",
|
||||
" \"adaptive_long_table\": True,\n",
|
||||
" \"outlined_table_extraction\": True,\n",
|
||||
" \"output_tables_as_HTML\": True,\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" # send the request, upload the file\n",
|
||||
" url = f\"{base_url}/upload\"\n",
|
||||
" response = requests.post(url, headers=headers, files=files, data=body)\n",
|
||||
"\n",
|
||||
"response.raise_for_status()\n",
|
||||
"# get the job id for the result_url\n",
|
||||
"job_id = response.json()[\"id\"]\n",
|
||||
"result_type = \"json\" # or \"markdown\" or \"json\"\n",
|
||||
"result_url = f\"{base_url}/job/{job_id}/result/{result_type}\"\n",
|
||||
"\n",
|
||||
"# check for the result until its ready\n",
|
||||
"while True:\n",
|
||||
" response = requests.get(result_url, headers=headers)\n",
|
||||
" if response.status_code == 200:\n",
|
||||
" break\n",
|
||||
"\n",
|
||||
" time.sleep(2)\n",
|
||||
"\n",
|
||||
"# download the result\n",
|
||||
"result = response.json()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"dict_keys(['pages', 'job_metadata'])\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(result.keys())"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"dict_keys(['page', 'text', 'md', 'images', 'charts', 'items', 'status', 'originalOrientationAngle', 'links', 'width', 'height', 'triggeredAutoMode', 'parsingMode', 'structuredData', 'noStructuredContent', 'noTextContent', 'pageHeaderMarkdown', 'pageFooterMarkdown', 'confidence'])\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(result[\"pages\"][0].keys())"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\n",
|
||||
"Provided proper attribution is provided, Google hereby grants permission to reproduce the tables and figures in this paper solely for use in journalistic or scholarly works.\n",
|
||||
"\n",
|
||||
"# Attention Is All You Need\n",
|
||||
"\n",
|
||||
"**Ashish Vaswani*** \n",
|
||||
"Google Brain \n",
|
||||
"avaswani@google.com \n",
|
||||
"\n",
|
||||
"**Noam Shazeer*** \n",
|
||||
"Google Brain \n",
|
||||
"noam@google.com \n",
|
||||
"\n",
|
||||
"**Niki Parmar*** \n",
|
||||
"Google Research \n",
|
||||
"nikip@google.com \n",
|
||||
"\n",
|
||||
"**Jakob Uszkoreit*** \n",
|
||||
"Google Research \n",
|
||||
"usz@google.com \n",
|
||||
"\n",
|
||||
"**Llion Jones*** \n",
|
||||
"Google Research \n",
|
||||
"llion@google.com \n",
|
||||
"\n",
|
||||
"**Aidan N. Gomez* †** \n",
|
||||
"University of Toronto \n",
|
||||
"aidan@cs.toronto.edu \n",
|
||||
"\n",
|
||||
"**Łukasz Kaiser*** \n",
|
||||
"Google Brain \n",
|
||||
"lukaszkaiser@google.com \n",
|
||||
"\n",
|
||||
"**Illia Polosukhin* ‡** \n",
|
||||
"illia.polosukhin@gmail.com \n",
|
||||
"\n",
|
||||
"## Abstract\n",
|
||||
"\n",
|
||||
"The dominant sequence transduction models are based on complex recurrent or convolutional neural networks that include an encoder and a decoder. The best performing models also connect the encoder and decoder through an attention mechanism. We propose a new simple network architecture, the Transformer, based solely on attention mechanisms, dispensing with recurrence and convolutions entirely. Experiments on two machine translation tasks show these models to be superior in quality while being more parallelizable and requiring significantly less time to train. Our model achieves 28.4 BLEU on the WMT 2014 English-to-German translation task, improving over the existing best results, including ensembles, by over 2 BLEU. On the WMT 2014 English-to-French translation task, our model establishes a new single-model state-of-the-art BLEU score of 41.8 after training for 3.5 days on eight GPUs, a small fraction of the training costs of the best models from the literature. We show that the Transformer generalizes well to other tasks by applying it successfully to English constituency parsing both with large and limited training data.\n",
|
||||
"\n",
|
||||
"----\n",
|
||||
"\n",
|
||||
"*Equal contribution. Listing order is random. Jakob proposed replacing RNNs with self-attention and started the effort to evaluate this idea. Ashish, with Il\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(result[\"pages\"][0][\"md\"][:2000])"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": ".venv",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2
|
||||
}
|
||||
@@ -0,0 +1,231 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# LlamaParse Usage\n",
|
||||
"\n",
|
||||
"This notebook walks through the basic usage of LlamaParse.\n",
|
||||
"\n",
|
||||
"Status:\n",
|
||||
"| Last Executed | Version | State |\n",
|
||||
"|---------------|---------|------------|\n",
|
||||
"| Aug-18-2025 | 0.6.61 | Maintained |"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%pip install \"llama-index>=0.13.2<0.14.0\" llama-cloud-services"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!wget \"https://arxiv.org/pdf/1706.03762.pdf\" -O \"./attention.pdf\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"\n",
|
||||
"os.environ[\"LLAMA_CLOUD_API_KEY\"] = \"llx-...\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Started parsing the file under job_id ebc7e76e-addb-429b-8666-bee9c5832a84\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from llama_cloud_services import LlamaParse\n",
|
||||
"\n",
|
||||
"result = await LlamaParse(\n",
|
||||
" parse_mode=\"parse_page_with_agent\",\n",
|
||||
" model=\"openai-gpt-4-1-mini\",\n",
|
||||
" high_res_ocr=True,\n",
|
||||
" adaptive_long_table=True,\n",
|
||||
" outlined_table_extraction=True,\n",
|
||||
" output_tables_as_HTML=True,\n",
|
||||
").aparse(\"./attention.pdf\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"1 Introduction\n",
|
||||
"\n",
|
||||
"Recurrent neural networks, long short-term memory [13] and gated recurrent [7] neural networks\n",
|
||||
"in particular, have been firmly established as state of the art approaches in sequence modeling and\n",
|
||||
"transduction problems such as language modeling and machine translation [35, 2, 5]. Numerous\n",
|
||||
"efforts have since continued to push the boundaries of recurrent language models and encoder-decoder\n",
|
||||
"architectures [38, 24, 15].\n",
|
||||
"Recurrent models typically factor computation along the symbol positions of the input and output\n",
|
||||
"sequences. Aligning the positions to steps in computation time, they generate a sequence of hidden\n",
|
||||
"states ht, as a function of the previous hidden state ht−1 and the input for position t. This inherently\n",
|
||||
"sequential nature precludes parallelization within training examples, which becomes critical at longer\n",
|
||||
"sequence lengths, as memory constraints limit batching across examples. Recent work has achieved\n",
|
||||
"significant improvements in computational efficiency through factorization tricks [21] and conditional\n",
|
||||
"computation [32], while also improving model performance in case of the latter. The fundamental\n",
|
||||
"constraint of sequential computation, however, remains.\n",
|
||||
"Attention mechanisms have become an integral part of compelling sequence modeling and transduc-\n",
|
||||
"tion models in various tasks, allowing modeling of dependencies without regard to their distance in\n",
|
||||
"the input or output sequences [2, 19]. In all but a few cases [27], however, such attention mechanisms\n",
|
||||
"are used in conjunction with a recurrent network.\n",
|
||||
"In this work we propose the Transformer, a model architecture eschewing recurrence and instead\n",
|
||||
"relying entirely on an attention mechanism to draw global dependencies between input and output.\n",
|
||||
"The Transformer allows for significantly more parallelization and can reach a new state of the art in\n",
|
||||
"translation quality after being trained for as little as twelve hours on eight P100 GPUs.\n",
|
||||
"\n",
|
||||
"2 Background\n",
|
||||
"\n",
|
||||
"The goal of reducing sequential computation also forms the foundation of the Extended Neural GPU\n",
|
||||
"[16], ByteNet [18] and ConvS2S [9], all of which use convolutional neural networks as basic building\n",
|
||||
"block, computing hidden representations in parallel for all input and output positions. In these models,\n",
|
||||
"the number of operations required to relate signals from two arbitrary input or output positions grows\n",
|
||||
"in the distance between positions, linearly for ConvS2S and logarithmically for ByteNet. This makes\n",
|
||||
"it more difficult to learn dependencies between distant positions [12]. In the Transformer this is\n",
|
||||
"reduced to a constant number of operations, albeit at the cost of reduced effective resolution due\n",
|
||||
"to averaging attention-weighted positions, an effect we counteract with Multi-Head Attention as\n",
|
||||
"described in section 3.2.\n",
|
||||
"Self-attention, sometimes called intra-attention is an attention mechanism relating different positions\n",
|
||||
"of a single sequence in order to compute a representation of the sequence. Self-attention has been\n",
|
||||
"used successfully in a variety of tasks including reading comprehension, abstractive summarization,\n",
|
||||
"textual entailment and learning task-independent sentence representations [4, 27, 28, 22].\n",
|
||||
"End-to-end memory networks are based on a recurrent attention mechanism instead of sequence-\n",
|
||||
"aligned recurrence and have been shown to perform well on simple-language question answering and\n",
|
||||
"language modeling tasks [34].\n",
|
||||
"To the best of our knowledge, however, the Transformer is the first transduction model relying\n",
|
||||
"entirely on self-attention to compute representations of its input and output without using sequence-\n",
|
||||
"aligned RNNs or convolution. In the following sections, we will describe the Transformer, motivate\n",
|
||||
"self-attention and discuss its advantages over models such as [17, 18] and [9].\n",
|
||||
"\n",
|
||||
"3 Model Architecture\n",
|
||||
"\n",
|
||||
"Most competitive neural sequence transduction models have an encoder-decoder structure [5, 2, 35].\n",
|
||||
"Here, the encoder maps an input sequence of symbol representations (x1, ..., xn) to a sequence\n",
|
||||
"of continuous representations z = (z1, ..., zn). Given z, the decoder then generates an output\n",
|
||||
"sequence (y1, ..., ym) of symbols one element at a time. At each step the model is auto-regressive\n",
|
||||
"[10], consuming the previously generated symbols as additional input when generating the next.\n",
|
||||
"\n",
|
||||
" 2\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"documents = result.get_text_documents(split_by_page=True)\n",
|
||||
"print(documents[1].text)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\n",
|
||||
"Provided proper attribution is provided, Google hereby grants permission to reproduce the tables and figures in this paper solely for use in journalistic or scholarly works.\n",
|
||||
"\n",
|
||||
"# Attention Is All You Need\n",
|
||||
"\n",
|
||||
"**Ashish Vaswani*** \n",
|
||||
"Google Brain \n",
|
||||
"avaswani@google.com \n",
|
||||
"\n",
|
||||
"**Noam Shazeer*** \n",
|
||||
"Google Brain \n",
|
||||
"noam@google.com \n",
|
||||
"\n",
|
||||
"**Niki Parmar*** \n",
|
||||
"Google Research \n",
|
||||
"nikip@google.com \n",
|
||||
"\n",
|
||||
"**Jakob Uszkoreit*** \n",
|
||||
"Google Research \n",
|
||||
"usz@google.com \n",
|
||||
"\n",
|
||||
"**Llion Jones*** \n",
|
||||
"Google Research \n",
|
||||
"llion@google.com \n",
|
||||
"\n",
|
||||
"**Aidan N. Gomez* †** \n",
|
||||
"University of Toronto \n",
|
||||
"aidan@cs.toronto.edu \n",
|
||||
"\n",
|
||||
"**Łukasz Kaiser*** \n",
|
||||
"Google Brain \n",
|
||||
"lukaszkaiser@google.com \n",
|
||||
"\n",
|
||||
"**Illia Polosukhin* ‡** \n",
|
||||
"illia.polosukhin@gmail.com \n",
|
||||
"\n",
|
||||
"## Abstract\n",
|
||||
"\n",
|
||||
"The dominant sequence transduction models are based on complex recurrent or convolutional neural networks that include an encoder and a decoder. The best performing models also connect the encoder and decoder through an attention mechanism. We propose a new simple network architecture, the Transformer, based solely on attention mechanisms, dispensing with recurrence and convolutions entirely. Experiments on two machine translation tasks show these models to be superior in quality while being more parallelizable and requiring significantly less time to train. Our model achieves 28.4 BLEU on the WMT 2014 English-to-German translation task, improving over the existing best results, including ensembles, by over 2 BLEU. On the WMT 2014 English-to-French translation task, our model establishes a new single-model state-of-the-art BLEU score of 41.8 after training for 3.5 days on eight GPUs, a small fraction of the training costs of the best models from the literature. We show that the Transformer generalizes well to other tasks by applying it successfully to English constituency parsing both with large and limited training data.\n",
|
||||
"\n",
|
||||
"----\n",
|
||||
"\n",
|
||||
"*Equal contribution. Listing order is random. Jakob proposed replacing RNNs with self-attention and started the effort to evaluate this idea. Ashish, with Illia, designed and implemented the first Transformer models and has been crucially involved in every aspect of this work. Noam proposed scaled dot-product attention, multi-head attention and the parameter-free position representation and became the other person involved in nearly every detail. Niki designed, implemented, tuned and evaluated countless model variants in our original codebase and tensor2tensor. Llion also experimented with novel model variants, was responsible for our initial codebase, and efficient inference and visualizations. Lukasz and Aidan spent countless long days designing various parts of and implementing tensor2tensor, replacing our earlier codebase, greatly improving results and massively accelerating our research. \n",
|
||||
"† Work performed while at Google Brain. \n",
|
||||
"‡ Work performed while at Google Research.\n",
|
||||
"\n",
|
||||
"31st Conference on Neural Information Processing Systems (NIPS 2017), Long Beach, CA, USA.\n",
|
||||
"\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"documents = result.get_markdown_documents(split_by_page=True)\n",
|
||||
"print(documents[0].text)"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": ".venv",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
||||
@@ -0,0 +1,297 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# RAG with Excel Spreadsheet using LlamaPrase\n",
|
||||
"\n",
|
||||
"<a href=\"https://colab.research.google.com/github/run-llama/llama_cloud_services/blob/main/examples/demo_excel.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>\n",
|
||||
"\n",
|
||||
"This notebook shows you using LlamaParse with Excel Spreadsheet.\n",
|
||||
"\n",
|
||||
"We will use NVIDIA revenue [data](https://investor.nvidia.com/financial-info/quarterly-results/default.aspx) from last 5 quarters/\n",
|
||||
"\n",
|
||||
"Status:\n",
|
||||
"| Last Executed | Version | State |\n",
|
||||
"|---------------|---------|------------|\n",
|
||||
"| Aug-18-2025 | 0.6.61 | Maintained |\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%pip install \"llama-index>=0.13.2<0.14.0\"\n",
|
||||
"%pip install llama-cloud-services"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Set LLAMA_CLOUD_API_KEY"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_cloud_services import LlamaParse\n",
|
||||
"\n",
|
||||
"api_key = \"llx-jwAQZL8T38onyL9hKBOXyRtnuCU0Fk3z7tmDhIT3L0GEfohJ\" # get from cloud.llamaindex.ai"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Use LlamaParse to parse excel document"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Started parsing the file under job_id 9ea6e117-ada1-4e22-b067-10a128b2c16e\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"parser = LlamaParse(\n",
|
||||
" api_key=api_key, # can also be set in your env as LLAMA_CLOUD_API_KEY\n",
|
||||
" parse_mode=\"parse_page_with_agent\",\n",
|
||||
" model=\"openai-gpt-4-1-mini\",\n",
|
||||
" high_res_ocr=True,\n",
|
||||
" adaptive_long_table=True,\n",
|
||||
" outlined_table_extraction=True,\n",
|
||||
" output_tables_as_HTML=True,\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"result = await parser.aparse(\"./data/nvidia_quarterly_revenue_trend_by_market.xlsx\")\n",
|
||||
"documents = result.get_markdown_documents(split_by_page=True)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Set OpenAI API Key"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"\n",
|
||||
"os.environ[\"OPENAI_API_KEY\"] = \"sk-...\"\n",
|
||||
"\n",
|
||||
"from llama_index.llms.openai import OpenAI\n",
|
||||
"from llama_index.core import Settings\n",
|
||||
"\n",
|
||||
"llm = OpenAI(model=\"gpt-5-mini\")\n",
|
||||
"Settings.llm = llm"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Build Index and QueryEngine"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.core import VectorStoreIndex\n",
|
||||
"\n",
|
||||
"index = VectorStoreIndex.from_documents(documents)\n",
|
||||
"\n",
|
||||
"query_engine = index.as_query_engine()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Querying"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Total revenue in Q1 FY25: $26,044 million.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"response = query_engine.query(\"What is the total revenue in Q1 FY25?\")\n",
|
||||
"print(str(response))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Data Center revenue rose from $3,750M in Q1 FY23 to $22,563M in Q1 FY25 — an absolute increase of $18,813M, which is a 501.7% increase (≈6.02×).\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"response = query_engine.query(\n",
|
||||
" \"What is the revenue growth of data centre from Q1 FY23 to Q1 FY25?\"\n",
|
||||
")\n",
|
||||
"print(str(response))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"$2,865 million\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"response = query_engine.query(\"What is the revenue of gaming in Q4 2024?\")\n",
|
||||
"print(str(response))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"$22,103 million.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"response = query_engine.query(\"What is the total revenue in Q4 FY24?\")\n",
|
||||
"print(str(response))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Professional Visualization revenue (last four quarters of 2024, $ in millions):\n",
|
||||
"- Q4 FY24: $463M\n",
|
||||
"- Q3 FY24: $416M\n",
|
||||
"- Q2 FY24: $379M\n",
|
||||
"- Q1 FY24: $295M\n",
|
||||
"\n",
|
||||
"Total (those four quarters): $1,553M.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"response = query_engine.query(\n",
|
||||
" \"What is the revenue Professional Visualization in last 4 quarters of 2024?\"\n",
|
||||
")\n",
|
||||
"print(str(response))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"$18,120 million\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"response = query_engine.query(\"What is the total revenue in Q3 FY24?\")\n",
|
||||
"print(str(response))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Data Center revenue rose from $14,514M (Q3 FY24) to $18,404M (Q4 FY24) — an increase of $3,890M, or about 26.8%.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"response = query_engine.query(\n",
|
||||
" \"What is the revenue growth of data centre from Q3 FY24 to Q4 FY24?\"\n",
|
||||
")\n",
|
||||
"print(str(response))"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"provenance": []
|
||||
},
|
||||
"kernelspec": {
|
||||
"display_name": ".venv",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 0
|
||||
}
|
||||
@@ -0,0 +1,565 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# LlamaParse - Fast checking Insurance Contract for Coverage\n",
|
||||
"\n",
|
||||
"<a href=\"https://colab.research.google.com/github/run-llama/llama_cloud_services/blob/main/examples/demo_insurance.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>\n",
|
||||
"\n",
|
||||
"In this notebook we will look at how LlamaParse can be used to extract structured coverage information from an insurance policy.\n",
|
||||
"\n",
|
||||
"Status:\n",
|
||||
"| Last Executed | Version | State |\n",
|
||||
"|---------------|---------|------------|\n",
|
||||
"| Aug-19-2025 | 0.6.61 | Deprecated |"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Installation of required packages"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%pip install \"llama-index>=0.13.0<0.14.0\" llama-parse"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Download an insurance policy fron IRDAI\n",
|
||||
"\n",
|
||||
"The Insurance Regulatory and Development Authority of India (IRDAI) maintains a great resource: https://policyholder.gov.in/web/guest/non-life-insurance-products where all insurance policies available in India are publicly available for download! Let's download a complex health insurance policy as an example."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!wget \"https://policyholder.gov.in/documents/37343/931203/NBHTGBP22011V012223.pdf/c392bcc1-f6a8-cadd-ab84-495b3273d2c3?version=1.0&t=1669350459879&download=true\" -O \"./policy.pdf\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Initializing LlamaIndex and LlamaParse"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"\n",
|
||||
"os.environ[\"LLAMA_CLOUD_API_KEY\"] = \"llx-...\"\n",
|
||||
"os.environ[\"OPENAI_API_KEY\"] = \"sk-...\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.llms.openai import OpenAI\n",
|
||||
"from llama_index.embeddings.openai import OpenAIEmbedding\n",
|
||||
"from llama_index.core import VectorStoreIndex\n",
|
||||
"from llama_index.core import Settings\n",
|
||||
"\n",
|
||||
"# for the purpose of this example, we will use the small model embedding and gpt3.5\n",
|
||||
"embed_model = OpenAIEmbedding(model=\"text-embedding-3-small\")\n",
|
||||
"llm = OpenAI(model=\"gpt-5-mini\")\n",
|
||||
"\n",
|
||||
"Settings.llm = llm\n",
|
||||
"Settings.embed_model = embed_model"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Vanilla Approach - Parse the Policy with LlamaParse into Markdown"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Started parsing the file under job_id 35052045-ce36-4343-9e7c-11e059a59cc2\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from llama_cloud_services import LlamaParse\n",
|
||||
"\n",
|
||||
"result = await LlamaParse().aparse(\"./policy.pdf\")\n",
|
||||
"documents = result.get_markdown_documents(split_by_page=True)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Bupa niva Health Insurance\n",
|
||||
"\n",
|
||||
"# 1. Preamble\n",
|
||||
"\n",
|
||||
"This ‘Travel Infinity’ Policy is a contract of insurance between You and Us which is subject to payment of full premium in advance and the terms, conditions and exclusions of this Policy. Expense incurred outside the policy period will NOT be covered. Unutilized Sum Insured will expire at the end of policy year. All applicable benefits, details and limits are mentioned in your Certificate of insurance. We will cover only allopathic treatments in this policy.\n",
|
||||
"\n",
|
||||
"# 2. Defined Terms\n",
|
||||
"\n",
|
||||
"The terms listed below in this Section and used elsewhere in the Policy in Initial Capitals shall have the meaning set out against them in this Section.\n",
|
||||
"\n",
|
||||
"# Standard Definitions\n",
|
||||
"\n",
|
||||
"# 2.1\n",
|
||||
"\n",
|
||||
"Accident or Accidental means sudden, unforeseen and involuntary event caused by external, visible and violent means.\n",
|
||||
"\n",
|
||||
"# 2.2\n",
|
||||
"\n",
|
||||
"Co-payment means a cost sharing requirement under a health insurance policy that provides that the policyholder/insured will bear a specified percentage of the adm\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(documents[0].text[0:1000])"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"index = VectorStoreIndex.from_documents(documents)\n",
|
||||
"query_engine = index.as_query_engine()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Querying the model for coverage"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"I can’t give an exact dollar amount without the values shown on your Certificate of Insurance. How the claim would be settled:\n",
|
||||
"\n",
|
||||
"1. First check that your policy’s required delay threshold is met (the policy only pays if the delay exceeds the number of hours shown on your Certificate). Also the insurer won’t pay if the delay was publicly known at least 6 hours before departure.\n",
|
||||
"\n",
|
||||
"2. Find which benefit option applies on your Certificate: a fixed payment or reimbursement of actual alternate-travel cost.\n",
|
||||
" - If a fixed payment applies, you will receive the fixed sum listed on the Certificate (regardless of the $450 you paid), subject to the other conditions and any deductible shown.\n",
|
||||
" - If reimbursement applies, the insurer will reimburse up to the Sum Insured shown on the Certificate, but will first deduct any compensation paid by the airline or other sources and then apply the deductible.\n",
|
||||
"\n",
|
||||
"3. Reimbursement formula (if reimbursement option applies):\n",
|
||||
" Payable = max(0, min(Sum Insured, Amount you paid ($450) − airline/other compensation) − Deductible)\n",
|
||||
"\n",
|
||||
"4. Other limits: only one flight-delay claim is payable in the policy period as shown on the Certificate.\n",
|
||||
"\n",
|
||||
"Example: if your Certificate shows Sum Insured $1,000, Deductible $50, and the airline paid no compensation, payable = min(1000,450) − 50 = $400.\n",
|
||||
"\n",
|
||||
"Check your Certificate of Insurance for the delay threshold, whether fixed or reimbursement applies, the Sum Insured and the Deductible, and any airline compensation already received to calculate the exact amount.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"query_1 = \"My flight was delayed 8 hours and I paid $450, how much am I covered for?\"\n",
|
||||
"\n",
|
||||
"response_1 = await query_engine.aquery(query_1)\n",
|
||||
"print(str(response_1))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"The information is split across the document which leads to retrieval issues. Let's try some parsing instructions to improve our result."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Started parsing the file under job_id c89abe4b-0bb3-4e04-a37f-1da880392346\n",
|
||||
"."
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"result = await LlamaParse(\n",
|
||||
" result_type=\"markdown\",\n",
|
||||
" system_prompt_append=\"\"\"\n",
|
||||
"This document is an insurance policy.\n",
|
||||
"When a benefits/coverage/exlusion is describe in the document ammend to it add a text in the follwing benefits string format (where coverage could be an exclusion).\n",
|
||||
"\n",
|
||||
"For {nameofrisk} and in this condition {whenDoesThecoverageApply} the coverage is {coverageDescription}. \n",
|
||||
" \n",
|
||||
"If the document contain a benefits TABLE that describe coverage amounts, do not ouput it as a table, but instead as a list of benefits string.\n",
|
||||
" \n",
|
||||
"\"\"\",\n",
|
||||
").aparse(\"./policy.pdf\")\n",
|
||||
"\n",
|
||||
"documents_with_instruction = result.get_markdown_documents(split_by_page=True)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Let see how the 2 parsing compare (change target page to explore)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\n",
|
||||
"Inpatient treatment\n",
|
||||
"\n",
|
||||
"# Claim Form (filled and signed by the Insured)\n",
|
||||
"\n",
|
||||
"# Hospital Daily Cash\n",
|
||||
"\n",
|
||||
"# Release of Medical information Form (filled and signed by the Insured)\n",
|
||||
"\n",
|
||||
"# Waiver of Deductible\n",
|
||||
"\n",
|
||||
"# Original pathological and diagnostic reports, discharge summary indoor case papers (if any) and prescriptions issued by the treating Medical practitioner or Network Provider\n",
|
||||
"\n",
|
||||
"# Adventure Sports Cover\n",
|
||||
"\n",
|
||||
"# Home to Home Cover\n",
|
||||
"\n",
|
||||
"# Extension to in-patient care\n",
|
||||
"\n",
|
||||
"# Ambulance Charge\n",
|
||||
"\n",
|
||||
"# Out-patient treatment\n",
|
||||
"\n",
|
||||
"# Cancer Screening & Mammographic Examination\n",
|
||||
"\n",
|
||||
"# New Born baby Cover\n",
|
||||
"\n",
|
||||
"# Maternity\n",
|
||||
"\n",
|
||||
"# Complete pre-existing disease cover\n",
|
||||
"\n",
|
||||
"# Medical sum insured replenishment in case of hospitalization due to accident\n",
|
||||
"\n",
|
||||
"# Waiver of sublimit for insured above 60 years of age\n",
|
||||
"\n",
|
||||
"# Psychiatric Counseling\n",
|
||||
"\n",
|
||||
"# Physiotherapy\n",
|
||||
"\n",
|
||||
"# Terrorism cover\n",
|
||||
"\n",
|
||||
"# Medical tele-consultation\n",
|
||||
"\n",
|
||||
"# Medical evacuation\n",
|
||||
"\n",
|
||||
"Medical reports and transportation details issued by the evacuation agency, prescriptions and medical report by the attending Medical Practitioner furnishing the name of the Insured Person and details of treatment rendered along with the statement confirm the necessity of evacuation. Documentary proof for expenses incurred towards the Medical Evacuation.\n",
|
||||
"\n",
|
||||
"# Compassionate visit\n",
|
||||
"\n",
|
||||
"A certificate from the Medical Practitioner recommending the presence in the form of special assistance to be rendered by an additional member during the entire period of hospitalization. The certificate shall also specify the minimum period in which person is admitted in the hospital. Discharge summary of the Hospital furnishing details including the date of admission and date of discharge. Stamped boarding pass with invoice used for the travel by the Immediate Family Member. Copy passport of Immediate Family Member with entry and exit stamp.\n",
|
||||
"\n",
|
||||
"# Escort of Minor Child\n",
|
||||
"\n",
|
||||
"A certificate from the Medical Practitioner specifying the minimum period of Hospitalization. Discharge summary of the Hospital furnishing details including the date of admission and date of discharge, Stamped Boarding pass used for the return travel of the child to the Country of Residence. Stamped Boarding pass of the attendant from the Country of Residence to the place of hospitalization (if attendant is necessary). Copy of passport of the child with entry and exit stamp.\n",
|
||||
"\n",
|
||||
"# Upgradation to Business Class\n",
|
||||
"\n",
|
||||
"A certificate from the Medical Practitioner specifying the minimum period of Hospitalization. Discharge summary of the Hospital furnishing the details including the date of admission and date of discharge.\n",
|
||||
"\n",
|
||||
"Product Name: Travel infinity\n",
|
||||
"\n",
|
||||
"Product UIN: NBHTGBP22011V012223\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"=========================================================\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"# Claim Form\n",
|
||||
"\n",
|
||||
"Inpatient treatment\n",
|
||||
"\n",
|
||||
"- Claim Form (filled and signed by the Insured)\n",
|
||||
"- Release of Medical information Form (filled and signed by the Insured)\n",
|
||||
"- Original pathological and diagnostic reports, discharge summary indoor case papers (if any) and prescriptions issued by the treating Medical practitioner or Network Provider\n",
|
||||
"- Passport and Visa copy with Entry Stamp of Country of Visit and exit Stamp from India\n",
|
||||
"- FIR report of police (if applicable)\n",
|
||||
"\n",
|
||||
"Hospital Daily Cash\n",
|
||||
"\n",
|
||||
"Waiver of Deductible\n",
|
||||
"\n",
|
||||
"Optional Co-payment\n",
|
||||
"\n",
|
||||
"Adventure Sports Cover\n",
|
||||
"\n",
|
||||
"Home to Home Cover\n",
|
||||
"\n",
|
||||
"Extension to in-patient care\n",
|
||||
"\n",
|
||||
"Ambulance Charge\n",
|
||||
"\n",
|
||||
"Out-patient treatment\n",
|
||||
"\n",
|
||||
"Cancer Screening & Mammographic Examination\n",
|
||||
"\n",
|
||||
"New Born baby Cover\n",
|
||||
"\n",
|
||||
"Maternity\n",
|
||||
"\n",
|
||||
"Complete pre-existing disease cover\n",
|
||||
"\n",
|
||||
"Medical sum insured replenishment in case of hospitalization due to accident\n",
|
||||
"\n",
|
||||
"Waiver of sublimit for insured above 60 years of age\n",
|
||||
"\n",
|
||||
"Psychiatric Counseling\n",
|
||||
"\n",
|
||||
"Physiotherapy\n",
|
||||
"\n",
|
||||
"Terrorism cover\n",
|
||||
"\n",
|
||||
"Medical tele-consultation\n",
|
||||
"\n",
|
||||
"Medical evacuation\n",
|
||||
"\n",
|
||||
"Medical reports and transportation details issued by the evacuation agency, prescriptions and medical report by the attending Medical Practitioner furnishing the name of the Insured Person and details of treatment rendered along with the statement confirming the necessity of evacuation. Documentary proof for expenses incurred towards the Medical Evacuation.\n",
|
||||
"\n",
|
||||
"Compassionate visit\n",
|
||||
"\n",
|
||||
"A certificate from the Medical Practitioner recommending the presence in the form of special assistance to be rendered by an additional member during the entire period of hospitalization. The certificate shall also specify the minimum period in which the person is admitted in the hospital. Discharge summary of the Hospital furnishing details including the date of admission and date of discharge. Stamped boarding pass with invoice used for the travel by the Immediate Family Member. Copy passport of Immediate Family Member with entry and exit stamp.\n",
|
||||
"\n",
|
||||
"Escort of Minor Child\n",
|
||||
"\n",
|
||||
"A certificate from the Medical Practitioner specifying the minimum period of Hospitalization. Discharge summary of the Hospital furnishing details including the date of admission and date of discharge, Stamped Boarding pass used for the return travel of the child to the Country of Residence. Stamped Boarding pass of the attendant from the Country of Residence to the place of hospitalization (if attendant is necessary). Copy of passport of the child with entry and exit stamp.\n",
|
||||
"\n",
|
||||
"Upgradation to Business Class\n",
|
||||
"\n",
|
||||
"A certificate from the Medical Practitioner specifying the minimum period of Hospitalization. Discharge summary of the Hospital furnishing the details including the date of admission and date of discharge.\n",
|
||||
"\n",
|
||||
"Product Name: Travel infinity\n",
|
||||
"\n",
|
||||
"Product UIN: NBHTGBP22011V012223\n",
|
||||
"\n",
|
||||
"\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"target_page = 45\n",
|
||||
"\n",
|
||||
"print(documents[target_page].text)\n",
|
||||
"print(\"\\n\\n=========================================================\\n\\n\")\n",
|
||||
"print(documents_with_instruction[target_page].text)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"instruction_index = VectorStoreIndex.from_documents(documents_with_instruction)\n",
|
||||
"query_engine_instruction = instruction_index.as_query_engine()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Comparing Instruction-Augmented Parsing vs. Vanilla Parsing\n",
|
||||
"\n",
|
||||
"When we parse the document with natural language instructions to add context on insurance coverage, we are able to correctly answer a wide range of queries in our RAG pipeline. In contrast, a RAG pipeline built with the vanilla method is not able to answer these queries."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Vanilla:\n",
|
||||
"I can’t give an exact payout without details from your Certificate of Insurance. What matters is which benefit applies and the certificate values. Here’s how to determine the amount and some examples:\n",
|
||||
"\n",
|
||||
"What to check on your certificate (send these if you want a precise calculation)\n",
|
||||
"- Which benefit is being used: Flight Delay (alternate travel booking reimbursement or fixed amount) or Trip Delay (fixed amount per block of hours). \n",
|
||||
"- The minimum delay threshold (the number of hours the delay must exceed). \n",
|
||||
"- Whether the policy pays reimbursement or a fixed amount (and, if fixed, the amount per block and length of each block). \n",
|
||||
"- Sum Insured / maximum limit for that benefit. \n",
|
||||
"- Deductible (amount you must absorb per claim). \n",
|
||||
"- Any compensation already paid by the airline or other source (this is deducted from the insurer’s payment). \n",
|
||||
"- Reason for the delay and whether it’s an excluded reason (e.g., delay was publicly known 6+ hours before departure).\n",
|
||||
"\n",
|
||||
"How to calculate (general rules)\n",
|
||||
"- If the policy reimburses actual alternate travel costs: insurer pays up to the Sum Insured, but subtract any compensation from the carrier and subtract the deductible. Payment = min(Sum Insured, your expense) − carrier compensation − deductible.\n",
|
||||
"- If the policy pays a fixed amount per block of hours: determine how many blocks your 8-hour delay covers (e.g., if a block is 4 hours, 8 hours = 2 blocks). Payment = blocks × fixed amount (subject to any stated maximum and any applicable deductible/offsets).\n",
|
||||
"\n",
|
||||
"Two simple examples\n",
|
||||
"- Reimbursement example: Sum Insured ≥ $450, deductible $50, airline paid $0 → insurer would pay $450 − $50 = $400. \n",
|
||||
"- Fixed-per-block example: certificate pays $100 per 4-hour block. 8 hours = 2 blocks → insurer would pay 2 × $100 = $200 (subject to any max limit or deductible if applicable).\n",
|
||||
"\n",
|
||||
"If you share the certificate values (which benefit, sum insured, deductible, fixed-per-block amount if any, and any airline compensation), I’ll compute the exact amount.\n",
|
||||
"With instructions:\n",
|
||||
"The amount payable depends on the Trip Delay benefit sum insured you chose in your policy certificate. Available Trip Delay benefit options are: 1K, 2K, 3K, 4K, 5K, 7.5K, 10K, 15K and 20K. The insurer pays the selected benefit amount for each block of delay hours as defined in your certificate (maximum up to 24 hours).\n",
|
||||
"\n",
|
||||
"So:\n",
|
||||
"- If your chosen Trip Delay benefit is at least equal to $450, the policy can cover your $450 expense (subject to the policy terms and exclusions).\n",
|
||||
"- If your chosen benefit is less than $450, the insurer will pay only up to the chosen benefit amount.\n",
|
||||
"\n",
|
||||
"Check your certificate to confirm which Trip Delay sum insured you purchased and whether any exclusions (for example, delays announced ≥6 hours before departure) apply.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"query_1 = \"My flight was delayed 8 hours and I paid $450, how much am I covered for?\"\n",
|
||||
"\n",
|
||||
"response_1 = await query_engine.aquery(query_1)\n",
|
||||
"print(\"Vanilla:\")\n",
|
||||
"print(response_1)\n",
|
||||
"\n",
|
||||
"print(\"With instructions:\")\n",
|
||||
"response_1_i = await query_engine_instruction.aquery(query_1)\n",
|
||||
"print(response_1_i)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Looking at the policy it says in list I that one expense not covered is Baby food"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Vanilla:\n",
|
||||
"No. Food and beverages (including baby food) are excluded as expenses not linked to treatment. The policy only covers medical treatment and specified newborn items (e.g., emergency inpatient care and vaccinations — vaccinations limited to USD 500) and explicitly excludes \"baby charges\" unless specifically indicated.\n",
|
||||
"With instructions:\n",
|
||||
"No. Baby food is not covered. The policy pays medical treatment expenses and expressly excludes items not linked to treatment (for example food and beverages), and it also lists \"baby charges\" as not payable unless specifically indicated. \n",
|
||||
"\n",
|
||||
"Newborn medical treatment and vaccinations can be covered under the newborn/maternity benefits (vaccination cover is limited and subject to the policy's special conditions, waiting periods and deductibles), so check your certificate of insurance for any specific limits or endorsements.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"query_2 = \"I just had a baby, is baby food covered?\"\n",
|
||||
"\n",
|
||||
"response_2 = await query_engine.aquery(query_2)\n",
|
||||
"print(\"Vanilla:\")\n",
|
||||
"print(response_2)\n",
|
||||
"\n",
|
||||
"print(\"With instructions:\")\n",
|
||||
"response_2_i = await query_engine_instruction.aquery(query_2)\n",
|
||||
"print(response_2_i)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Vanilla:\n",
|
||||
"Gauze (including gauze soft) used in your operation is included within the procedure charges. It is subsumed into the surgical/procedure fee and is not payable as a separate item.\n",
|
||||
"With instructions:\n",
|
||||
"Gauze used during your operation is included in the procedure charges. Its cost is subsumed into the procedure/surgical fee and will not be reimbursed as a separate line item.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"query_3 = \"How is gauze used in my operation covered?\"\n",
|
||||
"\n",
|
||||
"response_3 = await query_engine.aquery(query_3)\n",
|
||||
"print(\"Vanilla:\")\n",
|
||||
"print(response_3)\n",
|
||||
"\n",
|
||||
"print(\"With instructions:\")\n",
|
||||
"response_3_i = await query_engine_instruction.aquery(query_3)\n",
|
||||
"print(response_3_i)"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": ".venv",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
||||
@@ -0,0 +1,355 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "d27f1082-cd10-405e-9570-6f0e934bba8b",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# LlamaParse JSON Mode + Multimodal RAG\n",
|
||||
"\n",
|
||||
"<a href=\"https://colab.research.google.com/github/run-llama/llama_cloud_services/blob/main/examples/parse/demo_json.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>\n",
|
||||
"\n",
|
||||
"This notebook shows you how to use LlamaParse JSON mode with LlamaIndex to build a simple multimodal RAG pipeline.\n",
|
||||
"\n",
|
||||
"Using JSON mode gives you back a list of json dictionaries, which contains both text and images. You can then download these images and use a multimodal model to extract information and index them.\n",
|
||||
"\n",
|
||||
"Status:\n",
|
||||
"| Last Executed | Version | State |\n",
|
||||
"|---------------|---------|------------|\n",
|
||||
"| Aug-19-2025 | 0.6.61 | Maintained |"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "a004db48-8d3f-421c-915a-477692f71b90",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Setup\n",
|
||||
"\n",
|
||||
"Define imports, env variables, global LLM/embedding models."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "bc6a7a4b-b568-4db5-bcba-62f5c517ff3a",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%pip install llama-index\n",
|
||||
"%pip install \"llama-index-core>=0.13.2<0.14.0\"\n",
|
||||
"%pip install \"llama-index-llms-anthropic>=0.8.4<0.9.0\"\n",
|
||||
"%pip install \"llama-index-embeddings-huggingface>=0.6.0<0.7.0\"\n",
|
||||
"%pip install llama-cloud-services"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "0879301c-ff91-4431-941a-6c0ef7cd8fe2",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"\n",
|
||||
"# API access to llama-cloud\n",
|
||||
"os.environ[\"LLAMA_CLOUD_API_KEY\"] = \"llx-...\"\n",
|
||||
"\n",
|
||||
"# Using Anthropic API for LLMs\n",
|
||||
"os.environ[\"ANTHROPIC_API_KEY\"] = \"sk-...\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "391e2d95-5569-4d73-9f16-5b59d7326f8d",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.llms.anthropic import Anthropic\n",
|
||||
"\n",
|
||||
"llm = Anthropic(model=\"claude-4-sonnet-20250514\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "700f48e8-8b52-41f3-90f9-144d5fdd5c52",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"/Users/loganmarkewich/llama_parse/py/.venv/lib/python3.12/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n",
|
||||
" from .autonotebook import tqdm as notebook_tqdm\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from llama_index.core import Settings\n",
|
||||
"\n",
|
||||
"Settings.llm = llm\n",
|
||||
"Settings.embed_model = \"local:Qwen/Qwen3-Embedding-0.6B\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "b411d2ee-3e6b-45b0-b532-4a8e3abcdea0",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Load Data\n",
|
||||
"\n",
|
||||
"Let's load in the Uber 10Q report."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "c39d408f-e885-4940-85c7-b09ca3bc7cb7",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!wget 'https://raw.githubusercontent.com/run-llama/llama_index/main/docs/docs/examples/data/10q/uber_10q_march_2022.pdf' -O './uber_10q_march_2022.pdf'"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "c2f42af8-afb3-4b3b-82d3-6b332fb38aa4",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Using LlamaParse in JSON Mode for PDF Reading\n",
|
||||
"\n",
|
||||
"We show you how to run LlamaParse in JSON mode for PDF reading."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "9c9cd670-8229-4ad6-99a9-845bd82b7ec1",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Started parsing the file under job_id 33d93a46-1b43-4619-b4ff-0c272cbca4b3\n",
|
||||
".."
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from llama_cloud_services import LlamaParse\n",
|
||||
"\n",
|
||||
"parser = LlamaParse(\n",
|
||||
" parse_mode=\"parse_page_with_agent\",\n",
|
||||
" model=\"openai-gpt-4-1-mini\",\n",
|
||||
" high_res_ocr=True,\n",
|
||||
" adaptive_long_table=True,\n",
|
||||
" outlined_table_extraction=True,\n",
|
||||
" output_tables_as_HTML=True,\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"result = await parser.aparse(\"./uber_10q_march_2022.pdf\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "364a3276-d2db-4aee-9bc6-617ffd726d25",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"text_nodes = await result.aget_text_nodes(split_by_page=True)\n",
|
||||
"image_nodes = await result.aget_image_nodes(\n",
|
||||
" include_screenshot_images=True,\n",
|
||||
" include_object_images=False,\n",
|
||||
" image_download_dir=\"./uber_10q_images\",\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "2fe2e911-0393-42e8-a233-65639cdbebc4",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Extract/Index images from image dicts\n",
|
||||
"\n",
|
||||
"Here we use a multimodal model to caption images and create text nodes for indexing."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "36012145-5521-4ddb-a53e-df9ebd1ca8dd",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.core.llms import ChatMessage, ImageBlock, TextBlock\n",
|
||||
"from llama_index.core.schema import ImageNode, TextNode\n",
|
||||
"from llama_index.llms.anthropic import Anthropic\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"async def get_image_text_nodes(image_nodes: list[ImageNode]):\n",
|
||||
" \"\"\"Extract out text from images using a multimodal model.\"\"\"\n",
|
||||
" llm = Anthropic(model=\"claude-3-5-haiku-20241022\", max_tokens=300)\n",
|
||||
" img_text_nodes = []\n",
|
||||
" for image_node in image_nodes:\n",
|
||||
" image_path = image_node.image_path\n",
|
||||
" message = ChatMessage(\n",
|
||||
" role=\"user\",\n",
|
||||
" blocks=[\n",
|
||||
" TextBlock(text=\"Describe the images as alt text\"),\n",
|
||||
" ImageBlock(path=image_path),\n",
|
||||
" ],\n",
|
||||
" )\n",
|
||||
" response = await llm.achat([message])\n",
|
||||
" text_node = TextNode(\n",
|
||||
" text=str(response.message.content), metadata={\"path\": image_path}\n",
|
||||
" )\n",
|
||||
" img_text_nodes.append(text_node)\n",
|
||||
"\n",
|
||||
" return img_text_nodes"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "38f25045-6102-4920-9cd0-42b0ae6c872f",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"image_text_nodes = await get_image_text_nodes(image_nodes)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "4683c97a-da06-408a-9fe9-7e3c0aceb77d",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"'Alt text: United States Securities and Exchange Commission Form 10-Q for Uber Technologies, Inc., dated for the quarterly period ended March 31, 2022. The document shows company details including incorporation state (Delaware), address (1515 3rd Street, San Francisco), and indicates Uber is a large accelerated filer listed on the New York Stock Exchange with the trading symbol UBER.'"
|
||||
]
|
||||
},
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"image_text_nodes[0].get_content()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "3cfdf6db-381c-4e53-a0fb-e7670f75e0d5",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Build Index across image and text nodes\n",
|
||||
"\n",
|
||||
"Here we build a vector index across both text nodes and text nodes extracted from images."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "939aec6c-064a-4319-b2dc-70cc4a304c06",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.core import VectorStoreIndex\n",
|
||||
"\n",
|
||||
"index = VectorStoreIndex(text_nodes + image_text_nodes)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "529340d5-9319-4cdf-8ee1-bbd01ed00226",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"query_engine = index.as_query_engine()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "81d7ff30-5a87-44da-880d-4b1f41434d90",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"The bar graph titled 'Monthly Active Platform Consumers' shows the growth in platform users measured in millions from Q2 2020 to Q1 2022. The graph demonstrates a steady increase in the number of consumers using the platform, starting at 55 million users in Q2 2020 and rising to 115 million users in Q1 2022. The visualization displays notable growth between quarters, with the vertical axis representing the number of consumers in millions and the horizontal axis showing the quarterly progression over this two-year period.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# ask question over image!\n",
|
||||
"response = query_engine.query(\n",
|
||||
" \"What does the bar graph titled 'Monthly Active Platform Consumers' show?\"\n",
|
||||
")\n",
|
||||
"print(str(response))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "c4f14ad8-6bfd-49d9-b3d5-7215cf0e4ac1",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Based on the financial documents provided, I can identify some key risk factors for Uber, though the context is limited to specific pages:\n",
|
||||
"\n",
|
||||
"**Legal and Regulatory Risks:**\n",
|
||||
"- Driver classification issues pose significant business risks, as legal determinations about whether drivers are employees or independent contractors could substantially impact Uber's operations and cost structure.\n",
|
||||
"\n",
|
||||
"**Operational Risks:**\n",
|
||||
"- The company continues to report net losses, indicating ongoing profitability challenges across its business segments.\n",
|
||||
"\n",
|
||||
"**Business Model Risks:**\n",
|
||||
"- Uber operates across multiple segments (Mobility, Delivery, and Freight), which creates exposure to various market conditions and regulatory environments in different industries.\n",
|
||||
"\n",
|
||||
"**Geographic Concentration Risk:**\n",
|
||||
"- The company has operations across different geographic regions, which exposes it to varying regulatory frameworks, economic conditions, and competitive landscapes in different markets.\n",
|
||||
"\n",
|
||||
"However, the provided context appears to be from specific pages of financial reports that focus primarily on financial metrics and segment information. A complete assessment of Uber's risk factors would typically be found in the dedicated risk factors section of their SEC filings, which is not included in the available context.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# ask question over text!\n",
|
||||
"response = query_engine.query(\"What are the main risk factors for Uber?\")\n",
|
||||
"print(str(response))"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": ".venv",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
@@ -0,0 +1,583 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "d27f1082-cd10-405e-9570-6f0e934bba8b",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# LlamaParse `JobResult` Tour\n",
|
||||
"\n",
|
||||
"<a href=\"https://colab.research.google.com/github/run-llama/llama_cloud_services/blob/main/examples/demo_json.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>\n",
|
||||
"\n",
|
||||
"The `JobResult` object is the main object returned by the LlamaParse API. It contains all the information about the job, including the parsed data, metadata, and any errors.\n",
|
||||
"\n",
|
||||
"This notebook walks through each component of the `JobResult` object and shows you what it contains.\n",
|
||||
"\n",
|
||||
"Status:\n",
|
||||
"| Last Executed | Version | State |\n",
|
||||
"|---------------|---------|------------|\n",
|
||||
"| Aug-19-2025 | 0.6.61 | Maintained |"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "a004db48-8d3f-421c-915a-477692f71b90",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Setup\n",
|
||||
"\n",
|
||||
"Let's bring in our imports and set up our API keys."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "bc6a7a4b-b568-4db5-bcba-62f5c517ff3a",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%pip install llama-cloud-services"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "0879301c-ff91-4431-941a-6c0ef7cd8fe2",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"\n",
|
||||
"# API access to llama-cloud\n",
|
||||
"os.environ[\"LLAMA_CLOUD_API_KEY\"] = \"llx-..\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "b411d2ee-3e6b-45b0-b532-4a8e3abcdea0",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Load Data\n",
|
||||
"\n",
|
||||
"Let's load a large and complex PDF, San Francisco's 2023 proposed budget."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "c39d408f-e885-4940-85c7-b09ca3bc7cb7",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!wget 'https://www.dropbox.com/scl/fi/vip161t63s56vd94neqlt/2023-CSF_Proposed_Budget_Book_June_2023_Master_Web.pdf?rlkey=hemoce3w1jsuf6s2bz87g549i&dl=0' -O './san_francisco_budget_2023.pdf'"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "c2f42af8-afb3-4b3b-82d3-6b332fb38aa4",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Using LlamaParse for Basic PDF Parsing\n",
|
||||
"\n",
|
||||
"Let's parse our document!"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "9c9cd670-8229-4ad6-99a9-845bd82b7ec1",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Started parsing the file under job_id d12d419a-52fc-400c-9f88-f61b352d3fb2\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from llama_cloud_services import LlamaParse\n",
|
||||
"\n",
|
||||
"parser = LlamaParse(\n",
|
||||
" parse_mode=\"parse_page_with_agent\",\n",
|
||||
" model=\"openai-gpt-4-1-mini\",\n",
|
||||
" high_res_ocr=True,\n",
|
||||
" adaptive_long_table=True,\n",
|
||||
" outlined_table_extraction=True,\n",
|
||||
" output_tables_as_HTML=True,\n",
|
||||
")\n",
|
||||
"result = await parser.aparse(\"./san_francisco_budget_2023.pdf\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "11c22bab",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Every job will come back with some metadata about the job:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "c588c578",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"JobMetadata(job_credits_usage=0, job_pages=0, job_auto_mode_triggered_pages=0, job_is_cache_hit=True)"
|
||||
]
|
||||
},
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"result.job_metadata"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "1e96b7c9",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Since this was a re-run, I can see that a cache hit occurred. Jobs are cached for 48 hours by default."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "6543d2c6",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Beyond this, we can explore the parsed data per-page:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "af9f3717",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"362\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(len(result.pages))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "f8845fac",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"dict_keys(['page', 'text', 'md', 'images', 'charts', 'tables', 'layout', 'items', 'status', 'links', 'width', 'height', 'triggeredAutoMode', 'parsingMode', 'structuredData', 'noStructuredContent', 'noTextContent'])\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(result.pages[0].model_dump().keys())"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "6261f5e3",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Inside the page object, you can see nearly every detail about the page.\n",
|
||||
"\n",
|
||||
"Most of these will depend on the settings you used when parsing. Since we used the default settings, we get the text and markdown for each page, as well as a list of all the elements on the page.\n",
|
||||
"\n",
|
||||
"* `page`: this is simply the page number, starting at 1.\n",
|
||||
"* `text`: this is the text of the page, as extracted by the parser.\n",
|
||||
"* `images`: this is an array of all the images on the page, including metadata and text OCRed out of the images, as well as a full-page screenshot of the entire page.\n",
|
||||
"* `charts`: this is an array of all the charts on the page, including metadata and text OCRed out of the charts, as well as a full-page screenshot of the entire chart.\n",
|
||||
"* `layout`: this is an array of all the layout elements on the page, if you are using layout mode.\n",
|
||||
"* `items`: This is an array of all the parsed elements on the page, as used to render the markdown, but separated out into their own objects. This is useful if you want to do more processing on the data.\n",
|
||||
"* `links`: this is an array of all the links on the page, if you are used `annotate_links=True`\n",
|
||||
"* `status`: this is the status of the page, which is usually \"OK\" unless there was an error processing the page.\n",
|
||||
"* `width` and `height`: these are the dimensions of the page in pixels.\n",
|
||||
"* `parsingMode`: Contains the specific parsing mode that was used for the page.\n",
|
||||
"* `triggeredAutoMode`: this indicates whether the page triggered auto mode; see [LlamaParse docs](https://docs.cloud.llamaindex.ai/llamaparse/getting_started) for more details.\n",
|
||||
"* `structuredData`/`noStructuredContent`: these are set if you are using structured mode; see [LlamaParse docs](https://docs.cloud.llamaindex.ai/llamaparse/getting_started) for more details.\n",
|
||||
"* `noTextContent`: this is true if the page was empty of text.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "7a4cc901",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
" CITY & COUNTY OF SAN FRANCISCO, CALIFORNIA\n",
|
||||
" PROPOSED BUDGET\n",
|
||||
" FISCAL YEARS 2023-2024 & 2024-2025\n",
|
||||
" LONDON N. BREED\n",
|
||||
" MAYOR’S OFFICE OF PUBLIC POLICY AND FINANCE\n",
|
||||
" Anna Duning, Director of Mayor’s Fisher Zhu, Fiscal and Policy Analyst\n",
|
||||
" Office of Public Policy and Finance Anya Shutovska, Fiscal and Policy Analyst\n",
|
||||
" Sally Ma, Deputy Budget Director\n",
|
||||
"Radhika Mehlotra, Senior Fiscal and Policy Analyst Jack English, Fiscal and Policy Analyst\n",
|
||||
" Damon Daniels, Fiscal and Policy Analyst Xang Hang, Junior Fiscal and Policy Analyst\n",
|
||||
" Matthew Puckett, Fiscal and Policy Analyst Tabitha Romero-Bothi, Fiscal and Policy Assistant\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(result.pages[0].text[:1000])"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "2d5a5bc2",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"# CITY & COUNTY OF SAN FRANCISCO, CALIFORNIA\n",
|
||||
"\n",
|
||||
"# PROPOSED BUDGET\n",
|
||||
"\n",
|
||||
"# FISCAL YEARS 2023-2024 & 2024-2025\n",
|
||||
"\n",
|
||||
"# LONDON N. BREED\n",
|
||||
"\n",
|
||||
"# MAYOR’S OFFICE OF PUBLIC POLICY AND FINANCE\n",
|
||||
"\n",
|
||||
"Anna Duning, Director of Mayor’s Office of Public Policy and Finance\n",
|
||||
"\n",
|
||||
"Fisher Zhu, Fiscal and Policy Analyst\n",
|
||||
"\n",
|
||||
"Anya Shutovska, Fiscal and Policy Analyst\n",
|
||||
"\n",
|
||||
"Sally Ma, Deputy Budget Director\n",
|
||||
"\n",
|
||||
"Radhika Mehlotra, Senior Fiscal and Policy Analyst\n",
|
||||
"\n",
|
||||
"Jack English, Fiscal and Policy Analyst\n",
|
||||
"\n",
|
||||
"Damon Daniels, Fiscal and Policy Analyst\n",
|
||||
"\n",
|
||||
"Xang Hang, Junior Fiscal and Policy Analyst\n",
|
||||
"\n",
|
||||
"Matthew Puckett, Fiscal and Policy Analyst\n",
|
||||
"\n",
|
||||
"Tabitha Romero-Bothi, Fiscal and Policy Assistant\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(result.pages[0].md[:1000])"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "32de4c62",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Images\n",
|
||||
"\n",
|
||||
"By default, images embedded in documents that can be extracted are part of the result object."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "802d4a98",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"We can also specify to take screenshots of every page:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "2ee78f2f",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Started parsing the file under job_id e6332422-803b-404d-8d0d-ad510fa56c09\n",
|
||||
"..."
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"parser = LlamaParse(\n",
|
||||
" parse_mode=\"parse_page_with_agent\",\n",
|
||||
" model=\"openai-gpt-4-1-mini\",\n",
|
||||
" high_res_ocr=True,\n",
|
||||
" adaptive_long_table=True,\n",
|
||||
" outlined_table_extraction=True,\n",
|
||||
" output_tables_as_HTML=True,\n",
|
||||
" # Take screenshot of the page\n",
|
||||
" take_screenshot=True,\n",
|
||||
")\n",
|
||||
"result = await parser.aparse(\"./san_francisco_budget_2023.pdf\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "fab32886",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"[ImageItem(name='page_1.jpg', height=792.0, width=612.0, x=0.0, y=0.0, original_width=1236, original_height=1600, type='full_page_screenshot')]\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(result.pages[0].images)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "9eba9e52",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"We can download images (either their bytes or to a local file) using the `JobResult` object as well!"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "a7aa0a29",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# single image\n",
|
||||
"image_data = await result.aget_image_data(result.pages[0].images[0].name)\n",
|
||||
"\n",
|
||||
"# save an image to a file\n",
|
||||
"output_path = await result.asave_image(\n",
|
||||
" result.pages[0].images[0].name, \"./json_tour_screenshots\"\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"# save all images\n",
|
||||
"output_paths = await result.asave_all_images(\"./json_tour_screenshots\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "eae4ece3",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Items\n",
|
||||
"\n",
|
||||
"This is an array of all the parsed elements on the page, as used to render the markdown, but separated out into their own objects. This is useful if you want to do more processing on the data. Let's take a look:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "c10b9d7d",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"type='heading' lvl=1 value='CITY & COUNTY OF SAN FRANCISCO, CALIFORNIA' md='# CITY & COUNTY OF SAN FRANCISCO, CALIFORNIA' rows=None bBox=BBox(x=176.0, y=52.0, w=277.0, h=12.0)\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"import json\n",
|
||||
"\n",
|
||||
"print(result.pages[0].items[0])"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "dcb9f832",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"type='heading' lvl=1 value='PROPOSED BUDGET' md='# PROPOSED BUDGET' rows=None bBox=BBox(x=89.0, y=118.0, w=451.0, h=47.0)\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(result.pages[0].items[1])"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "a7f64443",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"As you can see you get different element types: text, headings, and tables. Each comes with its own `md` key containing a Markdown representation of that element, allowing you to easily summarize with only headings, tables only, etc..\n",
|
||||
"\n",
|
||||
"The ability to extract tables from visual data is really powerful. Let's take a look at page 35, which has some bar charts that get automatically converted into tables:\n",
|
||||
"\n",
|
||||
"<img src=\"./json_tour_screenshots/page_35.png\" alt=\"Page 35\" width=\"300\"/>\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "e4ccee76",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"The bar chart has been converted into a table, and even though explicit values are not included, the bar chart has been read and approximate values for each bar on the chart have been included!"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "7d6404a5",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"type='table' lvl=None value=None md=\"Source: U.S. Census Bureau, 2017-2021 American Community Survey 5-years Estimate.\\n|Race|Educational Level|Number of Residents| | | | |\\n|---|---|---|---|---|---|---|\\n|Age Group| | | | | | |\\n|Under 5 Years|5 to 19 Years|20 to 34 Years|35 to 59 Years|60 and Over| | |\\n|Graduate or professional degree|Bachelor's degree|Associate's degree|Some college, no degree|High school graduate (includes equivalency)|9th to 12th grade, no diploma|Less than 9th grade|\" rows=[[], ['Race', 'Educational Level', 'Number of Residents', '', '', '', ''], ['---', '---', '---', '---', '---', '---', '---'], ['Age Group', '', '', '', '', '', ''], ['Under 5 Years', '5 to 19 Years', '20 to 34 Years', '35 to 59 Years', '60 and Over', '', ''], ['Graduate or professional degree', \"Bachelor's degree\", \"Associate's degree\", 'Some college, no degree', 'High school graduate (includes equivalency)', '9th to 12th grade, no diploma', 'Less than 9th grade']] bBox=BBox(x=68.0, y=129.0, w=613.0, h=3067.0)\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(result.pages[34].items[6])"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "9570d3b8",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### `links`\n",
|
||||
"\n",
|
||||
"Our budget PDF doesn't have any links, so let's load a different PDF with links and see what we get.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "fb0da11a",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!wget 'https://www.dropbox.com/scl/fi/hay06lyxc49gkuh91oek6/basic-link-1.pdf?rlkey=uije7yb0lxqgqwk7p7hnqepdx&dl=0' -O './basic-link-1.pdf'"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "e7e393e6",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Started parsing the file under job_id 9b2df975-af3c-4868-99e2-520ce0b21f4d\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"parser = LlamaParse(\n",
|
||||
" parse_mode=\"parse_page_with_agent\",\n",
|
||||
" model=\"openai-gpt-4-1-mini\",\n",
|
||||
" high_res_ocr=True,\n",
|
||||
" adaptive_long_table=True,\n",
|
||||
" outlined_table_extraction=True,\n",
|
||||
" output_tables_as_HTML=True,\n",
|
||||
" # Annotate links in the document\n",
|
||||
" annotate_links=True,\n",
|
||||
")\n",
|
||||
"result = await parser.aparse(\"./basic-link-1.pdf\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "701ada4b",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"This is a very simple document with some internal and external links:\n",
|
||||
"\n",
|
||||
"<img src=\"./json_tour_screenshots/links_page.png\" alt=\"Page 1\" width=\"300\"/>\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "2e4de7de",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"The parser finds the external links and their labels and includes them in the `links` section:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "29bf7e3c",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"[{'url': 'https://www.antennahouse.com/', 'text': 'Antenna House, Inc.'}, {'url': 'https://www.antennahouse.com/', 'text': 'Linking to a website (https://www.antennahouse.com/)'}]\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(result.pages[0].links)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "ac9088a2",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"This concludes our tour! I hope this makes clear the power of JSON mode and the flexibility it gives you over what parts of your documents you can use."
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "llama-parse-aNC435Vv-py3.10",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
@@ -0,0 +1,505 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "28d15ea5-a3eb-4ee5-9d91-8dbd95e53129",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Multi-Language Support in LlamaParse\n",
|
||||
"\n",
|
||||
"LlamaParse supports users to specify a `language` parameter before uploading documents, giving users better OCR capabilities over non-English PDFs, parsing images into more accurate representations.\n",
|
||||
"\n",
|
||||
"You can specify 80+ different languages: see this file for a full list of supported languages: https://github.com/run-llama/llama_cloud_services/blob/main/llama_parse/base.py.\n",
|
||||
"\n",
|
||||
"This notebook shows a demo of this in action. \n",
|
||||
"\n",
|
||||
"Status:\n",
|
||||
"| Last Executed | Version | State |\n",
|
||||
"|---------------|---------|------------|\n",
|
||||
"| Aug-19-2025 | 0.6.61 | Maintained |"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "15539193-2f5c-4ecf-9ca4-9aee6f888468",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%pip install llama-cloud-services"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "87322210-c21c-43d6-b459-2e8a828ac576",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"\n",
|
||||
"os.environ[\"LLAMA_CLOUD_API_KEY\"] = \"llx-...\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "2b5cabdf-342a-42d2-8ad4-0ba7c46cdfb9",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Load in a French PDF\n",
|
||||
"\n",
|
||||
"We load in the 2022 annual report from Agence France Tresor."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "e81e0a08-3a99-42e6-adcc-00bb4ce1c3d4",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!wget \"https://www.dropbox.com/scl/fi/fxg17log5ydwoflhxmgrb/treasury_report.pdf?rlkey=mdintk0o2uuzkple26vc4v6fd&dl=1\" -O treasury_report.pdf"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "ecfc578c-3c7f-4ec1-aa06-51565c28632b",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Started parsing the file under job_id e1efd750-ed1f-4aaa-8a46-ed07b2ad6f52\n",
|
||||
"..."
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from llama_cloud_services import LlamaParse\n",
|
||||
"\n",
|
||||
"parser = LlamaParse(\n",
|
||||
" parse_mode=\"parse_page_with_agent\",\n",
|
||||
" model=\"openai-gpt-4-1-mini\",\n",
|
||||
" high_res_ocr=True,\n",
|
||||
" adaptive_long_table=True,\n",
|
||||
" outlined_table_extraction=True,\n",
|
||||
" output_tables_as_HTML=True,\n",
|
||||
" # Set the language to French!\n",
|
||||
" language=\"fr\",\n",
|
||||
")\n",
|
||||
"result = await parser.aparse(\"./treasury_report.pdf\")\n",
|
||||
"documents = result.get_text_documents(split_by_page=False)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "0c37db27-3496-4a59-918b-701c9ad7706d",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"TIVITÉ DE L’AFT\n",
|
||||
" P.84 RAPPORT STATISTIQUE\n",
|
||||
"\n",
|
||||
" FICHES TECHNIQUES GLOSSAIRES LISTE DES ABRÉVIATIONS\n",
|
||||
" P.106 P.118 P.122\n",
|
||||
"\n",
|
||||
" AGENCE FRANCE TRÉSOR - RAPPORT D’ACTIVITÉ 2022 3\n",
|
||||
"---\n",
|
||||
" Édito\n",
|
||||
"\n",
|
||||
"\n",
|
||||
" Avec une croissance\n",
|
||||
" de +2,5 %, la France a illustré\n",
|
||||
" une nouvelle fois sa résilience\n",
|
||||
" économique face aux chocs.\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"4 AGENCE FRANCE TRÉSOR - RAPPORT D’ACTIVITÉ 2022\n",
|
||||
"---\n",
|
||||
" L’économie française en 2022 :\n",
|
||||
"résilience face aux chocs géopolitiques\n",
|
||||
" et économiques\n",
|
||||
"\n",
|
||||
"\n",
|
||||
" LE DÉBUT DE sa résilience économique face aux lors du dernier trimestre de 2022.\n",
|
||||
" L’ANNÉE 2022 chocs. Cette croissance a été permise Malgré un climat des affaires impacté\n",
|
||||
" grâce à une forte demande intérieure par l’inflation, le soutien apporté\n",
|
||||
" SEMBLAIT alimentée par le dynamisme de aux TPE/PME leur a permis de faire\n",
|
||||
" l’investissement et, en dépit de face aux défis énergétiques tout en\n",
|
||||
" ENGAGÉ DANS l’inflation, d’une résilience de la préservant l’emploi.\n",
|
||||
" consommation des ménages sur une\n",
|
||||
" UNE DYNAMIQUE grande partie de l’année. Afin de combattre l’inflation qui a\n",
|
||||
" largement dépassé la cible de 2 %,\n",
|
||||
" EFFICACE DE Le taux d’inflation des prix à la la BCE, de concert avec les banques\n",
|
||||
" SORTIE DE CRISE consommation français est resté l’un centrales des principales économies\n",
|
||||
" des plus bas d’Europe avec +6,0 % développées, a adapté sa fonction de\n",
|
||||
" PORTÉE PAR en 2022, s’appuyant, d’une part, sur réaction en mettant fin aux politiques\n",
|
||||
" l’atout structurel que représente un d’assouplissement monétaire qu’elle\n",
|
||||
" UNE REPRISE mix énergétique parmi les moins menait depuis la crise financière de\n",
|
||||
" exposés à la Russie et, d’autre part, 2008. Ainsi, dès juillet 2022, et pour\n",
|
||||
" ÉCONOMIQUE sur les politiques proactives du la première fois en 10 ans, la BCE a\n",
|
||||
" INÉDITE gouvernement avec la mise en place augmenté ses taux directeurs. Les\n",
|
||||
" du bouclier tarifaire, de la remise taux d’emprunts de l’État à 10 ans se\n",
|
||||
" AMORCÉE carburant et du chèque énergie. sont ainsi progressivement éloignés\n",
|
||||
" Ces dispositifs, temporaires, ont de leur territoire négatif pour\n",
|
||||
" EN 2021. été progressivement supprimés : la atteindre 3,10 % en fin d’année.\n",
|
||||
" remise carburant, d’abord prolongée\n",
|
||||
" jusqu’à mi-novembre a pris fin Cette décision s’est également\n",
|
||||
" Le déclenchement de la guerre en en décembre 2022, tandis que le a c c o m p a g n é e d e l a f i n d u\n",
|
||||
" Ukraine par la Russie dès février a chèque énergie exceptionnel a pris programme d’achat d’urgence (PEPP)\n",
|
||||
" rebattu les cartes de cet équilibre, fin en mars 2023. mis en place pendant la pandémie,\n",
|
||||
" provoquant des bouleversements suivi de la réduction progressive de\n",
|
||||
" majeurs sur les plans géopolitiques et Le marché du travail français a par son bilan, à un rythme mensuel de 15\n",
|
||||
" économiques, avec le déploiement ailleurs montré toute sa robustesse, milliards d’euros par mois.\n",
|
||||
" de sanctions à l’encontre de la Russie la dynamique de reprise initiée en L’Agence France Trésor a fait face à ce\n",
|
||||
" et une forte poussée inflationniste. 2021 ainsi que l’effet des réformes contexte de grands bouleversements\n",
|
||||
" Face à cette situation, les principales structurelles engagées les années géopolitiques, économiques et\n",
|
||||
" banques centrales mondiales, dont précédentes permettant au taux financiers en s’appuyant sur ses\n",
|
||||
" la Banque centrale européenne d’emploi des Français âgés de 15 à 64 principes de régularité, de prévisibilité\n",
|
||||
" (BCE), ont engagé une politique de ans d’atteindre fin 2022 un niveau et de transparence. Cette stratégie\n",
|
||||
" normalisation monétaire rapide de 68,1 %, un record depuis 1975. s’est de nouveau révélée robuste et,\n",
|
||||
" pour lutter contre l’inflation. La reprise économique de début alliée à l’engagement et à l’efficacité\n",
|
||||
" Parallèlement, le gouvernement d’année et les effets positifs du plan de ses équipes, ainsi qu’à la qualité\n",
|
||||
" français a mis en place des mesures France Relance ont permis la création de crédit de la signature de la France,\n",
|
||||
" (à hauteur de 43,6 milliards d’euros de 337 100 emplois, essentiellement lui a permis d’accomplir sa mission\n",
|
||||
" sur l’année 2022) pour protéger les dans le secteur salarié marchand. Ce de financement de l’action publique\n",
|
||||
" entreprises et les ménages. dynamisme a aussi conduit à la chute au bénéfice de tous.\n",
|
||||
" du taux de chômage, atteignant son\n",
|
||||
" Avec une croissance de +2,5 %, la niveau le plus bas depuis mars 2008\n",
|
||||
" France a illustré une nouvelle fois avec 7,2 % de demandeurs d’emploi\n",
|
||||
" Emmanuel Moulin\n",
|
||||
" DIRECTEUR GÉNÉRAL DU TRÉSOR\n",
|
||||
" ET PRÉSIDENT DE L’AFT\n",
|
||||
"\n",
|
||||
"\n",
|
||||
" AGENCE FRANCE TRÉSOR - RAPPORT D’ACTIVITÉ 2022 5\n",
|
||||
"---\n",
|
||||
" Le mot\n",
|
||||
" du directeur général\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"En 2022, le choc d’inflation\n",
|
||||
" et la normalisation\n",
|
||||
" de la politique monétaire\n",
|
||||
"ont mis fin à une décennie\n",
|
||||
" de taux historiquement bas.\n",
|
||||
"\n",
|
||||
"\n",
|
||||
" 6 AGENCE FRANCE TRÉSOR - RAPPORT D’ACTIVITÉ 2022\n",
|
||||
"---\n",
|
||||
" MALGRÉ UN CONTEXTE DE MARCHÉ MOUVEMENTÉ ET LES MESURES D’AMPLEUR\n",
|
||||
" PRISES POUR LIMITER L’IMPACT DE L’INFLATION SUR LES MÉNAGES ET\n",
|
||||
" LES ENTREPRISES, LE PROGRAMME DE FINANCEMENT À MOYEN ET LONG TERME\n",
|
||||
" EST DEMEURÉ INCHANGÉ À 260 MILLIARDS D’EUROS, STABLE PAR RAPPORT\n",
|
||||
" À 2021, ET LA DETTE DE COURT TERME A ÉTÉ RÉDUITE DE 7 MILLIARDS D’EUROS.\n",
|
||||
"\n",
|
||||
"En janvier 2022, la normalisation de d’obligations indexées sur l’inflation, la dette de court terme a été réduite\n",
|
||||
"la politique monétaire en zone euro sur lequel a été enregistré un de 7 milliards d’euros. En effet, le\n",
|
||||
"était une perspective de moyen supplément d’indexation supérieur dynamisme des recettes fiscales et\n",
|
||||
"terme. Quelques semaines plus tard, de 17 milliards d’euros à celui de la trésorerie levée lors de la crise\n",
|
||||
"l’invasion de l’Ukraine par la Russie l’année 2021. Il s’est également sanitaire ont permis d’absorber le\n",
|
||||
"déclenchait le processus qui allait traduit par une hausse de la demande coût de ces mesures.\n",
|
||||
"mettre fin à une décennie de taux pour ces produits, qui ont représenté\n",
|
||||
"monétaires nuls ou négatifs. Dès près de 10 % du programme de La mise en œuvre des engagements\n",
|
||||
"l’été, la Banque centrale européenne financement. Ceci a notamment pris les années précédentes a\n",
|
||||
"mettait un terme à ses achats nets permis l’émission par syndication, en également mobilisé les équipes\n",
|
||||
"d’actifs et entamait la remontée de janvier, d’une nouvelle OAT indexée de l’AFT en 2022, qui ont émis\n",
|
||||
"ses taux directeurs. Illustration de la sur l’inflation européenne d’une pour le compte de la CADES\n",
|
||||
"rapidité de cette normalisation, le maturité de 30 ans, l’OAT€i 0,10 % 38 milliards d’obligations sociales\n",
|
||||
"taux de rendement des obligations 25 juillet 2053, pour un volume en 2022, permettant à la CADES\n",
|
||||
"assimilables du Trésor (OAT) à 10 ans \n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(documents[0].get_content()[1000:10000])"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "be161577-7b1e-4710-b721-f549feb8e6d0",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Download Chinese PDF"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "ac332ea3-cfff-4216-b292-62410a26c336",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!wget \"https://www.dropbox.com/scl/fi/g5ojyzk4m44hl7neut6vc/chinese_pdf.pdf?rlkey=45reu51kjvdvic6zucr8v9sh3&dl=1\" -O chinese_pdf.pdf"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "45235b17-08f0-48f1-92aa-06711225860b",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Started parsing the file under job_id bf9e76e8-fa2b-447a-a483-8bda12135c31\n",
|
||||
"."
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from llama_cloud_services import LlamaParse\n",
|
||||
"\n",
|
||||
"parser = LlamaParse(\n",
|
||||
" parse_mode=\"parse_page_with_agent\",\n",
|
||||
" model=\"openai-gpt-4-1-mini\",\n",
|
||||
" high_res_ocr=True,\n",
|
||||
" adaptive_long_table=True,\n",
|
||||
" outlined_table_extraction=True,\n",
|
||||
" output_tables_as_HTML=True,\n",
|
||||
" # Set the language to Chinese!\n",
|
||||
" language=\"ch_sim\",\n",
|
||||
")\n",
|
||||
"result = await parser.aparse(\"./chinese_pdf.pdf\")\n",
|
||||
"documents = result.get_text_documents(split_by_page=False)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "f0d546cc-6549-4cf5-8b37-0896f4e8d43d",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
" 核心价值观\n",
|
||||
"\n",
|
||||
" 致力于实现国家外汇资金多元化投资,在可接受风险范围内 责任 合力\n",
|
||||
" 实现股东权益最大化,以服务于国家经济发展和深化金融体\n",
|
||||
" 忠于使命、\n",
|
||||
" 勤勉尽责 立足大局、\n",
|
||||
" 制改革的需要 有效协同\n",
|
||||
" 是公司遵奉的核心价值取向 是实现公司可持续发展的关键\n",
|
||||
"\n",
|
||||
" 愿景 专业 进取\n",
|
||||
"\n",
|
||||
" 坚持良好的专业精神和职业操守 求知进取、\n",
|
||||
" 追求卓越\n",
|
||||
" 成为受人尊重的国际一流主权财富基金 是公司成功的基石 是公司成功和发展壮大的内驱力\n",
|
||||
"---\n",
|
||||
"01\n",
|
||||
"\n",
|
||||
"\n",
|
||||
" 致辞 我们将一以贯之地践行全球发展倡议,\n",
|
||||
" 充分维护投资东道国利益,\n",
|
||||
" 积极投身可持续投资,\n",
|
||||
" 助力世界经济实现更高质量、\n",
|
||||
" 更有韧性的发展。\n",
|
||||
"\n",
|
||||
"\n",
|
||||
" 3 中国投资有限责任公司2022年度报告 中国投资有限责任公司2022年度报告 4\n",
|
||||
"---\n",
|
||||
"“行之力则知愈进,知之深则行愈达。”站在新的历史起点上,中投公司\n",
|
||||
"将继续秉承精益求精、追求卓越的专业精神,与国内外合作伙伴一起深化\n",
|
||||
"合作,共聚力量、共迎挑战、共享成果,开启打造世界一流主权财富基金\n",
|
||||
"的新篇章,为助力全球经济发展作出新贡献!\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"彭纯\n",
|
||||
"董事长\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"董事长致辞 2022年,是中投公司成立十五周年。\n",
|
||||
" 自2007年成立以来,中投公司坚守长期机构投资者定位,坚持国际化、市场化、专业化、负责任原则,搭\n",
|
||||
"\n",
|
||||
" 建起符合大型国际投资机构特点的治理架构,形成了系统完备的投资管理体系,经受住了国际金融危机、世纪\n",
|
||||
"\n",
|
||||
" 疫情等多个历史罕见的风险与挑战。如今,公司对外投资业务覆盖国际市场主要资产类别以及全球110多个国家\n",
|
||||
" 和地区,培养了一支高素质专业化的投资管理人才队伍,搭建了互利共赢的投资合作“朋友圈”,长期投资收\n",
|
||||
"\n",
|
||||
" 益超越董事会制定的考核目标,为促进国家外汇资产保值增值、服务国内国际双循环作出了积极贡献,在推动\n",
|
||||
"\n",
|
||||
" 全球投资合作、助力世界经济增长中贡献了中投力量,书写了中国主权财富基金不平凡的创业发展史。\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"5 中国投资有限责任公司2022年度报告 中国投资有限责任公司2022年度报告 6\n",
|
||||
"---\n",
|
||||
"2022年以来,全球地缘政治风险显著攀升,产业链供应链持续调整重构,美欧央行大幅加息,国际资本 我们守正创新,坚决践行双碳与可持续发展理念。更加包容、更加普惠、更有韧性的发展是全球\n",
|
||||
"\n",
|
||||
"市场剧烈震荡,MSCI全球股票指数、彭博全球债券指数一度自高点下跌超过22%、13%。面对风高浪急的国 可持续发展的关键。我们积极履行负责任投资者理念,制定《关于践行双碳目标和可持续投资行动的意见》,\n",
|
||||
"际环境和前所未有的巨大挑战,公司保持战略定力,发挥长期机构投资者优势,不断优化资产配置和投资策 积极开展气候变化、能源转型等主题投资。我们发布《运营碳中和行动计划》,明确时间表和路线图,全力实\n",
|
||||
"\n",
|
||||
"略,着力提升总组合韧性,加强重点领域风险防控,年度投资收益跑赢大市;截至2022年底,过去十年对外 现节能减排目标。我们探索以绿色资源引领乡村发展的新方法,在四个定点帮扶县持续推进巩固脱贫成果与乡\n",
|
||||
"投资年化净收益率按美元计算为6.43%,超出十年业绩目标26个基点;自成立以来累计年化国有资本增值率达 村振兴的有效衔接,助力民生保障与产业扶持,积极履行企业社会责任。\n",
|
||||
"到12.67%,圆满完成五年战略规划主要目标任务。\n",
|
||||
"\n",
|
||||
" 面向未来,我们坚信,发展与合作是破解全球性问题的“钥匙”。中投公司将一以贯之地践行全球发展倡\n",
|
||||
"我们矢志不渝,积极打造世界一流主权财富基金。长期资本对于促进世界经济持续发展有着不 议,秉持互利共赢理念,以资本为纽带,促进国际产业交流合作,推动世界互联互通;充分维护投资东道国利\n",
|
||||
"\n",
|
||||
"可替代的作用。我们坚持国际化、市场化、专业化、负责任原则,快速恢复常态化对外交流交往,按照互利共 益,与东道国共创价值、共享价值;积极投身可持续投资,推动被投企业履行社会责任,助力世界经济实现更\n",
|
||||
"\n",
|
||||
"赢原则深化与国内外各类机构合作,持续为世界经济发展提供长期资本支持。我们积极创新对外投资方式,稳 高质量、更有韧性的发展。\n",
|
||||
"\n",
|
||||
"健运行多支新型双边基金,新设相关投资合作平台,深入推进中国市场价值创造,促进被投资公司拓展市场空\n",
|
||||
"\n",
|
||||
"间,助推国际投资与产业合作高质量发展。 经济全球化的潮流不可阻挡。我们呼吁各国携起手来,做多边主义的坚定维护者,打造更加开放有序的投\n",
|
||||
"\n",
|
||||
" 资环境,便利资本和资源要素在全球顺畅流动。我们尊重各方的利益关切,在开放中捕捉投资机遇,以务实合\n",
|
||||
"我们直面挑战,着力加强自主投资能力建设。面对持续动荡的国际金融市场,我们锚定配置方 作应对共同挑战,并肩前进分享发展红利,推动世界经济平稳运行和持续增长。\n",
|
||||
"\n",
|
||||
"向,强化研究驱动,有序实施组合调整、策略优化,及时调整公开市场投资布局,质量并重推进非公开市场投\n",
|
||||
" 50% “ 行 之 力 则 知 愈 进 , 知 之 深 则 行 愈 达 。\n",
|
||||
"资,完成另类资产投资占比 的资产配置目标,对外投资总组合的韧性和质量不断提高。我们持续深化投资 ” 过去的十五年,\n",
|
||||
" 是中投人不惧挑战、\n",
|
||||
" 接续奋斗的十五\n",
|
||||
"管理体制机制改革,统一非公开市场投资决策制度流程,配强投资决策专职委员并设立支持团队,投资管理科 2023年是中投人落实新一轮战略规划的开局之年。\n",
|
||||
" 上半年,\n",
|
||||
" 在风高浪急的国际环境下,\n",
|
||||
" 年。 中投公司锚定战略目\n",
|
||||
"学化、专业化水平得到进一步提升。 标,\n",
|
||||
" 统筹好发展和安全,\n",
|
||||
" 取得了良好业绩,\n",
|
||||
" 实现了良好开局。\n",
|
||||
" 近期,\n",
|
||||
" 公司部分董事更换,\n",
|
||||
" 我们对离任董事在指导和支\n",
|
||||
"\n",
|
||||
" 持公司完善公司治理、\n",
|
||||
" 深化投资管理体制机制改革、\n",
|
||||
" 应对国际市场风险挑战等方面所作的贡献表示衷心感谢,\n",
|
||||
" 对新\n",
|
||||
"我们勇担使命,坚定走好中国特色金融发展之路。面对新征程新要求,我们坚持发挥“积极股 任董事表示热烈欢迎。\n",
|
||||
" 站在新的历史起点上,\n",
|
||||
" 中投公司将完整、\n",
|
||||
" 准确、\n",
|
||||
" 全面贯彻新发展理念,\n",
|
||||
" 积极助力构建新发展格\n",
|
||||
"东”作用,督促控参股金融企业优化产品服务、加大资源倾斜力度,全力支持稳经济稳增长。我们积极创新完 局,\n",
|
||||
" 牢牢把握高质量发展首要任务,\n",
|
||||
" 继续秉承精益求精、\n",
|
||||
" 追求卓越的专业精神,\n",
|
||||
" 与国内外合作伙伴一起深化合作,\n",
|
||||
" 共\n",
|
||||
"善“汇金模式”,推动优化国有金融资本布局,以市场化方式参与问题金融机构救助,助力金融市场稳定健康 聚力量、\n",
|
||||
" 共迎挑战、\n",
|
||||
" 共享成果,\n",
|
||||
" 开启打造世界一流主权财富基金的新篇章,\n",
|
||||
" 为助力全球经济发展作出新贡献!\n",
|
||||
"发展。我们主动适应新形势新要求,围绕国有金融资本管理体系建设等重大课题深入研究,压实派出董事自主\n",
|
||||
"\n",
|
||||
"履职责任,不断提升机构化履职能力。\n",
|
||||
"\n",
|
||||
"我们坚守底线,持续夯实全面风险管理体系。面对风高浪急的国际环境,我们优化风险管理委员\n",
|
||||
"\n",
|
||||
"会设置,修订全面风险管理基本制度,增加风险类别的覆盖度,全面提升风险预见、应对、处置水平。在对外投\n",
|
||||
"\n",
|
||||
"资方面,我们严守法律合规底线,健全地缘政治、气候变化等非传统风险防控机制,突出抓好流动性管理,对外\n",
|
||||
"\n",
|
||||
"投资总组合风险保持在董事会规定的容忍度内。在国有金融资本受托管理方面,我们建立健全控参股金融企业风\n",
|
||||
"\n",
|
||||
"险监测体系,全面开展多维度风险画像,推动控参股金融企业风险减存量、控增量、防变量取得积极成效。\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"7 中国投资有限责任公司2022年度报告 中国投资有限责任公司2022年度报告 8\n",
|
||||
"---\n",
|
||||
"02\n",
|
||||
"\n",
|
||||
"\n",
|
||||
" 公司介绍 中投公司的组建宗旨是实现国家外汇资金多元化投资,在可接受风\n",
|
||||
" 险范围内实现股东权益最大化,以服务于国家宏观经济发展和深化\n",
|
||||
" 金融体制改革的需要。\n",
|
||||
"\n",
|
||||
"\n",
|
||||
" 9 中国投资有限责任公司2022年度报告 中国投资有限责任公司2022年度报告 10\n",
|
||||
"---\n",
|
||||
"公司概况 公司治理\n",
|
||||
"\n",
|
||||
"\n",
|
||||
" 中国投资有限责任公司(以下简称“中投公司”)依照《中华人民共和国公司法》(以下简称“《公司 中投公司按照《公司法》及《中国投资有限责任公司章程》(以下简称“《中投公司章程》”)中的有关规\n",
|
||||
" 法》”)于2007年9月成立,总部设在北京。中投公司的初始资本金为2000亿美元,由中国财政部发行1.55万 定,设立了董事会、监事会和执行委员会(以下简称“执委会”),三者之间权责明确、独立履职、有效制衡。\n",
|
||||
" 亿元人民币特别国债募集。截至2022年底,公司总资产达1.24万亿美元。\n",
|
||||
" 2022年,中投公司健全完善董事会、监事会运行机制,强化下设专门委员会的职能发挥,持续提升公司治\n",
|
||||
" 中投公司的组建宗旨是实现国家外汇资金多元化投资,在可接受风险范围内实现股东权益最大化,以服务于 理效能。公司根据业务发展需要,优化调整投资管理架构,完善投资决策和投后管理制度机制,深化全面风险管\n",
|
||||
" 国家宏观经济发展和深化金融体制改革的需要。 理体系建设,全面提升机构化投资能力。\n",
|
||||
"\n",
|
||||
" 中投公司开展境外投资业务与境内金融机构股权管理工作。其中,境外投资业务由下设子公司⸺中投国际\n",
|
||||
" 有限责任公司(以下简称“中投国际”)和中投海外直接投资有限责任公司(以下简称“中投海外”)承担,业\n",
|
||||
" 务范围包括公开市场股票和债券投资,对冲基金和多资产,泛行业私募股权和私募信用投资,房地产、基础设 组织架构图\n",
|
||||
" 施、资源商品、农业等领域的基金投资与直接投资,以及多双边基金管理等。\n",
|
||||
"\n",
|
||||
" 中央汇金投资有限责任公司(以下简称“中央汇金”)作为中投公司的子公司,根据国务院授权,对国有重\n",
|
||||
" 点金融企业进行股权投资,以出资额为限代表国家依法对国有重点金融企业行使出资人权利和履行出资人义务。 董事会 监事会\n",
|
||||
" 中央汇金不开展商业性经营活动,不干预其控股的国有重点金融企业的日常经营活动。 提名与\n",
|
||||
" 薪酬委员会\n",
|
||||
"\n",
|
||||
" 中投国际和中投海外开展的境外业务与中央汇金开展的境内业务之间实行严格的“防火墙”政策和措施。\n",
|
||||
"\n",
|
||||
" 战略与\n",
|
||||
" 社会责任\n",
|
||||
" 委员会\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"风险管理 执行 国际咨询 监督 审计\n",
|
||||
"委员会 委员会 委员会 委员会 委员会\n",
|
||||
"\n",
|
||||
"\n",
|
||||
" 境外投资 管理与支持 境内股权\n",
|
||||
" 业务部门 部门 管理部门\n",
|
||||
"\n",
|
||||
"\n",
|
||||
" 11 中国投资有限责任公司2022年度报告 中国投资有限责任公司2022年度报告 12\n",
|
||||
"---\n",
|
||||
"董事会 沈如军\n",
|
||||
" 党委委员、\n",
|
||||
" 执行董事、\n",
|
||||
" 副总经理\n",
|
||||
"\n",
|
||||
" 中投公司董事会行使《公司法》和《中投公司章程》中规定的有限责任公司董事会的职权,主要包括:审核 1964年出生,管理学博士,高级会计师。历任中国工商银行计划财务部副总经理、\n",
|
||||
"和批准公司的发展战略、经营方针和投资计划;确定公司需向股东报告的重大事项;制定公司年度预决算方案; 北京市分行副行长、财务会计部总经理、山东省分行行长,交通银行执行董事、副\n",
|
||||
"任免公司高级管理人员;决定或授权批准设立内部管理机构等。 行长。现任本公司党委委员、执行董事、副总经理。\n",
|
||||
"\n",
|
||||
" 董事会由执行董事、非执行董事、独立董事以及职工董事构成。 丛亮\n",
|
||||
"\n",
|
||||
" 2022年,面对复杂严峻的国际经济形势,董事会加强对公司重大经营管理事项的指导和督促,及时听取投 非执行董事\n",
|
||||
"资形势、经营管理、风险防控等汇报,认真审议经营计划、财务预算和决算、业绩考核等重要议题,深入谋划中 1971年出生,经济学博士。历任国家发展和改革委员会国民经济综合司副司长、司\n",
|
||||
"投公司新一轮战略规划,明确发展目标、基本原则和重点举措,为公司下一阶段改革发展描绘新的蓝图。董事会 长,国家发展和改革委员会秘书长、新闻发言人,国家发展和改革委员会副主任,\n",
|
||||
"专门委员会根据授权,重点关注关系企业长远发展的重大事项,为董事会出谋划策,推动公司高质量发展迈上新 国家粮食和物资储备局局长。现任国家发展和改革委员会副主任,并兼任本公司非\n",
|
||||
"台\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(documents[0].get_content()[1000:10000])"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": ".venv",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
@@ -0,0 +1,411 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# LlamaParse With MongoDB\n",
|
||||
"\n",
|
||||
"<a href=\"https://colab.research.google.com/github/run-llama/llama_cloud_services/blob/main/examples/parse/demo_mongodb.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>\n",
|
||||
"\n",
|
||||
"In this notebook, we provide a straightforward example of using LlamaParse with MongoDB Atlas VectorSearch.\n",
|
||||
"\n",
|
||||
"We illustrate the process of using llama-parse to parse a PDF document, then index the document with a MongoDB vector store, and subsequently perform basic queries against this store.\n",
|
||||
"\n",
|
||||
"This notebook is structured similarly to quick start guides, aiming to introduce users to utilizing llama-parse in conjunction with a MongoDB Atlas VectorSearch.\n",
|
||||
"\n",
|
||||
"Status:\n",
|
||||
"| Last Executed | Version | State |\n",
|
||||
"|---------------|---------|------------|\n",
|
||||
"| Aug-19-2025 | 0.6.61 | Maintained |"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Installation"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%pip install llama-cloud-services\n",
|
||||
"%pip install \"llama-index-vector-stores-mongodb>=0.8.0<0.9.0\" \"llama-index>=0.13.0<0.14.0\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Setup API Keys"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"\n",
|
||||
"os.environ[\n",
|
||||
" \"LLAMA_CLOUD_API_KEY\"\n",
|
||||
"] = \"llx-...\" # Get it from https://cloud.llamaindex.ai/api-key\n",
|
||||
"os.environ[\n",
|
||||
" \"OPENAI_API_KEY\"\n",
|
||||
"] = \"sk-...\" # Get it from https://platform.openai.com/api-keys"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import requests\n",
|
||||
"import pymongo\n",
|
||||
"\n",
|
||||
"from llama_index.vector_stores.mongodb import MongoDBAtlasVectorSearch\n",
|
||||
"from llama_cloud_services import LlamaParse\n",
|
||||
"from llama_index.embeddings.openai import OpenAIEmbedding\n",
|
||||
"from llama_index.core import VectorStoreIndex, StorageContext\n",
|
||||
"from llama_index.core.node_parser import SentenceSplitter"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.core import Settings\n",
|
||||
"from llama_index.llms.openai import OpenAI\n",
|
||||
"from llama_index.embeddings.openai import OpenAIEmbedding\n",
|
||||
"\n",
|
||||
"Settings.llm = OpenAI(model=\"gpt-5-mini\")\n",
|
||||
"Settings.embed_model = OpenAIEmbedding(model=\"text-embedding-3-small\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Download Document\n",
|
||||
"\n",
|
||||
"We will use `Attention is all you need` paper."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Download complete.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# The URL of the file you want to download\n",
|
||||
"url = \"https://arxiv.org/pdf/1706.03762.pdf\"\n",
|
||||
"# The local path where you want to save the file\n",
|
||||
"file_path = \"./attention.pdf\"\n",
|
||||
"\n",
|
||||
"# Perform the HTTP request\n",
|
||||
"response = requests.get(url)\n",
|
||||
"\n",
|
||||
"# Check if the request was successful\n",
|
||||
"if response.status_code == 200:\n",
|
||||
" # Open the file in binary write mode and save the content\n",
|
||||
" with open(file_path, \"wb\") as file:\n",
|
||||
" file.write(response.content)\n",
|
||||
" print(\"Download complete.\")\n",
|
||||
"else:\n",
|
||||
" print(\"Error downloading the file.\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Parse the document using `LlamaParse`."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Started parsing the file under job_id 993fa45f-f4ed-4d49-9032-794b3470305a\n",
|
||||
"."
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"result = await LlamaParse(\n",
|
||||
" parse_mode=\"parse_page_with_agent\",\n",
|
||||
" model=\"openai-gpt-4-1-mini\",\n",
|
||||
" high_res_ocr=True,\n",
|
||||
" adaptive_long_table=True,\n",
|
||||
" outlined_table_extraction=True,\n",
|
||||
" output_tables_as_HTML=True,\n",
|
||||
").aparse(file_path)\n",
|
||||
"\n",
|
||||
"documents = result.get_text_documents(split_by_page=False)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
" sub-layer, which performs multi-head\n",
|
||||
"attention over the output of the encoder stack. Similar to the encoder, we employ residual connections\n",
|
||||
"around each of the sub-layers, followed by layer normalization. We also modify the self-attention\n",
|
||||
"sub-layer in the decoder stack to prevent positions from attending to subsequent positions. This\n",
|
||||
"masking, combined with fact that the output embeddings are offset by one position, ensures that the\n",
|
||||
"predictions for position i can depend only on the known outputs at positions less than i.\n",
|
||||
"\n",
|
||||
"3.2 Attention\n",
|
||||
"An attention function can be described as mapping a query and a set of key-value pairs to an output,\n",
|
||||
"where the query, keys, values, and output are all vectors. The output is computed as a weighted sum\n",
|
||||
"\n",
|
||||
" 3\n",
|
||||
"---\n",
|
||||
" Scaled Dot-Product Attention Multi-Head Attention\n",
|
||||
"\n",
|
||||
" Linear\n",
|
||||
" MatMul\n",
|
||||
"\n",
|
||||
" SoftMax \n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# Take a quick look at some of the parsed text from the document:\n",
|
||||
"print(documents[0].get_content()[10000:11000])"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Create `MongoDBAtlasVectorSearch`."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"mongo_uri = \"<mongodb_uri>\"\n",
|
||||
"\n",
|
||||
"mongodb_client = pymongo.MongoClient(mongo_uri)\n",
|
||||
"mongodb_vector_store = MongoDBAtlasVectorSearch(mongodb_client)\n",
|
||||
"\n",
|
||||
"mongodb_vector_store.create_vector_search_index(\n",
|
||||
" dimensions=1536, path=\"embedding\", similarity=\"cosine\"\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Create nodes."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"node_parser = SentenceSplitter()\n",
|
||||
"\n",
|
||||
"nodes = node_parser.get_nodes_from_documents(documents)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Create Index and Query Engine."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"storage_context = StorageContext.from_defaults(vector_store=mongodb_vector_store)\n",
|
||||
"\n",
|
||||
"index = VectorStoreIndex(\n",
|
||||
" nodes=nodes,\n",
|
||||
" storage_context=storage_context,\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"query_engine = index.as_query_engine(similarity_top_k=2)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Test Query"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\n",
|
||||
"***********New LlamaParse+ Basic Query Engine***********\n",
|
||||
"28.4 BLEU\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"query = \"What is BLEU score on the WMT 2014 English-to-German translation task?\"\n",
|
||||
"\n",
|
||||
"response = query_engine.query(query)\n",
|
||||
"print(\"\\n***********New LlamaParse+ Basic Query Engine***********\")\n",
|
||||
"print(response)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"For our big models,(described on the\n",
|
||||
"bottom line of table 3), step time was 1.0 seconds. The big models were trained for 300,000 steps\n",
|
||||
"(3.5 days).\n",
|
||||
"\n",
|
||||
"5.3 Optimizer\n",
|
||||
"\n",
|
||||
"We used the Adam optimizer [20] with β1 = 0.9, β2 = 0.98 and ϵ = 10−9. We varied the learning\n",
|
||||
"rate over the course of training, according to the formula:\n",
|
||||
"\n",
|
||||
" lrate = d−0.5 · min(step_num−0.5, step_num · warmup_steps−1.5) (3)\n",
|
||||
" model\n",
|
||||
"\n",
|
||||
"This corresponds to increasing the learning rate linearly for the first warmup_steps training steps,\n",
|
||||
"and decreasing it thereafter proportionally to the inverse square root of the step number. We used\n",
|
||||
"warmup_steps = 4000.\n",
|
||||
"\n",
|
||||
"5.4 Regularization\n",
|
||||
"\n",
|
||||
"We employ three types of regularization during training:\n",
|
||||
"\n",
|
||||
" 7\n",
|
||||
"---\n",
|
||||
"Table 2: The Transformer achieves better BLEU scores than previous state-of-the-art models on the\n",
|
||||
"English-to-German and English-to-French newstest2014 tests at a fraction of the training cost.\n",
|
||||
"\n",
|
||||
" Model BLEU Training Cost (FLOPs)\n",
|
||||
" EN-DE EN-FR EN-DE EN-FR\n",
|
||||
" ByteNet [18] 23.75\n",
|
||||
" Deep-Att + PosUnk [39] 39.2 1.0 · 1020\n",
|
||||
" GNMT + RL [38] 24.6 39.92 2.3 · 1019 1.4 · 1020\n",
|
||||
" ConvS2S [9] 25.16 40.46 9.6 · 1018 1.5 · 1020\n",
|
||||
" MoE [32] 26.03 40.56 2.0 · 1019 1.2 · 1020\n",
|
||||
" Deep-Att + PosUnk Ensemble [39] 40.4 8.0 · 1020\n",
|
||||
" GNMT + RL Ensemble [38] 26.30 41.16 1.8 · 1020 1.1 · 1021\n",
|
||||
" ConvS2S Ensemble [9] 26.36 41.29 7.7 · 1019 1.2 · 1021\n",
|
||||
" Transformer (base model) 27.3 38.1 3.3 · 1018\n",
|
||||
" Transformer (big) 28.4 41.8 2.3 · 1019\n",
|
||||
"\n",
|
||||
"Residual Dropout We apply dropout [33] to the output of each sub-layer, before it is added to the\n",
|
||||
"sub-layer input and normalized. In addition, we apply dropout to the sums of the embeddings and the\n",
|
||||
"positional encodings in both the encoder and decoder stacks. For the base model, we use a rate of\n",
|
||||
"Pdrop = 0.1.\n",
|
||||
"\n",
|
||||
"Label Smoothing During training, we employed label smoothing of value ϵls = 0.1 [36]. This\n",
|
||||
"hurts perplexity, as the model learns to be more unsure, but improves accuracy and BLEU score.\n",
|
||||
"\n",
|
||||
"6 Results\n",
|
||||
"\n",
|
||||
"6.1 Machine Translation\n",
|
||||
"\n",
|
||||
"On the WMT 2014 English-to-German translation task, the big transformer model (Transformer (big)\n",
|
||||
"in Table 2) outperforms the best previously reported models (including ensembles) by more than 2.0\n",
|
||||
"BLEU, establishing a new state-of-the-art BLEU score of 28.4. The configuration of this model is\n",
|
||||
"listed in the bottom line of Table 3. Training took 3.5 days on 8 P100 GPUs. Even our base model\n",
|
||||
"surpasses all previously published models and ensembles, at a fraction of the training cost of any of\n",
|
||||
"the competitive models.\n",
|
||||
"On the WMT 2014 English-to-French translation task, our big model achieves a BLEU score of 41.0,\n",
|
||||
"outperforming all of the previously published single models, at less than 1/4 the training cost of the\n",
|
||||
"previous state-of-the-art model. The Transformer (big) model trained for English-to-French used\n",
|
||||
"dropout rate Pdrop = 0.1, instead of 0.3.\n",
|
||||
"For the base models, we used a single model obtained by averaging the last 5 checkpoints, which\n",
|
||||
"were written at 10-minute intervals. For the big models, we averaged the last 20 checkpoints. We\n",
|
||||
"used beam search with a beam size of 4 and length penalty α = 0.6 [38].\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# Take a look at one of the source nodes from the response\n",
|
||||
"print(response.source_nodes[0].get_content())"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"provenance": []
|
||||
},
|
||||
"kernelspec": {
|
||||
"display_name": ".venv",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 0
|
||||
}
|
||||
@@ -0,0 +1,459 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "97c79c38-38a3-40f3-ba2e-250649347d63",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"<a href=\"https://colab.research.google.com/github/run-llama/llama_cloud_services/blob/main/examples/parse/demo_starter_multimodal.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "4e081457",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Multimodal Parsing using LlamaParse\n",
|
||||
"\n",
|
||||
"This cookbook shows you how to use LlamaParse to parse any document with the multimodal capabilities of Multi-Modal LLMs from Anthropic/ OpenAI.\n",
|
||||
"\n",
|
||||
"LlamaParse allows you to plug in external, multimodal model vendors for parsing - we handle the error correction, validation, and scalability/reliability for you.\n",
|
||||
"\n",
|
||||
"Status:\n",
|
||||
"| Last Executed | Version | State |\n",
|
||||
"|---------------|---------|------------|\n",
|
||||
"| Aug-19-2025 | 0.6.61 | Maintained |"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "qOdqBxCS51Ow",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Installation"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "H_Vqcylb50vm",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%pip install llama-cloud-services"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "15e60ecf-519c-41fc-911b-765adaf8bad4",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Setup\n",
|
||||
"\n",
|
||||
"Here we setup `LLAMA_CLOUD_API_KEY` for using `LlamaParse`."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "91a9e532-1454-40e0-bbf0-fd442c350121",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"\n",
|
||||
"# API access to llama-cloud\n",
|
||||
"os.environ[\"LLAMA_CLOUD_API_KEY\"] = \"llx-...\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "LGwBNPNotZRQ",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Download Data\n",
|
||||
"\n",
|
||||
"For this demonstration, we will use OpenAI's recent paper `Evaluation of OpenAI o1: Opportunities and Challenges of AGI`."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "IjtKDQRLrylI",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!wget \"https://arxiv.org/pdf/2409.18486\" -O \"o1.pdf\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "4e29a9d7-5bd9-4fb8-8ec1-4c128a748662",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Initialize LlamaParse\n",
|
||||
"\n",
|
||||
"Initialize LlamaParse in multimodal mode, and specify the vendor.\n",
|
||||
"\n",
|
||||
"**NOTE**: optionally you can specify the Anthropic/ OpenAI API key. If you choose to do so LlamaParse will only charge you 1 credit (0.3c) per page. \n",
|
||||
"\n",
|
||||
"\n",
|
||||
"Using your own API key may incur additional costs from your model provider and could result in failed pages or documents if you do not have sufficient usage limits."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "1b5d6da6",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### With anthropic-sonnet-4.0"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "f2e9d9cf-8189-4fcb-b34f-cde6cc0b59c8",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Started parsing the file under job_id fdbe857e-48d0-4024-ba06-bfead78c4a0c\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from llama_cloud_services import LlamaParse\n",
|
||||
"\n",
|
||||
"parser = LlamaParse(\n",
|
||||
" # Enable pure multimodal parsing\n",
|
||||
" parse_mode=\"parse_page_with_lvm\",\n",
|
||||
" vendor_multimodal_model_name=\"anthropic-sonnet-4.0\",\n",
|
||||
" # Pass in your own API key optionally\n",
|
||||
" # vendor_multimodal_api_key=\"fake\",\n",
|
||||
" target_pages=\"24\",\n",
|
||||
" high_res_ocr=True,\n",
|
||||
" adaptive_long_table=True,\n",
|
||||
" outlined_table_extraction=True,\n",
|
||||
" output_tables_as_HTML=True,\n",
|
||||
")\n",
|
||||
"result = await parser.aparse(\"o1.pdf\")\n",
|
||||
"sonnet_nodes = result.get_markdown_nodes(split_by_page=False)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "4f3c51b0-7878-48d7-9bc3-02b516500128",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### With GPT-4.1-mini\n",
|
||||
"\n",
|
||||
"For comparison, we will also parse the document using GPT-4.1-mini."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "6fc3f258-50ae-4988-b904-c105463a498f",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Started parsing the file under job_id faab19bf-0810-4437-a1ff-4f6ae36d6ce0\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from llama_cloud_services import LlamaParse\n",
|
||||
"\n",
|
||||
"parser_gpt4o = LlamaParse(\n",
|
||||
" # Enable pure multimodal parsing\n",
|
||||
" parse_mode=\"parse_page_with_lvm\",\n",
|
||||
" vendor_multimodal_model_name=\"openai-gpt-4-1-mini\",\n",
|
||||
" # Pass in your own API key optionally\n",
|
||||
" # vendor_multimodal_api_key=\"fake\",\n",
|
||||
" target_pages=\"24\",\n",
|
||||
" high_res_ocr=True,\n",
|
||||
" adaptive_long_table=True,\n",
|
||||
" outlined_table_extraction=True,\n",
|
||||
" output_tables_as_HTML=True,\n",
|
||||
")\n",
|
||||
"result = await parser_gpt4o.aparse(\"o1.pdf\")\n",
|
||||
"gpt_nodes = result.get_markdown_nodes(split_by_page=False)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "44c20f7a-2901-4dd0-b635-a4b33c5664c1",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### View Results\n",
|
||||
"\n",
|
||||
"Let's visualize the results along with the original document page."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "778698aa-da7e-4081-b3b5-0372f228536f",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"file_name: o1.pdf\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"<table>\n",
|
||||
"<thead>\n",
|
||||
"<tr>\n",
|
||||
"<th>Participant_ID</th>\n",
|
||||
"<th>clinical Description Reference</th>\n",
|
||||
"</tr>\n",
|
||||
"</thead>\n",
|
||||
"<tbody>\n",
|
||||
"<tr>\n",
|
||||
"<td>Attribute</td>\n",
|
||||
"<td>Value</td>\n",
|
||||
"<td rowspan=\"12\"><strong>Basic Personal Information:</strong> Subject 098_S_0896 is a 72.0-year-old Female who has completed 15 years of education. The ethnicity is Not Hisp/Latino and race is White. Marital status is Married. Initially diagnosed as AD, as of the date 2007-10-24, the final diagnosis was Dementia.<br><br><strong>Biomarker Measurements:</strong> The subject's genetic profile includes an ApoE4 status of 0.0...<br><br><strong>Cognitive and Neurofunctional Assessments:</strong> The Mini-Mental State Examination score stands at 29.0. The Clinical Dementia Rating, sum of boxes, is 1.0. ADAS 11 and 13 scores are 4.67 and 4.67 respectively, with a score of 1.0 in delayed word recall...<br><br><strong>Volumetric Data:</strong> Under MRI conditions at a field strength of 1.5 Tesla MRI Tesla, using Cross-Sectional FreeSurfer (FreeSurfer Version 4.3), the imaging data recorded includes ventricles volume at 54422.0, hippocampus volume at 6717.0, whole brain volume at 1147980.0, entorhinal cortex volume at 2782.0, fusiform gyrus volume at 19432.0, and middle temporal area volume at 24951.0. The intracranial volume measured is 1799580.0....</td>\n",
|
||||
"</tr>\n",
|
||||
"<tr>\n",
|
||||
"<td>Age</td>\n",
|
||||
"<td>72.0</td>\n",
|
||||
"</tr>\n",
|
||||
"<tr>\n",
|
||||
"<td>Sex</td>\n",
|
||||
"<td>Female</td>\n",
|
||||
"</tr>\n",
|
||||
"<tr>\n",
|
||||
"<td>Education</td>\n",
|
||||
"<td>15</td>\n",
|
||||
"</tr>\n",
|
||||
"<tr>\n",
|
||||
"<td>Race</td>\n",
|
||||
"<td>White</td>\n",
|
||||
"</tr>\n",
|
||||
"<tr>\n",
|
||||
"<td>DX_bl</td>\n",
|
||||
"<td>AD</td>\n",
|
||||
"</tr>\n",
|
||||
"<tr>\n",
|
||||
"<td>DX</td>\n",
|
||||
"<td>Dementia</td>\n",
|
||||
"</tr>\n",
|
||||
"<tr>\n",
|
||||
"<td>...</td>\n",
|
||||
"<td>...</td>\n",
|
||||
"</tr>\n",
|
||||
"<tr>\n",
|
||||
"<td>APOE4</td>\n",
|
||||
"<td>1.0</td>\n",
|
||||
"</tr>\n",
|
||||
"<tr>\n",
|
||||
"<td>TAU</td>\n",
|
||||
"<td>212.5</td>\n",
|
||||
"</tr>\n",
|
||||
"<tr>\n",
|
||||
"<td>...</td>\n",
|
||||
"<td>...</td>\n",
|
||||
"</tr>\n",
|
||||
"<tr>\n",
|
||||
"<td>MMSE</td>\n",
|
||||
"<td>29.0</td>\n",
|
||||
"</tr>\n",
|
||||
"<tr>\n",
|
||||
"<td>CDRSB</td>\n",
|
||||
"<td>0.0</td>\n",
|
||||
"</tr>\n",
|
||||
"<tr>\n",
|
||||
"<td>...</td>\n",
|
||||
"<td>...</td>\n",
|
||||
"</tr>\n",
|
||||
"<tr>\n",
|
||||
"<td>FLDSTRENG</td>\n",
|
||||
"<td>1.5 Tesla MRI</td>\n",
|
||||
"</tr>\n",
|
||||
"<tr>\n",
|
||||
"<td>Ventricles</td>\n",
|
||||
"<td>84509</td>\n",
|
||||
"</tr>\n",
|
||||
"<tr>\n",
|
||||
"<td>Hippocampus</td>\n",
|
||||
"<td>5319</td>\n",
|
||||
"</tr>\n",
|
||||
"<tr>\n",
|
||||
"<td>...</td>\n",
|
||||
"<td>...</td>\n",
|
||||
"</tr>\n",
|
||||
"</tbody>\n",
|
||||
"</table>\n",
|
||||
"\n",
|
||||
"Figure 2: An example of a patient table and its corresponding clinical description.\n",
|
||||
"\n",
|
||||
"skills. Mathematics, as a highly structured and logic-driven discipline, provides an ideal testing ground for evaluating this reasoning ability. To investigate o1-preview's performance, we designed a series of tests covering various difficulty levels. We begin with high school-level math competition problems in this section, followed by college-level mathematics problems in the next section, allowing us to observe the model's logical reasoning across varying levels of complexity.\n",
|
||||
"\n",
|
||||
"In this section, we selected two primary areas of mathematics: algebra and counting and probability in this section. We chose these two topics because of their heavy reliance on problem-solving skills and their frequent use in assessing logical and abstract thinking [46]. The dataset used in testing is from the MATH dataset [46]. The problems in the dataset cover a wide range of subjects, including Prealgebra, Intermediate Algebra, Algebra, Geometry, Counting and Probability, Number Theory, and Precalculus. Each problem is categorized based on difficulty, ranked from level 1 to 5, according to the Art of Problem Solving (AoPS). The dataset mainly comprises problems from various high school math competitions, including the American Mathematics Competitions (AMC) 10 and 12, as well as the American Invitational Mathematics Examination (AIME), and other similar contests. Each problem comes with detailed reference solutions, allowing for a comprehensive comparison of o1-preview's solutions.\n",
|
||||
"\n",
|
||||
"In addition to evaluating the final answers produced by o1-preview, our analysis delves into the step-by-step reasoning process of the o1-preview's solutions. By comparing o1-preview's solutions with the dataset's solutions, we assess its ability to engage in logical reasoning, handle abstract problem-solving tasks, and apply structured approaches to reach correct answers. This deeper analysis offers insights into o1-preview's overall reasoning capabilities, using mathematics as a reliable indicator for logical and structured thought processes.\n",
|
||||
"\n",
|
||||
"25\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# using Sonnet-4.0\n",
|
||||
"print(sonnet_nodes[0].get_content(metadata_mode=\"all\"))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "1511a30f-3efc-4142-9668-7dc056a24d0c",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"file_name: o1.pdf\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"<table>\n",
|
||||
"<thead>\n",
|
||||
"<tr>\n",
|
||||
"<th colspan=\"2\"><b>Participant_ID</b></th>\n",
|
||||
"<th rowspan=\"2\" style=\"background-color: #b0b0b0;\"><b>clinical Description Reference</b></th>\n",
|
||||
"</tr>\n",
|
||||
"</thead>\n",
|
||||
"<tbody>\n",
|
||||
"<tr>\n",
|
||||
"<td><b>Attribute</b></td>\n",
|
||||
"<td><b>Value</b></td>\n",
|
||||
"<td rowspan=\"17\" style=\"background-color: #d0d0d0; vertical-align: top;\">\n",
|
||||
"<b>Basic Personal Information:</b> Subject 098_S_0896 is a 72.0-year-old Female who has completed 15 years of education. The ethnicity is Not Hisp/Latino and race is White. Marital status is Married. Initially diagnosed as AD, as of the date 2007-10-24, the final diagnosis was Dementia.<br><br>\n",
|
||||
"<b>Biomarker Measurements:</b> The subject's genetic profile includes an ApoE4 status of 0.0…<br><br>\n",
|
||||
"<b>Cognitive and Neurofunctional Assessments:</b> The Mini-Mental State Examination score stands at 29.0. The Clinical Dementia Rating, sum of boxes, is 1.0. ADAS 11 and 13 scores are 4.67 and 4.67 respectively, with a score of 1.0 in delayed word recall…<br><br>\n",
|
||||
"<b>Volumetric Data:</b> Under MRI conditions at a field strength of 1.5 Tesla MRI Tesla, using Cross-Sectional FreeSurfer (FreeSurfer Version 4.3), the imaging data recorded includes ventricles volume at 54422.0, hippocampus volume at 6677.0, whole brain volume at 1147980.0, entorhinal cortex volume at 2782.0, fusiform gyrus volume at 19432.0, and middle temporal area volume at 24951.0. The intracranial volume measured is 1799580.0.… \n",
|
||||
"</td>\n",
|
||||
"</tr>\n",
|
||||
"<tr>\n",
|
||||
"<td rowspan=\"7\"><b>Basic Personal information</b></td>\n",
|
||||
"<td>Age</td>\n",
|
||||
"<td>72.0</td>\n",
|
||||
"</tr>\n",
|
||||
"<tr>\n",
|
||||
"<td>Sex</td>\n",
|
||||
"<td>Female</td>\n",
|
||||
"</tr>\n",
|
||||
"<tr>\n",
|
||||
"<td>Education</td>\n",
|
||||
"<td>15</td>\n",
|
||||
"</tr>\n",
|
||||
"<tr>\n",
|
||||
"<td>Race</td>\n",
|
||||
"<td>White</td>\n",
|
||||
"</tr>\n",
|
||||
"<tr>\n",
|
||||
"<td>DX_bl</td>\n",
|
||||
"<td>AD</td>\n",
|
||||
"</tr>\n",
|
||||
"<tr>\n",
|
||||
"<td>DX</td>\n",
|
||||
"<td>Dementia</td>\n",
|
||||
"</tr>\n",
|
||||
"<tr>\n",
|
||||
"<td>…</td>\n",
|
||||
"<td>…</td>\n",
|
||||
"</tr>\n",
|
||||
"<tr>\n",
|
||||
"<td rowspan=\"3\"><b>Biomarker measurements</b></td>\n",
|
||||
"<td>APOE4</td>\n",
|
||||
"<td>1.0</td>\n",
|
||||
"</tr>\n",
|
||||
"<tr>\n",
|
||||
"<td>TAU</td>\n",
|
||||
"<td>212.5</td>\n",
|
||||
"</tr>\n",
|
||||
"<tr>\n",
|
||||
"<td>…</td>\n",
|
||||
"<td>…</td>\n",
|
||||
"</tr>\n",
|
||||
"<tr>\n",
|
||||
"<td rowspan=\"3\"><b>Cognitive and neurofunctional Assessments</b></td>\n",
|
||||
"<td>MMSE</td>\n",
|
||||
"<td>29.0</td>\n",
|
||||
"</tr>\n",
|
||||
"<tr>\n",
|
||||
"<td>CDRSB</td>\n",
|
||||
"<td>0.0</td>\n",
|
||||
"</tr>\n",
|
||||
"<tr>\n",
|
||||
"<td>…</td>\n",
|
||||
"<td>…</td>\n",
|
||||
"</tr>\n",
|
||||
"<tr>\n",
|
||||
"<td rowspan=\"4\"><b>Volumetric data</b></td>\n",
|
||||
"<td>FLDSTRENG</td>\n",
|
||||
"<td>1.5 Tesla MRI</td>\n",
|
||||
"</tr>\n",
|
||||
"<tr>\n",
|
||||
"<td>Ventricles</td>\n",
|
||||
"<td>84599</td>\n",
|
||||
"</tr>\n",
|
||||
"<tr>\n",
|
||||
"<td>Hippocampus</td>\n",
|
||||
"<td>5319</td>\n",
|
||||
"</tr>\n",
|
||||
"<tr>\n",
|
||||
"<td>…</td>\n",
|
||||
"<td>…</td>\n",
|
||||
"</tr>\n",
|
||||
"</tbody>\n",
|
||||
"</table>\n",
|
||||
"\n",
|
||||
"Figure 2: An example of a patient table and its corresponding clinical description.\n",
|
||||
"\n",
|
||||
"skills. Mathematics, as a highly structured and logic-driven discipline, provides an ideal testing ground for evaluating this reasoning ability. To investigate o1-preview’s performance, we designed a series of tests covering various difficulty levels. We begin with high school-level math competition problems in this section, followed by college-level mathematics problems in the next section, allowing us to observe the model’s logical reasoning across varying levels of complexity.\n",
|
||||
"\n",
|
||||
"In this section, we selected two primary areas of mathematics: algebra and counting and probability in this section. We chose these two topics because of their heavy reliance on problem-solving skills and their frequent use in assessing logical and abstract thinking [46]. The dataset used in testing is from the MATH dataset [46]. The problems in the dataset cover a wide range of subjects, including Prealgebra, Intermediate Algebra, Algebra, Geometry, Counting and Probability, Number Theory, and Precalculus. Each problem is categorized based on difficulty, ranked from level 1 to 5, according to the Art of Problem Solving (AoPS). The dataset mainly comprises problems from various high school math competitions, including the American Mathematics Competitions (AMC) 10 and 12, as well as the American Invitational Mathematics Examination (AIME), and other similar contests. Each problem comes with detailed reference solutions, allowing for a comprehensive comparison of o1-preview’s solutions.\n",
|
||||
"\n",
|
||||
"In addition to evaluating the final answers produced by o1-preview, our analysis delves into the step-by-step reasoning process of the o1-preview’s solutions. By comparing o1-preview’s solutions with the dataset’s solutions, we assess its ability to engage in logical reasoning, handle abstract problem-solving tasks, and apply structured approaches to reach correct answers. This deeper analysis offers insights into o1-preview’s overall reasoning capabilities, using mathematics as a reliable indicator for logical and structured thought processes.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# using GPT-4o\n",
|
||||
"print(gpt_nodes[0].get_content(metadata_mode=\"all\"))"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"provenance": []
|
||||
},
|
||||
"kernelspec": {
|
||||
"display_name": ".venv",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
@@ -0,0 +1,180 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"<a href=\"https://colab.research.google.com/github/run-llama/llama_cloud_services/blob/main/examples/parse/demo_starter_parse_selected_pages.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Parse Selected Pages \n",
|
||||
"\n",
|
||||
"In this notebook we will demonstrate how to parse selected pages in a document using LlamaParse.\n",
|
||||
"\n",
|
||||
"Status:\n",
|
||||
"| Last Executed | Version | State |\n",
|
||||
"|---------------|---------|------------|\n",
|
||||
"| Aug-19-2025 | 0.6.61 | Maintained |"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Installation\n",
|
||||
"\n",
|
||||
"Here we install `llama-cloud-services` and use `LlamaParse` for parsing the document."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!pip install llama-cloud-services"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Set API Key"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"\n",
|
||||
"# API access to llama-cloud\n",
|
||||
"os.environ[\"LLAMA_CLOUD_API_KEY\"] = \"llx-...\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Download Data\n",
|
||||
"\n",
|
||||
"Here we download Uber 2021 10K SEC filings data for the demonstration."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!wget 'https://raw.githubusercontent.com/run-llama/llama_index/main/docs/docs/examples/data/10k/uber_2021.pdf' -O './uber_2021.pdf'"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Parse the PDF file in selected pages\n",
|
||||
"\n",
|
||||
"Here we will parse the PDF file in selected pages and get the text in `markdown` format."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Started parsing the file under job_id d9d7ecc9-766c-48c6-92a8-17432d34818a\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from llama_cloud_services import LlamaParse\n",
|
||||
"\n",
|
||||
"parser = LlamaParse(\n",
|
||||
" # target pages allows for a few formats: 1,2,3 or 1-3 or 1,3,5-7, etc.\n",
|
||||
" target_pages=\"0,1,2\",\n",
|
||||
" parse_mode=\"parse_page_with_agent\",\n",
|
||||
" model=\"openai-gpt-4-1-mini\",\n",
|
||||
" high_res_ocr=True,\n",
|
||||
" adaptive_long_table=True,\n",
|
||||
" outlined_table_extraction=True,\n",
|
||||
" output_tables_as_HTML=True,\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"results = await parser.aparse(\"./uber_2021.pdf\")\n",
|
||||
"documents = results.get_markdown_documents(split_by_page=True)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"'\\n# UNITED STATES \\n## SECURITIES AND EXCHANGE COMMISSION \\nWashington, D.C. 20549 \\n____________________________________________ \\n# FORM 10-K \\n____________________________________________ \\n\\n(Mark One) \\n\\n[x] **ANNUAL REPORT PURSUANT TO SECTION 13 OR 15(d) OF THE SECURITIES EXCHANGE ACT OF 1934** \\nFor the fiscal year ended December 31, 2021 \\nOR \\n[ ] **TRANSITION REPORT PURSUANT TO SECTION 13 OR 15(d) OF THE SECURITIES EXCHANGE ACT OF 1934** \\nFor the transition period from_____ to _____ \\nCommission File Number: 001-38902 \\n____________________________________________ \\n\\n# UBER TECHNOLOGIES, INC. \\n\\n(Exact name of registrant as specified in its charter) \\n____________________________________________ \\n\\nDelaware | 45-2647441 \\n(State or other jurisdiction of incorporation or organization) | (I.R.S. Employer Identification No.) \\n\\n1515 3rd Street \\nSan Francisco, California 94158 \\n(Address of principal executive offices, including zip code) \\n\\n(415) 612-8582 \\n(Registrant’s telephone number, including area code) \\n____________________________________________ \\n\\nSecurities registered pursuant to Section 12(b) of the Act: \\n\\n<table>\\n<thead>\\n<tr>\\n<th>Title of each class</th>\\n<th>Trading Symbol(s)</th>\\n<th>Name of each exchange on which registered</th>\\n</tr>\\n</thead>\\n<tbody>\\n<tr>\\n<td>Common Stock, par value $0.00001 per share</td>\\n<td>UBER</td>\\n<td>New York Stock Exchange</td>\\n</tr>\\n</tbody>\\n</table>\\n\\nSecurities registered pursuant to Section 12(g) of the Act: None \\n\\n* Indicate by check mark whether the registrant is a well-known seasoned issuer, as defined in Rule 405 of the Securities Act. \\n - Yes [x] \\n - No [ ] \\n\\n* Indicate by check mark whether the registrant is not required to file reports pursuant to Section 13 or Section 15(d) of the Act. \\n - Yes [ ] \\n - No [x] \\n\\n* Indicate by check mark whether the registrant (1) has filed all reports required to be filed by Section 13 or 15(d) of the Securities Exchange Act of 1934 during the preceding 12 months '"
|
||||
]
|
||||
},
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"documents[0].text[:2000]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"3"
|
||||
]
|
||||
},
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"len(documents)"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": ".venv",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2
|
||||
}
|
||||
@@ -0,0 +1,290 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Table Extraction with LlamaParse\n",
|
||||
"\n",
|
||||
"This notebook will show you how to extract tables and save them as CSV files thanks to LlamaParse advanced parsing capabilities.\n",
|
||||
"\n",
|
||||
"Status:\n",
|
||||
"| Last Executed | Version | State |\n",
|
||||
"|---------------|---------|------------|\n",
|
||||
"| Aug-19-2025 | 0.6.61 | Maintained |"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"**1. Install needed dependencies**"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%pip install llama-cloud-services pandas"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"**2. Set you LLAMA_CLOUD_API_KEY as env variable**"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"\n",
|
||||
"os.environ[\"LLAMA_CLOUD_API_KEY\"] = \"llx-...\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"**3. Initialiaze the parser**"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_cloud_services import LlamaParse\n",
|
||||
"\n",
|
||||
"parser = LlamaParse(\n",
|
||||
" parse_mode=\"parse_page_with_agent\",\n",
|
||||
" model=\"openai-gpt-4-1-mini\",\n",
|
||||
" high_res_ocr=True,\n",
|
||||
" adaptive_long_table=True,\n",
|
||||
" outlined_table_extraction=True,\n",
|
||||
" output_tables_as_HTML=True,\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"**4. Get data**\n",
|
||||
"\n",
|
||||
"This is a PDF with _lots_ of tables!"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"--2025-08-19 16:05:55-- https://assets.accessible-digital-documents.com/uploads/2017/01/sample-tables.pdf\n",
|
||||
"Resolving assets.accessible-digital-documents.com (assets.accessible-digital-documents.com)... 18.64.67.96, 18.64.67.90, 18.64.67.78, ...\n",
|
||||
"Connecting to assets.accessible-digital-documents.com (assets.accessible-digital-documents.com)|18.64.67.96|:443... connected.\n",
|
||||
"HTTP request sent, awaiting response... 200 OK\n",
|
||||
"Length: 145494 (142K) [application/pdf]\n",
|
||||
"Saving to: ‘sample-tables.pdf’\n",
|
||||
"\n",
|
||||
"sample-tables.pdf 100%[===================>] 142.08K 529KB/s in 0.3s \n",
|
||||
"\n",
|
||||
"2025-08-19 16:05:57 (529 KB/s) - ‘sample-tables.pdf’ saved [145494/145494]\n",
|
||||
"\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"! wget https://assets.accessible-digital-documents.com/uploads/2017/01/sample-tables.pdf"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"**5. Parse document**"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Started parsing the file under job_id 727ce176-96bd-4cd1-84e3-fb64e08de336\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"result = await parser.aparse(\"sample-tables.pdf\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"**6. Get tables!**"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"[['Rainfall (inches)', 'Americas', 'Asia', 'Europe', 'Africa'], ['', '133', '244', '155', '166'], ['', '27', '28', '29', '20'], ['', '11', '12', '13', '16']]\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"tables = []\n",
|
||||
"for page in result.pages:\n",
|
||||
" for item in page.items:\n",
|
||||
" if item.type == \"table\":\n",
|
||||
" tables.append(item.rows)\n",
|
||||
"\n",
|
||||
"print(tables[8])"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"**7. Load tables**\n",
|
||||
"\n",
|
||||
"Let's show one example table!"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<div>\n",
|
||||
"<style scoped>\n",
|
||||
" .dataframe tbody tr th:only-of-type {\n",
|
||||
" vertical-align: middle;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" .dataframe tbody tr th {\n",
|
||||
" vertical-align: top;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" .dataframe thead th {\n",
|
||||
" text-align: right;\n",
|
||||
" }\n",
|
||||
"</style>\n",
|
||||
"<table border=\"1\" class=\"dataframe\">\n",
|
||||
" <thead>\n",
|
||||
" <tr style=\"text-align: right;\">\n",
|
||||
" <th></th>\n",
|
||||
" <th>0</th>\n",
|
||||
" <th>1</th>\n",
|
||||
" <th>2</th>\n",
|
||||
" <th>3</th>\n",
|
||||
" <th>4</th>\n",
|
||||
" </tr>\n",
|
||||
" </thead>\n",
|
||||
" <tbody>\n",
|
||||
" <tr>\n",
|
||||
" <th>0</th>\n",
|
||||
" <td>Rainfall (inches)</td>\n",
|
||||
" <td>Americas</td>\n",
|
||||
" <td>Asia</td>\n",
|
||||
" <td>Europe</td>\n",
|
||||
" <td>Africa</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>1</th>\n",
|
||||
" <td></td>\n",
|
||||
" <td>133</td>\n",
|
||||
" <td>244</td>\n",
|
||||
" <td>155</td>\n",
|
||||
" <td>166</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>2</th>\n",
|
||||
" <td></td>\n",
|
||||
" <td>27</td>\n",
|
||||
" <td>28</td>\n",
|
||||
" <td>29</td>\n",
|
||||
" <td>20</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>3</th>\n",
|
||||
" <td></td>\n",
|
||||
" <td>11</td>\n",
|
||||
" <td>12</td>\n",
|
||||
" <td>13</td>\n",
|
||||
" <td>16</td>\n",
|
||||
" </tr>\n",
|
||||
" </tbody>\n",
|
||||
"</table>\n",
|
||||
"</div>"
|
||||
],
|
||||
"text/plain": [
|
||||
" 0 1 2 3 4\n",
|
||||
"0 Rainfall (inches) Americas Asia Europe Africa\n",
|
||||
"1 133 244 155 166\n",
|
||||
"2 27 28 29 20\n",
|
||||
"3 11 12 13 16"
|
||||
]
|
||||
},
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"import pandas as pd\n",
|
||||
"from IPython.display import display\n",
|
||||
"\n",
|
||||
"df = pd.DataFrame(tables[8])\n",
|
||||
"df.head()"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"provenance": []
|
||||
},
|
||||
"kernelspec": {
|
||||
"display_name": ".venv",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 0
|
||||
}
|
||||
@@ -0,0 +1,279 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "0db58db5-d4ee-4631-af5b-4fc53eb05170",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# RAG with Excel Spreadsheet using LlamaPrase\n",
|
||||
"\n",
|
||||
"<a href=\"https://colab.research.google.com/github/run-llama/llama_cloud_services/blob/main/examples/parse/excel/dcf_rag.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>\n",
|
||||
"\n",
|
||||
"This notebook constructs a RAG pipeline over a simple DCF template [here](https://eqvista.com/app/uploads/2020/09/Eqvista_DCF-Excel-Template.xlsx).\n",
|
||||
"\n",
|
||||
"Status:\n",
|
||||
"| Last Executed | Version | State |\n",
|
||||
"|---------------|---------|------------|\n",
|
||||
"| Aug-19-2025 | 0.6.61 | Maintained |\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "5f7d99ad-6ebd-47d0-92a7-566630b0c22a",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Setup\n",
|
||||
"\n",
|
||||
"We first setup and load the data. If you haven't already, [download the template](https://eqvista.com/wp-content/uploads/2020/09/Eqvista_DCF-Excel-Template.xlsx) and name it `dcf_template.xlxs` locally."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "d867d1a6-cfcf-4f53-952a-f4a6ff2fa205",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%pip install \"llama-index>=0.13.0<0.14.0\"\n",
|
||||
"%pip install llama-cloud-services"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "9876ae6d",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"\n",
|
||||
"os.environ[\"LLAMA_CLOUD_API_KEY\"] = \"llx-...\"\n",
|
||||
"os.environ[\"OPENAI_API_KEY\"] = \"sk-...\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "9c4693c7-c1c8-47b4-8a8c-25d7e9ef9d2c",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Started parsing the file under job_id 1adabb9a-31d3-4732-962f-a287d5f7af2a\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from llama_cloud_services import LlamaParse\n",
|
||||
"\n",
|
||||
"parser = LlamaParse(\n",
|
||||
" parse_mode=\"parse_page_with_agent\",\n",
|
||||
" model=\"openai-gpt-4-1-mini\",\n",
|
||||
" high_res_ocr=True,\n",
|
||||
" adaptive_long_table=True,\n",
|
||||
" outlined_table_extraction=True,\n",
|
||||
" output_tables_as_HTML=True,\n",
|
||||
" api_key=\"llx-jwAQZL8T38onyL9hKBOXyRtnuCU0Fk3z7tmDhIT3L0GEfohJ\",\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"result = await parser.aparse(\"./dcf_template.xlsx\")\n",
|
||||
"llama_parse_documents = result.get_text_documents(split_by_page=True)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "7302f1c8-e405-4cda-8ff7-1d55185816f7",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Discounted Cash Flow Excel Template\t\t\t\t\t\t\t\t\t\t\t\n",
|
||||
"Here is a simple discounted cash flow excel template for estimating your company value based on this income valuation approach\t\t\t\t\t\t\t\t\t\t\t\n",
|
||||
"Instructions:\t\t\t\t\t\t\t\t\t\t\t\n",
|
||||
"1) Fill out the two assumptions in yellow highlight\t\t\t\t\t\t\t\t\t\t\t\n",
|
||||
"2) Fill in either the 5 year or 3 year weighted average figures in yellow highlight\t\t\t\t\t\t\t\t\t\t\t\n",
|
||||
"Assumptions\t\t\t\t\t\t\t\t\t\t\t\n",
|
||||
"Tax Rate\t20%\t\t\t\t\t\t\t\t\t\t\n",
|
||||
"Discount Rate\t15%\t\t\t\t\t\t\t\t\t\t\n",
|
||||
"5 Year Weighted Moving Average\t\t\t\t\t\t\t\t\t\t\t\n",
|
||||
"Indication of Company Value\t $242,995.43 \t\t\t\t\t\t\t\t\t\t\n",
|
||||
"3 Year Weighted Moving Average\t\t\t\t\t\t\t\t\t\t\t\n",
|
||||
"Indication of Company Value\t $158,651.07 \t\t\t\t\t\t\t\t\t\t\n",
|
||||
"\t5 Year Weighted Moving Average\t\t\t\t\t\t\t\t\t\t\n",
|
||||
"\tPast Years\t\t\t\t\tForecasted Future Years\t\t\t\t\t\n",
|
||||
"\tYear 1\tYear 2\tYear 3\tYear 4\tYear 5\tYear 6\tYear 7\tYear 8\tYear 9\tYear 10\tTerminal Value\n",
|
||||
"Pre-tax income\t 50,000.00 \t 55,000.00 \t 45,000.00 \t 52,000.00 \t 60,000.00 \t\t\t\t\t\t\n",
|
||||
"Income Taxes\t 10,000.00 \t 11,000.00 \t 9,000.00 \t 10,400.00 \t 12,000.00 \t\t\t\t\t\t\n",
|
||||
"Net Income\t 40,000.00 \t 44,000.00 \t 36,000.00 \t 41,600.00 \t 48,000.00 \t\t\t\t\t\t\n",
|
||||
"Depreciation Expense\t 5,000.00 \t 4,000.00 \t 3,000.00 \t 2,000.00 \t 1,000.00 \t\t\t\t\t\t\n",
|
||||
"Capital Expenditures\t 10,000.00 \t 8,000.00 \t 5,000.00 \t 5,000.00 \t 7,000.00 \t\t\t\t\t\t\n",
|
||||
"Debt Repayments\t 5,000.00 \t 5,000.00 \t 5,000.00 \t 5,000.00 \t 5,000.00 \t\t\t\t\t\t\n",
|
||||
"Net Cash Flow\t 20,000.00 \t 27,000.00 \t 23,000.00 \t 29,600.00 \t 35,000.00 \t 29,093.33 \t 29,817.78 \t 30,177.48 \t 30,469.23 \t 30,379.74 \t 287,188.00 \n",
|
||||
"Discounting Factor\t\t\t\t\t\t 0.8696 \t 0.7561 \t 0.6575 \t 0.5718 \t 0.4972 \t 0.4972 \n",
|
||||
"Present Value of Future Cash Flow\t\t\t\t\t\t 25,298.55 \t 22,546.52 \t 19,842.18 \t 17,420.88 \t 15,104.10 \t 142,783.19 \n",
|
||||
"\t3 Year Weighted Moving Average\t\t\t\t\t\t\t\t\t\t\n",
|
||||
"\tPast Years\t\t\tForecasted Future Years\t\t\t\t\t\t\t\n",
|
||||
"\tYear 1\tYear 2\tYear 3\tYear 4\tYear 5\tYear 6\tTerminal Value\t\t\t\t\n",
|
||||
"Pre-tax income\t 50,000.00 \t 55,000.00 \t 45,000.00 \t\t\t\t\t\t\t\t\n",
|
||||
"Income Taxes\t 10,000.00 \t 11,000.00 \t 9,000.00 \t\t\t\t\t\t\t\t\n",
|
||||
"Net Income\t 40,000.00 \t 44,000.00 \t 36,000.00 \t\t\t\t\t\t\t\t\n",
|
||||
"Depreciation Expense\t 5,000.00 \t 4,000.00 \t 3,000.00 \t\t\t\t\t\t\t\t\n",
|
||||
"Capital Expenditures\t 10,000.00 \t 8,000.00 \t 5,000.00 \t\t\t\t\t\t\t\t\n",
|
||||
"Debt Repayments\t 5,000.00 \t 5,000.00 \t 5,000.00 \t\t\t\t\t\t\t\t\n",
|
||||
"Net Cash Flow\t 20,000.00 \t 27,000.00 \t 23,000.00 \t 23,833.33 \t 24,083.33 \t 23,819.44 \t 158,253.59 \t\t\t\t\n",
|
||||
"Discounting Factor\t\t\t\t 0.8696 \t 0.7561 \t 0.6575 \t 0.6575 \t\t\t\t\n",
|
||||
"Present Value of Future Cash Flow\t\t\t\t 20,724.64 \t 18,210.46 \t 15,661.67 \t 104,054.30 \t\t\t\t\n",
|
||||
"Notes:\t\t\t\t\t\t\t\t\t\t\t\n",
|
||||
"-We based this simple discounted cash flow excel model based on the weighted moving averages (5 year or 3 year) for simplicity, in case a constant growth rate cannot be easily determined.\t\t\t\t\t\t\t\t\t\t\t\n",
|
||||
"-The factors such as Depreciation Expense, Capital Expense and Debt Repayments remain constant, so consider this when looking at the forecasted figures.\t\t\t\t\t\t\t\t\t\t\t\n",
|
||||
"-For the terminal value constant growth rate, we make the assumption of the growth from the last forecasted year compared to the first forecasted year. Adjust in the formula as needed.\t\t\t\t\t\t\t\t\t\t\t\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(llama_parse_documents[1].text)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "1aedd4bb-7939-4fbc-8f07-d362e24d9772",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Configure LLM\n",
|
||||
"\n",
|
||||
"We configure the LLM to use the OpenAI API to answer questions based on the parsed data."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "f7c056a8-d098-4ebe-9341-d9f07081067c",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from llama_index.llms.openai import OpenAI\n",
|
||||
"\n",
|
||||
"llm = OpenAI(model=\"gpt-5-mini\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "fa75f1bc-6fed-4721-ba5e-dc5408395618",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Ask Questions over this Data\n",
|
||||
"\n",
|
||||
"Let's now ask questions over this data, using both the LlamaParse-powered pipeline and naive pipeline.\n",
|
||||
"\n",
|
||||
"LlamaParse-powered responses:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "a875a20e-a6b6-46b7-80d4-614546215ffc",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"2025-08-19 19:35:11,505 - INFO - HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"In the 5-year WMA table, income taxes for past years (Year 3–Year 5) are:\n",
|
||||
"\n",
|
||||
"- Year 3: $9,000 \n",
|
||||
"- Year 4: $10,400 \n",
|
||||
"- Year 5: $12,000\n",
|
||||
"\n",
|
||||
"These equal 20% of pre-tax income for those years (pre-tax: $45,000; $52,000; $60,000). The taxes rise steadily: Year 3 → Year 4 is about a 15.6% increase, Year 4 → Year 5 about a 15.4% increase, and Year 3 → Year 5 is a 33.3% increase.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from llama_index.core.llms import ChatMessage\n",
|
||||
"\n",
|
||||
"query_str = \"Tell me about the income taxes in the past years (year 3-5) for the 5 year WMA table\"\n",
|
||||
"context = \"\\n\\n\".join([doc.text for doc in llama_parse_documents])\n",
|
||||
"messages = [\n",
|
||||
" ChatMessage(\n",
|
||||
" role=\"user\",\n",
|
||||
" content=f\"Here is some context\\n<context>{context}</context>\\n\\nAnswer the following question: {query_str}\",\n",
|
||||
" )\n",
|
||||
"]\n",
|
||||
"\n",
|
||||
"response = await llm.achat(messages)\n",
|
||||
"print(response.message.content)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "7a93af5f-fcea-4f14-80eb-5dfad230cd8a",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"2025-08-19 19:36:38,456 - INFO - HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"For the 3‑year WMA the discount factor used in Year 5 is 0.7561.\n",
|
||||
"\n",
|
||||
"Why: the model uses a 15% discount rate (assumption). Because Years 1–3 are historical, Year 4 is discounted one period, Year 5 two periods, etc. So the Year‑5 factor = 1 / (1 + 0.15)^2 = 0.756143 (rounded to 0.7561).\n",
|
||||
"\n",
|
||||
"How it’s used: Year‑5 net cash flow 24,083.33 × 0.7561 = 18,210.46 (present value shown in the template).\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"query_str = \"Tell me about the discounting factors in year 5 for the 3 year WMA\"\n",
|
||||
"context = \"\\n\\n\".join([doc.text for doc in llama_parse_documents])\n",
|
||||
"messages = [\n",
|
||||
" ChatMessage(\n",
|
||||
" role=\"user\",\n",
|
||||
" content=f\"Here is some context\\n<context>{context}</context>\\n\\nAnswer the following question: {query_str}\",\n",
|
||||
" )\n",
|
||||
"]\n",
|
||||
"\n",
|
||||
"response = await llm.achat(messages)\n",
|
||||
"print(response.message.content)"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": ".venv",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
|
After Width: | Height: | Size: 195 KiB |
|
After Width: | Height: | Size: 363 KiB |
|
After Width: | Height: | Size: 343 KiB |