Skip to content

Commit 500970c

Browse files
authored
Merge pull request #21 from symfony/ai-bundle-integration
Integrate LLM Chain Bundle as AI Bundle
2 parents ac23f60 + a0c8943 commit 500970c

20 files changed

+1632
-0
lines changed

src/ai-bundle/.gitattributes

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
/.github export-ignore
2+
/tests export-ignore
3+
.gitattributes export-ignore
4+
.gitignore export-ignore
5+
phpstan.dist.neon export-ignore
6+
phpunit.xml.dist export-ignore
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
Please do not submit any Pull Requests here. They will be closed.
2+
---
3+
4+
Please submit your PR here instead:
5+
https://github.com/symfony/ai
6+
7+
This repository is what we call a "subtree split": a read-only subset of that main repository.
8+
We're looking forward to your PR there!
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
name: Close Pull Request
2+
3+
on:
4+
pull_request_target:
5+
types: [opened]
6+
7+
jobs:
8+
run:
9+
runs-on: ubuntu-latest
10+
steps:
11+
- uses: superbrothers/close-pull-request@v3
12+
with:
13+
comment: |
14+
Thanks for your Pull Request! We love contributions.
15+
16+
However, you should instead open your PR on the main repository:
17+
https://github.com/symfony/ai
18+
19+
This repository is what we call a "subtree split": a read-only subset of that main repository.
20+
We're looking forward to your PR there!

src/ai-bundle/.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
vendor
2+
composer.lock
3+
.php-cs-fixer.cache
4+
.phpunit.cache
5+
coverage

src/ai-bundle/LICENSE

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
Copyright (c) 2025-present Fabien Potencier
2+
3+
Permission is hereby granted, free of charge, to any person obtaining a copy
4+
of this software and associated documentation files (the "Software"), to deal
5+
in the Software without restriction, including without limitation the rights
6+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
copies of the Software, and to permit persons to whom the Software is furnished
8+
to do so, subject to the following conditions:
9+
10+
The above copyright notice and this permission notice shall be included in all
11+
copies or substantial portions of the Software.
12+
13+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19+
THE SOFTWARE.

src/ai-bundle/README.md

Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
# Symfony AI Bundle
2+
3+
Integration bundle for Symfony AI components.
4+
5+
## Installation
6+
7+
```bash
8+
composer require symfony/ai-bundle
9+
```
10+
11+
## Configuration
12+
13+
### Simple Example with OpenAI
14+
15+
```yaml
16+
# config/packages/ai.yaml
17+
ai:
18+
platform:
19+
openai:
20+
api_key: '%env(OPENAI_API_KEY)%'
21+
agent:
22+
default:
23+
model:
24+
name: 'GPT'
25+
```
26+
27+
### Advanced Example with Anthropic, Azure, Google and multiple agents
28+
```yaml
29+
# config/packages/ai.yaml
30+
ai:
31+
platform:
32+
anthropic:
33+
api_key: '%env(ANTHROPIC_API_KEY)%'
34+
azure:
35+
# multiple deployments possible
36+
gpt_deployment:
37+
base_url: '%env(AZURE_OPENAI_BASEURL)%'
38+
deployment: '%env(AZURE_OPENAI_GPT)%'
39+
api_key: '%env(AZURE_OPENAI_KEY)%'
40+
api_version: '%env(AZURE_GPT_VERSION)%'
41+
google:
42+
api_key: '%env(GOOGLE_API_KEY)%'
43+
agent:
44+
rag:
45+
platform: 'symfony_ai.platform.azure.gpt_deployment'
46+
structured_output: false # Disables support for "output_structure" option, default is true
47+
model:
48+
name: 'GPT'
49+
version: 'gpt-4o-mini'
50+
system_prompt: 'You are a helpful assistant that can answer questions.' # The default system prompt of the agent
51+
include_tools: true # Include tool definitions at the end of the system prompt
52+
tools:
53+
# Referencing a service with #[AsTool] attribute
54+
- 'Symfony\AI\Agent\Toolbox\Tool\SimilaritySearch'
55+
56+
# Referencing a service without #[AsTool] attribute
57+
- service: 'App\Agent\Tool\CompanyName'
58+
name: 'company_name'
59+
description: 'Provides the name of your company'
60+
method: 'foo' # Optional with default value '__invoke'
61+
62+
# Referencing a agent => agent in agent 🤯
63+
- service: 'symfony_ai.agent.research'
64+
name: 'wikipedia_research'
65+
description: 'Can research on Wikipedia'
66+
is_agent: true
67+
research:
68+
platform: 'symfony_ai.platform.anthropic'
69+
model:
70+
name: 'Claude'
71+
tools: # If undefined, all tools are injected into the agent, use "tools: false" to disable tools.
72+
- 'Symfony\AI\Agent\Toolbox\Tool\Wikipedia'
73+
fault_tolerant_toolbox: false # Disables fault tolerant toolbox, default is true
74+
store:
75+
# also azure_search, mongodb and pinecone are supported as store type
76+
chroma_db:
77+
# multiple collections possible per type
78+
default:
79+
collection: 'my_collection'
80+
embedder:
81+
default:
82+
# platform: 'symfony_ai.platform.anthropic'
83+
# store: 'symfony_ai.store.chroma_db.default'
84+
model:
85+
name: 'Embeddings'
86+
version: 'text-embedding-ada-002'
87+
```
88+
89+
## Usage
90+
91+
### Agent Service
92+
93+
Use the `Agent` service to leverage models and tools:
94+
```php
95+
use Symfony\AI\Agent\AgentInterface;
96+
use Symfony\AI\Platform\Message\Message;
97+
use Symfony\AI\Platform\Message\MessageBag;
98+
99+
final readonly class MyService
100+
{
101+
public function __construct(
102+
private AgentInterface $agent,
103+
) {
104+
}
105+
106+
public function submit(string $message): string
107+
{
108+
$messages = new MessageBag(
109+
Message::forSystem('Speak like a pirate.'),
110+
Message::ofUser($message),
111+
);
112+
113+
return $this->agent->call($messages);
114+
}
115+
}
116+
```
117+
118+
### Register Tools
119+
120+
To use existing tools, you can register them as a service:
121+
```yaml
122+
services:
123+
_defaults:
124+
autowire: true
125+
autoconfigure: true
126+
127+
Symfony\AI\Agent\Toolbox\Tool\Clock: ~
128+
Symfony\AI\Agent\Toolbox\Tool\OpenMeteo: ~
129+
Symfony\AI\Agent\Toolbox\Tool\SerpApi:
130+
$apiKey: '%env(SERP_API_KEY)%'
131+
Symfony\AI\Agent\Toolbox\Tool\SimilaritySearch: ~
132+
Symfony\AI\Agent\Toolbox\Tool\Tavily:
133+
$apiKey: '%env(TAVILY_API_KEY)%'
134+
Symfony\AI\Agent\Toolbox\Tool\Wikipedia: ~
135+
Symfony\AI\Agent\Toolbox\Tool\YouTubeTranscriber: ~
136+
```
137+
138+
Custom tools can be registered by using the `#[AsTool]` attribute:
139+
140+
```php
141+
use Symfony\AI\Agent\Toolbox\Attribute\AsTool;
142+
143+
#[AsTool('company_name', 'Provides the name of your company')]
144+
final class CompanyName
145+
{
146+
public function __invoke(): string
147+
{
148+
return 'ACME Corp.'
149+
}
150+
}
151+
```
152+
153+
The agent configuration by default will inject all known tools into the agent.
154+
155+
To disable this behavior, set the `tools` option to `false`:
156+
```yaml
157+
ai:
158+
agent:
159+
my_agent:
160+
tools: false
161+
```
162+
163+
To inject only specific tools, list them in the configuration:
164+
```yaml
165+
ai:
166+
agent:
167+
my_agent:
168+
tools:
169+
- 'Symfony\AI\Agent\Toolbox\Tool\SimilaritySearch'
170+
```
171+
172+
### Profiler
173+
174+
The profiler panel provides insights into the agent's execution:
175+
176+
![Profiler](./profiler.png)

