Skip to content

Commit

Permalink
Refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
huangzhhui committed Sep 25, 2023
1 parent 79c8413 commit 65178ca
Show file tree
Hide file tree
Showing 37 changed files with 803 additions and 90 deletions.
4 changes: 2 additions & 2 deletions bin/action.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@ function getClient(string $type = 'azure')
switch ($type) {
case 'openai':
$openAI = new OpenAI();
$config = new OpenAIConfig(env('OPENAI_API_KEY_FOR_TEST'),);
$config = new OpenAIConfig(env('OPENAI_API_KEY'),);
$client = $openAI->getClient($config);
break;
case 'azure':
$openAI = new AzureOpenAI();
$config = new AzureOpenAIConfig(apiKey: env('AZURE_OPENAI_API_KEY_FOR_TEST'), baseUrl: env('AZURE_OPENAI_HOST'), apiVersion: env('AZURE_OPENAI_API_VERSION'), deploymentName: env('AZURE_OPENAI_DEPLOYMENT_NAME'),);
$config = new AzureOpenAIConfig(apiKey: env('AZURE_OPENAI_API_KEY'), baseUrl: env('AZURE_OPENAI_API_BASE'), apiVersion: env('AZURE_OPENAI_API_VERSION'), deploymentName: env('AZURE_OPENAI_DEPLOYMENT_NAME'),);
$client = $openAI->getClient($config);
break;
case 'rwkv':
Expand Down
4 changes: 2 additions & 2 deletions bin/agent.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,12 @@ public function getClient(string $type = 'azure')
switch ($type) {
case 'openai':
$openAI = new OpenAI();
$config = new OpenAIConfig(env('OPENAI_API_KEY_FOR_TEST'),);
$config = new OpenAIConfig(env('OPENAI_API_KEY'),);
$client = $openAI->getClient($config);
break;
case 'azure':
$openAI = new AzureOpenAI();
$config = new AzureOpenAIConfig(apiKey: env('AZURE_OPENAI_API_KEY_FOR_TEST'), baseUrl: env('AZURE_OPENAI_HOST'), apiVersion: env('AZURE_OPENAI_API_VERSION'), deploymentName: env('AZURE_OPENAI_DEPLOYMENT_NAME'),);
$config = new AzureOpenAIConfig(apiKey: env('AZURE_OPENAI_API_KEY'), baseUrl: env('AZURE_OPENAI_API_BASE'), apiVersion: env('AZURE_OPENAI_API_VERSION'), deploymentName: env('AZURE_OPENAI_DEPLOYMENT_NAME'),);
$client = $openAI->getClient($config);
break;
case 'rwkv':
Expand Down
4 changes: 2 additions & 2 deletions bin/code_optimize.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,14 @@ public function chat(array $messages, float $temperature = 0.9,): string
function getOpenAIClient(): OpenAIClient
{
$openAI = new OpenAI();
$config = new OpenAIConfig(env('OPENAI_API_KEY_FOR_TEST'),);
$config = new OpenAIConfig(env('OPENAI_API_KEY'),);
return $openAI->getClient($config);
}

function getAzureOpenAIClient(): AzureOpenAIClient
{
$openAI = new AzureOpenAI();
$config = new AzureOpenAIConfig(apiKey: env('AZURE_OPENAI_API_KEY_FOR_TEST'), baseUrl: env('AZURE_OPENAI_HOST'), apiVersion: env('AZURE_OPENAI_API_VERSION'), deploymentName: env('AZURE_OPENAI_DEPLOYMENT_NAME'),);
$config = new AzureOpenAIConfig(apiKey: env('AZURE_OPENAI_API_KEY'), baseUrl: env('AZURE_OPENAI_API_BASE'), apiVersion: env('AZURE_OPENAI_API_VERSION'), deploymentName: env('AZURE_OPENAI_DEPLOYMENT_NAME'),);
return $openAI->getClient($config);
}
}
Expand Down
50 changes: 28 additions & 22 deletions bin/codegen.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
<?php

declare(strict_types=1);

/**
* This file is part of Hyperf.
*
* @link https://www.hyperf.io
* @document https://hyperf.wiki
* @contact [email protected]
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
*/

use Hyperf\Odin\Apis\AzureOpenAI\AzureOpenAI;
use Hyperf\Odin\Apis\AzureOpenAI\AzureOpenAIConfig;
use Hyperf\Odin\Apis\AzureOpenAI\Client as AzureOpenAIClient;
Expand All @@ -8,7 +19,7 @@
use Hyperf\Odin\Apis\OpenAI\OpenAIConfig;
use Hyperf\Odin\Message\SystemMessage;
use Hyperf\Odin\Message\UserMessage;
use function Hyperf\Support\env as env;
use function Hyperf\Support\env;

! defined('BASE_PATH') && define('BASE_PATH', dirname(__DIR__, 1));

Expand All @@ -18,34 +29,33 @@

class LLM
{

public string $model = 'gpt-3.5-turbo';

public function chat(array $messages, float $temperature = 0.9,): string
public function chat(array $messages, float $temperature = 0.9): string
{
$client = $this->getAzureOpenAIClient();
$client->setDebug(false);
return $client->chat($messages, $this->model, $temperature, 3000);
}

function getOpenAIClient(): OpenAIClient
public function getOpenAIClient(): OpenAIClient
{
$openAI = new OpenAI();
$config = new OpenAIConfig(env('OPENAI_API_KEY_FOR_TEST'),);
$config = new OpenAIConfig(env('OPENAI_API_KEY'));
return $openAI->getClient($config);
}

function getAzureOpenAIClient(): AzureOpenAIClient
public function getAzureOpenAIClient(): AzureOpenAIClient
{
$openAI = new AzureOpenAI();
$config = new AzureOpenAIConfig(apiKey: env('AZURE_OPENAI_API_KEY_FOR_TEST'), baseUrl: env('AZURE_OPENAI_HOST'), apiVersion: env('AZURE_OPENAI_API_VERSION'), deploymentName: env('AZURE_OPENAI_DEPLOYMENT_NAME'),);
$config = new AzureOpenAIConfig(apiKey: env('AZURE_OPENAI_API_KEY'), baseUrl: env('AZURE_OPENAI_API_BASE'), apiVersion: env('AZURE_OPENAI_API_VERSION'), deploymentName: env('AZURE_OPENAI_DEPLOYMENT_NAME'));
return $openAI->getClient($config);
}
}

function chat(string $message): string
{
$prefixPrompt = <<<PROMPT
$prefixPrompt = <<<'PROMPT'
You are a code generator for a low-code platform. The project uses Hyperf 3.0 framework for code implementation. You need to analyze the process in detail and generate complete and runnable code. The result must be returned according to the required format.
PROMPT;

Expand All @@ -58,13 +68,13 @@ function chat(string $message): string
return $result;
}

$userMessage = "我需要设计一个访客管理系统,需要创建一个表单用于满足访客申请的表单,需要收集访客的姓名、手机号码、身份证号码、来访时间、来访的团队名称等基础信息,如果访客有开车过来,还需要提供车牌";
$userMessage = '我需要设计一个访客管理系统,需要创建一个表单用于满足访客申请的表单,需要收集访客的姓名、手机号码、身份证号码、来访时间、来访的团队名称等基础信息,如果访客有开车过来,还需要提供车牌';

/**
* Code structure generation
* Code structure generation.
*/
$analyse = <<<PROMPT
User Demand:$userMessage
User Demand:{$userMessage}
Requirements: Analyze user needs and design code structure to meet the needs. Code structure should be simple, clear, and without redundancy. Use full namespace for class calls. Code structure must comply with Hyperf 3.0 framework rules. No need to output code or extra line breaks, just output code structure according to format requirements. A request usually includes Controller, Service, Model, Repository, FormRequest. A class should have all methods.
Format:
[
Expand All @@ -91,7 +101,6 @@ function chat(string $message): string
Result:
PROMPT;


$result = chat($analyse);
$structs = json_decode(trim($result), true);

Expand All @@ -110,19 +119,18 @@ function chat(string $message): string
$paramsText .= "{$param['type']} {$param['name']}, ";
}
$paramsText = rtrim($paramsText, ', ');
$text .= "- {$method['name']}($paramsText): {$method['return_type']} // {$method['desc']}" . PHP_EOL;
$text .= "- {$method['name']}({$paramsText}): {$method['return_type']} // {$method['desc']}" . PHP_EOL;
}
$promptStructs[] = $text;
}
$promptStruct = implode(PHP_EOL, $promptStructs);


