CrewAIで簡単なサンプルアプリを作る際にハマった箇所（超基本）

# 目的
CrewAIの[Quickstart](https://docs.crewai.com/quickstart#build-your-first-crewai-agent)を見た後、簡単なサンプルアプリを作る際に、ハマった箇所をメモします。
超基本で恐縮ですが、どなたかの参考になれば幸いです。

# 1 AgentにLLMの設定が必要
QuickstartでAgentが以下のように書かれています。

https://docs.crewai.com/quickstart#build-your-first-crewai-agent

```
  @agent
  def researcher(self) -> Agent:
    return Agent(
      config=self.agents_config['researcher'],
      verbose=True,
      tools=[SerperDevTool()]
    )
```

同じようにAgentを作ったのですが、実行すると以下のエラーがでました。
```text: エラーメッセージ
 Error during LLM call: litellm.AuthenticationError: AuthenticationError: OpenAIException - The api_key client option must be set either by passing api_key to the client or by setting the OPENAI_API_KEY environment variable
 An unknown error occurred. Please check the details below.
 Error details: litellm.AuthenticationError: AuthenticationError: OpenAIException - The api_key client option must be set either by passing api_key to the client or by setting the OPENAI_API_KEY environment variable
```

実は、AgentはデフォルトでOpenAIのLLMを使います。OpenAI用の環境変数を設定していないことが原因でした。
https://docs.crewai.com/how-to/llm-connections#connect-crewai-to-llms
>By default, CrewAI uses the gpt-4o-mini model. This is determined by the OPENAI_MODEL_NAME environment variable, which defaults to “gpt-4o-mini” if not set. You can easily configure your agents to use a different model or provider as described in this guide.

AgentなのでLLMが必要で当然ですね。AgentにOpenAI以外のLLMを使いたい場合は、以下のようにllmの指定が必要です。

https://docs.crewai.com/how-to/llm-connections#changing-the-llm
```
# Using Anthropic's Claude
claude_agent = Agent(
    role='Anthropic Expert',
    goal='Analyze data using Claude',
    backstory="An AI assistant leveraging Anthropic's language model.",
    llm='claude-2'
)
```

サポートされているLLMのモデルとプロバイダーは以下を参照
https://docs.crewai.com/how-to/llm-connections#supported-providers
https://docs.litellm.ai/docs/providers

例えば、IBM watsonx.aiの場合は以下のように書きます。
WATSONX_URLは、`https://jp-tok.ml.cloud.ibm.com`、などです。
```
    @agent
    def business_analyst_agent(self) -> Agent:
        llm = LLM(
            model="watsonx/meta-llama/llama-3-3-70b-instruct",
            temperature=0.7,
            base_url=WATSONX_URL,
            api_key=WATSONX_APIKEY
        )
        return Agent(
            config=self.agents_config['hogehoge_agent'],
            llm=llm,
            tools=[
                HogeHogeTool.hoge
            ],
            allow_delegation=False,
            verbose=True
        )
```

# 2 ツールの引数に意図した値をセットするには？

Quickstartを見て、ツールの引数の値をどうやってセットするのか、ピンと来ませんでした。
動かしてみてわかったことは、エージェントがツールの引数に何をセットするのか考えてセットするということです。Agentなので当たり前でした。

例えば、crewに対してパス（src_doc_path）を渡して何らかの処理をするケースを想定します。
ファイルを処理するツールをつくって、引数をパスとします。
このとき、Agentがツールの引数にファイルパスをセットするように、タスクを定義する必要があります。そうしないと、Agentがでたらめのパスをセットします。
ここでは、{src_doc_path}という変数をtask.yamlに記載しています。

```python: ツール例
class HogeHogeTool:
    @tool("Refer the document and HogeHoge")
    def hogehoge(src_doc_path:str) -> str:
        """
        Refer to the document located at the specified file path(src_doc_path).
        HogeHoge

        :param src_doc_path: file path of a document to be hogehoge.
        :return: hogehoge.
        """
        with open(src_doc_path, "r", encoding="utf-8") as file:
            src_doc = file.read()
```

```yaml: task.yaml
hogehoge_task:
  description: >
    Refer to the document located at {src_doc_path} and hogehoge.
  agent: hogehoge_agent
  ・・・
```
{src_doc_path}の値は、crewをkickoffするときに、inputsというオブジェクトに入れてあげればOKです。
```python: kickoff例
    inputs = {
        'src_doc_path': src_doc_path
    }

    crew_instance = SdlcUpstreamCrew()
    crew_obj = crew_instance.crew()
    final_outputs = crew_obj.kickoff(inputs=inputs)
```