src/ai-bundle/composer.json

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
{
2+
"name": "symfony/ai-bundle",
3+
"type": "symfony-bundle",
4+
"description": "Integration bundle for Symfony AI components",
5+
"license": "MIT",
6+
"authors": [
7+
{
8+
"name": "Christopher Hertel",
9+
"email": "[email protected]"
10+
},
11+
{
12+
"name": "Oskar Stark",
13+
"email": "[email protected]"
14+
}
15+
],
16+
"require": {
17+
"php": ">=8.2",
18+
"symfony/ai-agent": "@dev",
19+
"symfony/ai-platform": "@dev",
20+
"symfony/ai-store": "@dev",
21+
"symfony/config": "^6.4 || ^7.0",
22+
"symfony/dependency-injection": "^6.4 || ^7.0",
23+
"symfony/framework-bundle": "^6.4 || ^7.0",
24+
"symfony/string": "^6.4 || ^7.0"
25+
},
26+
"require-dev": {
27+
"phpstan/phpstan": "^2.1",
28+
"phpunit/phpunit": "^11.5"
29+
},
30+
"config": {
31+
"sort-packages": true
32+
},
33+
"autoload": {
34+
"psr-4": {
35+
"Symfony\\AI\\AIBundle\\": "src/"
36+
}
37+
},
38+
"autoload-dev": {
39+
"psr-4": {
40+
"Symfony\\AI\\AIBundle\\Tests\\": "tests/"
41+
}
42+
},
43+
"repositories": [
44+
{"type": "path", "url": "../agent"},
45+
{"type": "path", "url": "../platform"},
46+
{"type": "path", "url": "../store"}
47+
]
48+
}

src/ai-bundle/phpstan.dist.neon

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
parameters:
2+
level: 6
3+
paths:
4+
- src/
5+
excludePaths:
6+
analyse:
7+
- src/DependencyInjection/Configuration.php

src/ai-bundle/phpunit.xml.dist

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/11.3/phpunit.xsd"
4+
bootstrap="vendor/autoload.php"
5+
cacheDirectory=".phpunit.cache"
6+
colors="true"
7+
executionOrder="depends,defects"
8+
requireCoverageMetadata="true"
9+
beStrictAboutCoverageMetadata="true"
10+
beStrictAboutOutputDuringTests="true"
11+
failOnRisky="true"
12+
failOnWarning="true">
13+
<testsuites>
14+
<testsuite name="default">
15+
<directory>tests</directory>
16+
</testsuite>
17+
</testsuites>
18+
19+
<source ignoreIndirectDeprecations="true" restrictNotices="true" restrictWarnings="true">
20+
<include>
21+
<directory>src</directory>
22+
</include>
23+
</source>
24+
</phpunit>

src/ai-bundle/profiler.png

168 KB
Loading

0 commit comments

Comments
 (0)