/**
* Data structure generation
* Data structure generation.
*/
$dataStruct = '';
$dataStructPrompt = <<<PROMPT
User requirements: $userMessage
User requirements: {$userMessage}
Requirements: Generate the data structure that meets the user requirements. The data structure should be simple, clear, and without redundancy. Data structure is the key structure to realize user requirements. No extra line breaks, just output data structure according to format requirements.
Format:
DataModelName:
Expand All @@ -133,7 +141,7 @@ function chat(string $message): string
$dataStruct = chat($dataStructPrompt);

/**
* Code generation
* Code generation.
*/
$outputDir = BASE_PATH . '/output';
$codeContext = '';
Expand All @@ -142,11 +150,11 @@ function chat(string $message): string
continue;
}
$generate = <<<PROMPT
User requirements: $userMessage
User requirements: {$userMessage}
data structure:
$dataStruct
{$dataStruct}
code structure:
$promptStruct
{$promptStruct}
Requirements: Generate runnable detailed PHP code for `{$struct['class']}` class based on code structure and user requirements. Only output code for `{$struct['class']}` class, code structure must comply with Hyperf 3.0 framework rules. Use Camel case for class names, class properties, and method names. Use Snake case for array keys. Implement strong typing. The code implementation must be runnable specific code and must implementation all logic, cannot be omitted, and cannot only have comments, strictly follow the return type. No need for explanations or Note or extra line breaks, just output the code, make sure the code is runnable.
Result:
PROMPT;
Expand All @@ -167,5 +175,3 @@ function chat(string $message): string
$codeContext .= '// Class: ' . $struct['path'] . PHP_EOL;
$codeContext .= $code . PHP_EOL;
}


