Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Docs: Flesh out AI docs and move to top level nav #7317

Merged
merged 19 commits into from May 15, 2024
Merged

Conversation

raddevon
Copy link
Contributor

@raddevon raddevon commented May 8, 2024

This depends on https://github.com/edgedb/edgedb.com/pull/897 to get "AI" into the top-level navigation. Otherwise, it will not be linked from anywhere.

docs/ai/reference.rst Outdated Show resolved Hide resolved
* ``stream`` (boolean, optional): Specifies whether the response should be
streamed. Defaults to false.

* ``prompt`` (object, optional): Settings that define a prompt, overriding the
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The pseudo type language here is a little bit imprecise, but maybe that's fine.

In reality this is not an object with a bunch of optional fields but rather a union of different types. Like in TypeScript this would be:

type Prompt =
  | { name: string }
  | { id: string }
  | [{ role: string; content: string }];

There are more precise formats like OpenAPI/Swagger or JSON Schema which we could leverage here to be perfectly precise if we don't want to adopt a specific language's type system like TypeScript.

wdyt?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I took a look at these formats, and it seems they are intended to generate documentation, not to be user-facing documentation themselves. I guess we could try to implement this, but we would probably need to add something to the documentation build system to generate docs from one of the formats.

I do take your point here though. I missed the point of the properties of prompt, so I've tried to clarify that you should pass only one of the properties under prompt and which to use depending on what you want to achieve. See how you feel about the outcome.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I guess what we could do is not use OpenAPI or any of those tools, but see how they structure the types in the documentation that they generate. I agree that we don't have to worry too much about giving an actual machine-readable format like one of those mentioned tools, and we certainly shouldn't complicate our build process.

Maybe we could even take inspiration a bit from something like the Stripe API docs? Ultimately I think we just need to add a bit more detail/precision here so that someone knows exactly what they can send and exactly what to expect as a response.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense. I'll turn this over a bit and see what I can come up with.

Thank you!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added some request examples, which I think could be helpful and some other minor details, like a note about authentication.

I guess the thing that's missing in terms of precision is the types of the response object properties? Is that what you're referring to when you say that it's missing detail and precision, or is there something else I'm overlooking? The request objects already give the types and descriptions of each property, so I'm not sure what else we can expose there. Aside from documentation like the Stripe ones you linked being prettier, I can't tell they're giving much more detail there. They definitely are on the responses, although I wonder how necessary it is with the examples. I think the request object details are pretty necessary since an example wouldn't capture every possible property on the object.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this specific case I mean that the definition for prompt is wrong in a specific kind of way. Given the current defintion you it seems like you could supply this object:

{
  "prompt": {
    "name": "foo",
    "id": 123,
    "custom": [{ "role": null, "content": 42.38 }],
  }
}

But really this is a disjoint union like the TypeScript type I referenced earlier. So, what I'm looking for is something that makes this union-type a little more explicit. Something like "one of", or "this or that" rather than marking each property as optional. Does that make more sense? I think how Stripe would do it is to define different types of Prompts and say this property is one of those types.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, the plot thickens a bit here after looking at the code. The type is actually more like:

interface CustomPrompt {
  role: "User" | "System";
  content: string;
}

type Prompt = 
  ({ name: string } | { id: string })
  & { custom: CustomPrompt[] };

Since you can provide a custom key along with the name or id (which is exclusive and will throw an error if you set both) and those messages will be appended to the prompt that you specified either by name or id.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, OK. I missed that you could append to an existing prompt. Did you see the prose I added to try to explain though? Does that resolve the other concern?

  You may specify an existing prompt by its ``name`` or ``id``, or you may
  define a custom prompt inline by sending an array of objects, each containing
  a ``role`` and ``content``. Choose to specify any one of these properties, or
  omit the ``prompt`` property to use the default prompt:

  * ``name`` (string, optional): The ``name`` of an existing custom prompt to
    use.

  * ``id`` (string, optional): The ``id`` of an existing custom prompt to use.

  * ``custom`` (array of objects, optional): Custom prompt messages, each
    containing a ``role`` and ``content``.

If I update that to address the ability to append to an existing prompt, does this solve the problem?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it's not worth belaboring this, but I think my main concern is that if you squint at the definition, it's not clear that name and id are exclusive just based on looking at the structure. I think something that makes it clear structurally that { name: string } and { id: string } are exclusive rather than them being both optional siblings in the object's definition. Not 100% sure how to solve that (or if it's worth solving given the explanatory prose) but that's my main concern in this specific case.

But the general thing here is: how do we structure these type definitions in a friendly cross-language way that is precise enough to be non-ambiguous, but not too tied to a specific type annotation style. That's the broader question, and something we can iterate on if we're feeling stuck here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I see. So, it's more about the implication of having the three presented as they are in the list. Yeah, that makes sense.

docs/ai/reference.rst Outdated Show resolved Hide resolved
docs/ai/python.rst Outdated Show resolved Hide resolved
@raddevon raddevon requested a review from scotttrinh May 9, 2024 16:21
Wanted to use an ellipsis to show that values were omitted, but I'll
just follow the code block with a note saying so instead.
@raddevon raddevon requested a review from scotttrinh May 10, 2024 15:55
@raddevon raddevon closed this May 10, 2024
@raddevon raddevon reopened this May 10, 2024
docs/ai/javascript.rst Outdated Show resolved Hide resolved
docs/ai/javascript.rst Show resolved Hide resolved
docs/ai/javascript.rst Outdated Show resolved Hide resolved
@raddevon raddevon requested a review from beerose May 13, 2024 16:23
Referred to it previously as a "query," but it gets wrapped with
`select` so it can actually be any expression that produces a set of
objects, whether or not that is a standalone query.
@raddevon raddevon merged commit 826004b into master May 15, 2024
24 checks passed
@raddevon raddevon deleted the doc-v5-more-ai-docs branch May 15, 2024 14:57
Copy link
Member

@fantix fantix left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

An instance of ``httpx.AsyncClient`` used for making HTTP requests
asynchronously.

.. py:method:: query_rag(message, context=None) -> str
Copy link
Member

@fantix fantix May 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a py:coroutinemethod:: I believe, the following method too

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants