Skip to content

Commit d4e2ac3

Browse files
authored
feat: structured output in config of chain (#50)
1 parent 52746aa commit d4e2ac3

File tree

4 files changed

+23
-17
lines changed

4 files changed

+23
-17
lines changed

README.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ llm_chain:
4141
chain:
4242
rag:
4343
platform: 'llm_chain.platform.azure.gpt_deployment'
44+
structured_output: false # Disables support for "output_structure" option, default is true
4445
model:
4546
name: 'GPT'
4647
version: 'gpt-4o-mini'
@@ -50,7 +51,7 @@ llm_chain:
5051
platform: 'llm_chain.platform.anthropic'
5152
model:
5253
name: 'Claude'
53-
tools: # Unconfigured all tools are injected into the chain, use "[]" or "false" to have no tools.
54+
tools: # If undefined, all tools are injected into the chain, use "[]" or "false" to have no tools.
5455
- 'PhpLlm\LlmChain\Chain\ToolBox\Tool\Wikipedia'
5556
store:
5657
# also azure_search, mongodb and pinecone are supported as store type

src/DependencyInjection/Configuration.php

+1
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ public function getConfigTreeBuilder(): TreeBuilder
6363
->end()
6464
->end()
6565
->end()
66+
->booleanNode('structured_output')->defaultTrue()->end()
6667
->arrayNode('tools')
6768
->beforeNormalization()
6869
->ifTrue(fn ($v) => false === $v)

src/DependencyInjection/LlmChainExtension.php

+20-6
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,10 @@
1616
use PhpLlm\LlmChain\Bridge\OpenAI\PlatformFactory as OpenAIPlatformFactory;
1717
use PhpLlm\LlmChain\Bridge\Pinecone\Store as PineconeStore;
1818
use PhpLlm\LlmChain\Bridge\Voyage\Voyage;
19+
use PhpLlm\LlmChain\Chain;
1920
use PhpLlm\LlmChain\Chain\InputProcessor;
2021
use PhpLlm\LlmChain\Chain\OutputProcessor;
22+
use PhpLlm\LlmChain\Chain\StructuredOutput\ChainProcessor as StructureOutputProcessor;
2123
use PhpLlm\LlmChain\Chain\ToolBox\Attribute\AsTool;
2224
use PhpLlm\LlmChain\ChainInterface;
2325
use PhpLlm\LlmChain\Embedder;
@@ -214,12 +216,15 @@ private function processChainConfig(string $name, array $config, ContainerBuilde
214216
$container->setDefinition('llm_chain.chain.'.$name.'.llm', $llmDefinition);
215217

216218
// CHAIN
217-
$chainDefinition = (new ChildDefinition('llm_chain.chain.abstract'))
218-
->replaceArgument('$platform', new Reference($config['platform']))
219-
->replaceArgument('$llm', new Reference('llm_chain.chain.'.$name.'.llm'));
219+
$chainDefinition = (new Definition(Chain::class))
220+
->setArgument('$platform', new Reference($config['platform']))
221+
->setArgument('$llm', new Reference('llm_chain.chain.'.$name.'.llm'));
222+
223+
$inputProcessor = [];
224+
$outputProcessor = [];
220225

221226
// TOOL & PROCESSOR
222-
if (isset($config['tools']) && 0 !== count($config['tools'])) {
227+
if (0 !== count($config['tools'])) {
223228
$tools = array_map(static fn (string $tool) => new Reference($tool), $config['tools']);
224229
$toolboxDefinition = (new ChildDefinition('llm_chain.toolbox.abstract'))
225230
->replaceArgument('$tools', $tools);
@@ -238,9 +243,18 @@ private function processChainConfig(string $name, array $config, ContainerBuilde
238243
->replaceArgument('$toolBox', new Reference('llm_chain.toolbox.'.$name));
239244
$container->setDefinition('llm_chain.tool.chain_processor.'.$name, $toolProcessorDefinition);
240245

241-
$chainDefinition->replaceArgument('$inputProcessor', [new Reference('llm_chain.tool.chain_processor.'.$name)]);
242-
$chainDefinition->replaceArgument('$outputProcessor', [new Reference('llm_chain.tool.chain_processor.'.$name)]);
246+
$inputProcessor[] = new Reference('llm_chain.tool.chain_processor.'.$name);
247+
$outputProcessor[] = new Reference('llm_chain.tool.chain_processor.'.$name);
248+
}
249+
250+
// STRUCTURED OUTPUT
251+
if ($config['structured_output']) {
252+
$inputProcessor[] = new Reference(StructureOutputProcessor::class);
253+
$outputProcessor[] = new Reference(StructureOutputProcessor::class);
243254
}
255+
$chainDefinition
256+
->setArgument('$inputProcessor', $inputProcessor)
257+
->setArgument('$outputProcessor', $outputProcessor);
244258

245259
$container->setDefinition('llm_chain.chain.'.$name, $chainDefinition);
246260
}

src/Resources/config/services.php

-10
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
66

7-
use PhpLlm\LlmChain\Chain;
87
use PhpLlm\LlmChain\Chain\StructuredOutput\ChainProcessor as StructureOutputProcessor;
98
use PhpLlm\LlmChain\Chain\StructuredOutput\ResponseFormatFactory;
109
use PhpLlm\LlmChain\Chain\StructuredOutput\ResponseFormatFactoryInterface;
@@ -15,7 +14,6 @@
1514
use PhpLlm\LlmChain\Chain\ToolBox\ToolBox;
1615
use PhpLlm\LlmChain\Chain\ToolBox\ToolBoxInterface;
1716
use PhpLlm\LlmChain\Embedder;
18-
use PhpLlm\LlmChain\PlatformInterface;
1917
use PhpLlm\LlmChainBundle\Profiler\DataCollector;
2018
use PhpLlm\LlmChainBundle\Profiler\TraceableToolBox;
2119

@@ -25,14 +23,6 @@
2523
->autowire()
2624

2725
// high level feature
28-
->set('llm_chain.chain.abstract', Chain::class)
29-
->abstract()
30-
->args([
31-
'$platform' => service(PlatformInterface::class),
32-
'$llm' => abstract_arg('Language model'),
33-
'$inputProcessor' => tagged_iterator('llm_chain.chain.input_processor'),
34-
'$outputProcessor' => tagged_iterator('llm_chain.chain.output_processor'),
35-
])
3626
->set('llm_chain.embedder.abstract', Embedder::class)
3727
->abstract()
3828
->args([

0 commit comments

Comments
 (0)