14 changes: 8 additions & 6 deletions bin/data.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class LLM

public string $model = 'gpt-3.5-turbo';

public function chat(array $messages, float $temperature = 0.9,): string
public function chat(array $messages, float $temperature = 0,): string
{
$client = $this->getAzureOpenAIClient();
$client->setDebug(true);
Expand All @@ -31,27 +31,29 @@ public function chat(array $messages, float $temperature = 0.9,): string
function getOpenAIClient(): OpenAIClient
{
$openAI = new OpenAI();
$config = new OpenAIConfig(env('OPENAI_API_KEY_FOR_TEST'),);
$config = new OpenAIConfig(env('OPENAI_API_KEY'),);
return $openAI->getClient($config);
}

function getAzureOpenAIClient(): AzureOpenAIClient
{
$openAI = new AzureOpenAI();
$config = new AzureOpenAIConfig(apiKey: env('AZURE_OPENAI_API_KEY_FOR_TEST'), baseUrl: env('AZURE_OPENAI_HOST'), apiVersion: env('AZURE_OPENAI_API_VERSION'), deploymentName: env('AZURE_OPENAI_DEPLOYMENT_NAME'),);
$config = new AzureOpenAIConfig(apiKey: env('AZURE_OPENAI_API_KEY'), baseUrl: env('AZURE_OPENAI_API_BASE'), apiVersion: env('AZURE_OPENAI_API_VERSION'), deploymentName: env('AZURE_OPENAI_DEPLOYMENT_NAME'),);
return $openAI->getClient($config);
}
}

$data = file_get_contents(BASE_PATH . '/data/销售额趋势.csv');
$data = file_get_contents(BASE_PATH . '/data/test.markdown');

$prompt = <<<PROMPT
你是一个专业的数据分析师,你需要根据下面的数据进行分析,可以通过数学统计、归因分析、关联性分析、趋势分析等专业的分析技巧,根据用户问题以结论性的内容简洁的输出你的分析结果,不需要解释计算过程,尽量不要输出空白行:
你是一个专业的数据分析师,你需要根据下面的数据进行分析,根据用户问题以结论性的内容简洁的输出你的分析结果,尽量不要输出空白行:
数据:
$data
问题:进行数据分析
数据计算逻辑:单杯利润=价格-费用合计,毛利率=毛利/价格,毛利=价格-物料成本,费用合计=运营费用+营销费用+其它成本+折旧+管理费用+税项
要求:严格基于上面的数据和数据计算逻辑,一步一步推理全过程回答下面的问题
问题:如果我想在2021年提高单杯利润到2.1,但前提保持价格为15.1不变,那么其它指标应该要如何调整才能支持这个目标?调整多少?
分析结果:
PROMPT;

Expand Down
4 changes: 2 additions & 2 deletions bin/interactive.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@ function getClient(string $type = 'azure')
switch ($type) {
case 'openai':
$openAI = new OpenAI();
$config = new OpenAIConfig(env('OPENAI_API_KEY_FOR_TEST'),);
$config = new OpenAIConfig(env('OPENAI_API_KEY'),);
$client = $openAI->getClient($config);
break;
case 'azure':
$openAI = new AzureOpenAI();
$config = new AzureOpenAIConfig(apiKey: env('AZURE_OPENAI_API_KEY_FOR_TEST'), baseUrl: env('AZURE_OPENAI_HOST'), apiVersion: env('AZURE_OPENAI_API_VERSION'), deploymentName: env('AZURE_OPENAI_DEPLOYMENT_NAME'),);
$config = new AzureOpenAIConfig(apiKey: env('AZURE_OPENAI_API_KEY'), baseUrl: env('AZURE_OPENAI_API_BASE'), apiVersion: env('AZURE_OPENAI_API_VERSION'), deploymentName: env('AZURE_OPENAI_DEPLOYMENT_NAME'),);
$client = $openAI->getClient($config);
break;
case 'rwkv':
Expand Down
143 changes: 143 additions & 0 deletions bin/interpreter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
<?php

use Hyperf\Odin\Apis\AzureOpenAI\AzureOpenAI;
use Hyperf\Odin\Apis\AzureOpenAI\AzureOpenAIConfig;
use Hyperf\Odin\Apis\AzureOpenAI\Client as AzureOpenAIClient;
use Hyperf\Odin\Apis\OpenAI\Client as OpenAIClient;
use Hyperf\Odin\Apis\OpenAI\OpenAI;
use Hyperf\Odin\Apis\OpenAI\OpenAIConfig;
use Hyperf\Odin\Apis\OpenAI\Response\ChatCompletionChoice;
use Hyperf\Odin\Interpreter\CodeRunner;
use Hyperf\Odin\Memory\AbstractMemory;
use Hyperf\Odin\Memory\MessageHistory;
use Hyperf\Odin\Message\AssistantMessage;
use Hyperf\Odin\Message\SystemMessage;
use Hyperf\Odin\Message\UserMessage;
use Hyperf\Odin\Prompt\InterpreterPromptTemplate;
use function Hyperf\Support\env as env;

! defined('BASE_PATH') && define('BASE_PATH', dirname(__DIR__, 1));

require_once dirname(dirname(__FILE__)) . '/vendor/autoload.php';

\Hyperf\Di\ClassLoader::init();

class LLM
{

public string $model = 'gpt-3.5-turbo';
protected int $times = 0;

public function chat(array $messages, float $temperature = 0.9, array $functions = []): string
{
$client = $this->getAzureOpenAIClient();
$client->setDebug(false);
$response = $client->chat($messages, $this->model, $temperature, 3000, [], $functions);
$choice = $response->getChoices()[0];
try {
if ($choice instanceof ChatCompletionChoice && $choice->isFinishedByFunctionCall()) {
$message = $choice->getMessage();
if ($message instanceof AssistantMessage) {
echo 'AI: ' . $message->getContent() . PHP_EOL;
$functionCall = $message->getFunctionCall();
$functionName = $functionCall['name'];
$functionParameters = json_decode($functionCall['arguments'], true);
$functionCallResult = match ($functionName) {
'run_code' => function () use ($functions, $temperature, $messages, $functionParameters) {
if ($this->times > 3) {
return 'No result';
}
if (! isset($functionParameters['language']) || ! isset($functionParameters['code'])) {
$this->times++;
echo '[DEBUG] Invalid function parameters' . PHP_EOL;
return $this->chat($messages, $temperature, $functions);
}

$language = $functionParameters['language'];
$code = $functionParameters['code'];
return (new CodeRunner())->runCode($language, $code);
},
};
$result = $functionCallResult();
if (! $result) {
$result = 'No result';
}
$response = $result;
}
}
} catch (\Throwable $e) {
echo $e->getMessage() . PHP_EOL;
}
return $response;
}

function getOpenAIClient(): OpenAIClient
{
$openAI = new OpenAI();
$config = new OpenAIConfig(env('OPENAI_API_KEY'),);
return $openAI->getClient($config);
}

function getAzureOpenAIClient(): AzureOpenAIClient
{
$openAI = new AzureOpenAI();
$config = new AzureOpenAIConfig(apiKey: env('AZURE_OPENAI_API_KEY'), baseUrl: env('AZURE_OPENAI_API_BASE'), apiVersion: env('AZURE_OPENAI_API_VERSION'), deploymentName: env('AZURE_OPENAI_DEPLOYMENT_NAME'),);
return $openAI->getClient($config);
}
}

function chat(string $message, AbstractMemory $memory = null, string $conversationId = null): string
{
$name = get_current_user();
$os = PHP_OS_FAMILY;
$cwd = getcwd();
$functions = [
[
'name' => 'run_code',
'description' => 'Executes code and returns the output.',
'parameters' => [
'type' => 'object',
'properties' => [
'language' => [
'type' => 'string',
'description' => 'The programming language',
'enum' => [
'php',
'shell'
]
],
'code' => [
'type' => 'string',
'description' => 'The code to execute',
],
],
'required' => [
'language',
'code'
],
],
]
];
$llm = new LLM();
if ($memory) {
$message = $memory->buildPrompt($message, $conversationId);
}
$messages = [
'system' => new SystemMessage((new InterpreterPromptTemplate())->buildSystemPrompt($name, $cwd, $os)),
'user' => new UserMessage($message),
];
var_dump($messages['user']->getContent());
$response = $llm->chat($messages, temperature: 0, functions: $functions);
$memory?->addHumanMessage($message, $conversationId);
$memory?->addAIMessage($response, $conversationId);
return $response;
}

$conversionId = uniqid();
$memory = new MessageHistory();
while (true) {
echo 'Human: ';
$input = trim(fgets(STDIN, 1024));
$response = trim(chat($input, $memory, $conversionId));
echo 'AI: ' . $response . PHP_EOL;
}
Loading

0 comments on commit 65178ca

Please sign in to comment.